Conecte seu agente de IA (MCP)
O Tarno traz um servidor MCP neutro e somente leitura para que um agente de IA possa consultar o corpus de marcas do INAPI através do Model Context Protocol. Ele expõe o mesmo contrato de leitura da API REST — apoiado na mesma camada de consultas e nos mesmos schemas Zod — de modo que os dois transportes retornam resultados idênticos.
Endpoint e transporte
| Propriedade | Valor |
|---|---|
| Endpoint | https://mcp.tarno.cl |
| Transporte | Streamable HTTP (MCP) |
| Autenticação | Header X-API-Key, enviado por requisição |
| Identidade do servidor | tarno-read-mcp |
O servidor responde a MCP JSON-RPC sobre o transporte Streamable HTTP. Uma sonda GET /health é a
única rota não autenticada; toda chamada de ferramenta é autenticada.
Autenticação
A autenticação é por ferramenta, não por conexão. Cada handler de ferramenta verifica a chave apresentada
antes de ler qualquer coisa, de modo que uma chave ausente ou inválida nunca retorna dados do corpus. Envie sua
chave emitida pelo operador no header X-API-Key nas requisições do transporte (placeholder <API_KEY>
nesta documentação):
X-API-Key: <API_KEY>
Ambas as ferramentas exigem o escopo brands:read (uma chave irrestrita, de escopo vazio, também funciona) — veja
o guia de autenticação. Uma chave ausente/inválida é rejeitada como um erro de ferramenta unauthorized;
uma chave válida sem o escopo é rejeitada como forbidden.
O handshake
initializeno nível de transporte pode ter sucesso sem uma chave — o invariante rígido é que uma chamada de ferramenta nunca retorna dados do corpus a menos que a chave seja válida e tenha o escopo. Sempre envie o header.
Cota
A mesma cota mensal que governa a API REST se aplica ao MCP. Quando uma chave está acima da
cota, o servidor responde com HTTP 429 e um header Retry-After (segundos até reiniciar),
correspondendo byte a byte à resposta de cota do REST:
HTTP/1.1 429 Too Many Requests
Retry-After: 1209600
{ "error": { "code": "quota_exceeded", "message": "Monthly quota exceeded", "requestId": "..." } }
Catálogo de ferramentas
O servidor regista apenas ferramentas de leitura, cada uma o gémeo exato de uma rota REST:
mesma validação, mesmos dados, mesmos códigos de erro. As duas abaixo são as de entrada; o catálogo
completo é enumerado pelo seu cliente MCP com tools/list, e inclui entre outras get_feriados e
get_feriados_cobertura (o calendário de feriados e o intervalo que afirma cobrir), get_freshness,
get_sync_runs, search_personas e a família watch_* de vigilância.
As pessoas dizem que tipo de parte são, desde 2026-09-08. Cada pessoa —dentro de
get_brand_detail, dentro deget_brand_reporte emsearch_personas— traz cinco campos adicionados:tipo(natural/juridica/desconocido),tipoOrigen(rut/sufijo/manual, omitido, nuncanull, quando não houve sinal),observacion,nombrePublicadoerevision. São aditivos —nenhum campo foi removido, renomeado ou re-tipado— e são lidos sob o mesmo scopebrands:read, portanto nenhuma chave em circulação precisa de ser reemitida. A paridade REST≡MCP destes campos está verificada com um teste deep-equal contra um Postgres real, incluindo a omissão detipoOrigen. O que cada um significa: busca de pessoas.
search_brands
Busca no corpus de marcas neutro por texto livre (full-text + fuzzy) com filtros opcionais e
paginação por keyset estável. Idêntico ao REST GET /v1/brands.
Entrada (o formato de busca compartilhado — todos os campos opcionais):
| Campo | Tipo | Notas |
|---|---|---|
q |
string | Consulta por texto livre. Quando presente, os resultados são ranqueados. |
clase |
integer | Classe de Nice, 1–45. |
estado |
string | Código de status (catálogo controlado). |
tipoSigno |
string | Código de tipo de signo (catálogo controlado). |
fechaDesde |
YYYY-MM-DD |
Limite inferior da data de apresentação. |
fechaHasta |
YYYY-MM-DD |
Limite superior da data de apresentação. |
limit |
integer | Tamanho da página, padrão 20, máx. 100. |
cursor |
string | Cursor de keyset opaco para a próxima página. |
Saída: uma página JSON de resumos de marcas — { items: [...], nextCursor: string | null } —
idêntica ao REST GET /v1/brands. O payload é retornado como o primeiro bloco de conteúdo de texto do
resultado da ferramenta (faça o parse como JSON).
get_brand_detail
Busca uma marca pelo seu número de solicitação, composta com suas classes, pessoas (com papel) e
anotações do Estado-Diário. Idêntico ao REST GET /v1/brands/:nroSolicitud.
Entrada:
| Campo | Tipo | Notas |
|---|---|---|
nroSolicitud |
string | O número de solicitação da marca (obrigatório). |
Saída: o detalhe completo da marca como JSON. Um número de solicitação desconhecido retorna um
erro de ferramenta estruturado not_found (veja Forma dos erros abaixo), refletindo o
404 not_found do equivalente REST.
Forma dos erros
Todos os erros de ferramenta compartilham uma única forma: um resultado de ferramenta com
isError: true cujo texto é o JSON { "error": { "code": "<code>", "message": "<mensagem>" } } —
idêntico ao envelope {error:{code}} que a API REST retorna para 4xx/5xx (REST≡MCP). Um cliente
pode fazer JSON.parse(text).error.code de forma uniforme para qualquer erro de ferramenta. Os
code que você pode ver:
code |
Significado |
|---|---|
unauthorized |
Chave ausente, inválida, revogada ou expirada. |
forbidden |
Chave válida sem o scope requerido (p. ex. brands:read). |
invalid_input |
Entrada inválida (p. ex. a regra "exatamente um de nroSolicitud ou q"). |
not_found |
Busca por id de um recurso desconhecido (ou de outro tenant). |
query_timeout |
A consulta excedeu o orçamento de tempo; reprocessável. |
service_unavailable |
Dependência temporariamente indisponível; reprocessável. |
fuera_de_cobertura |
Pediu-se um intervalo que o calendário de feriados não afirma cobrir. É o único código que traz também coverage dentro do erro, com o intervalo real. |
internal_error |
Erro interno genérico — nunca vaza detalhes internos. |
Detalhes internos do banco de dados ou do transporte nunca são incluídos na mensagem.
Conecte seu cliente de IA
Cliente MCP Streamable-HTTP genérico
A maioria dos clientes MCP aceita uma entrada de servidor HTTP com headers personalizados. Aponte-o para o endpoint e
envie sua chave no header X-API-Key:
{
"mcpServers": {
"tarno": {
"type": "streamable-http",
"url": "https://mcp.tarno.cl",
"headers": { "X-API-Key": "<API_KEY>" }
}
}
}
Claude Desktop (via a ponte mcp-remote)
O Claude Desktop inicia servidores MCP sobre stdio, e sua UI embutida de conector personalizado só
suporta servidores OAuth ou sem autenticação — não há campo para um header X-API-Key personalizado. Para alcançar
um endpoint autenticado por header como o Tarno, faça uma ponte com o auxiliar mcp-remote,
que roda localmente sobre stdio e injeta o header em cada requisição.
Pré-requisito: Node.js 18 ou mais novo no seu PATH (o Claude Desktop invoca
npx). Verifique com node --version.
1. Abra seu arquivo de configuração do Claude Desktop (crie-o se ele não existir):
| SO | Caminho |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
Você também pode chegar até ele por Settings → Developer → Edit Config.
2. Adicione o Tarno a mcpServers. Mantenha sua chave em uma entrada env (não inline em args) — este é
o padrão seguro e evita um bug conhecido do Claude Desktop/Windows em que um espaço dentro de um valor de args
é mal-escapado ao invocar npx:
{
"mcpServers": {
"tarno": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.tarno.cl",
"--header", "X-API-Key:${TARNO_API_KEY}"
],
"env": {
"TARNO_API_KEY": "<API_KEY>"
}
}
}
}
Substitua <API_KEY> pela chave emitida pelo seu operador. (Como uma chave de API nunca contém espaços, a
forma inline "--header", "X-API-Key:<API_KEY>" também funciona — mas o padrão env acima mantém a
chave fora da lista de args e evita o bug do espaço.)
3. Reinicie o Claude Desktop por completo (feche e reabra). O Tarno então aparece como uma fonte de ferramentas
conectada; você pode pedir ao Claude que busque marcas ou obtenha o detalhe de uma marca, e ele chamará
search_brands / get_brand_detail para você.
Solução de problemas: se o servidor não aparecer, confirme que node --version funciona em um terminal,
que o JSON é válido (sem vírgulas sobrando) e que a chave é uma chave ativa e com escopo — um erro de ferramenta
unauthorized/forbidden significa que a chave está ausente, inválida ou sem brands:read.
Para um cliente programático (connect + callTool) usando @modelcontextprotocol/sdk, veja os
exemplos de código.
Veja também
- Autenticação e escopos —
X-API-Key,brands:read, ciclo de vida, códigos de erro. - Exemplos de código — um cliente mínimo do SDK MCP.
- Primeiros passos — os primeiros passos REST equivalentes.