Skip to main content
Glama

MCP Brasil

Servidor MCP (Model Context Protocol) escrito em TypeScript que expõe dados públicos brasileiros — CEP, CNPJ, CPF, bancos, feriados nacionais, municípios e DDD — como tools e resources para qualquer cliente MCP (Claude Desktop, Claude Code, ou uma integração própria).

⚠️ Licença proprietária. Este código é disponibilizado publicamente apenas para consulta/avaliação (ex.: portfólio). Cópia, uso, execução, modificação ou distribuição não são permitidos sem autorização prévia e por escrito do autor. Veja LICENSE.


Índice


Related MCP server: brasil-data-mcp

Visão geral

LLMs não têm, nativamente, acesso a dados cadastrais e de referência do Brasil: não sabem o endereço de um CEP, se um CNPJ está ativo, quais são os feriados nacionais de um ano, ou qual estado corresponde a um DDD. Para que um agente de IA seja útil em fluxos de cadastro, cobrança, atendimento ou integração no contexto brasileiro, ele precisa de acesso confiável a esses dados — com validação de entrada, cache, tratamento de falhas e mensagens de erro que o próprio modelo consiga interpretar.

O MCP Brasil resolve isso implementando o protocolo MCP (o padrão aberto usado pelo Claude e por um número crescente de outros clientes de IA para conectar modelos a ferramentas e dados externos) sobre um conjunto de APIs públicas brasileiras: BrasilAPI, ViaCEP e o IBGE. O resultado é um binário que roda com npx mcp-brasil e se conecta a qualquer cliente MCP.

Por que este projeto existe

Este projeto nasceu como peça de portfólio técnico, para demonstrar:

  • Domínio do protocolo MCP e do SDK oficial (@modelcontextprotocol/sdk), incluindo tools, resources e os dois transportes padrão (stdio e streamable HTTP).

  • Engenharia de integração de verdade: múltiplos providers HTTP com fallback, cache com TTL, rate limiting por provedor, retry com backoff, timeout, e tratamento cuidadoso de erros de API (inclusive comportamentos inconsistentes entre elas — ver Segurança e robustez).

  • TypeScript rigoroso, com validação de schema via Zod convertida automaticamente em JSON Schema para as tools.

  • Uma suíte de testes em três camadas (unitária, integração com APIs mockadas de forma realista, e end-to-end com o binário real), com cobertura de 100% nas partes testáveis.

Tools disponíveis

Tool

Entrada

Descrição

Cache

validar_documento

documento: string

Valida CPF ou CNPJ (dígito verificador) e retorna o documento formatado. Detecta o tipo automaticamente pelo número de dígitos. 100% offline, não faz nenhuma chamada de rede.

—

consultar_cep

cep: string

CEP → logradouro, bairro, cidade, UF (e coordenadas, quando disponíveis). Tenta o ViaCEP primeiro; se falhar por motivo de infraestrutura, cai para a BrasilAPI automaticamente.

24h

consultar_cnpj

cnpj: string

CNPJ → razão social, nome fantasia, situação cadastral, atividade (CNAE), porte, endereço e sócios. Valida o dígito verificador antes de consultar a API, evitando uma chamada desnecessária.

1h

listar_bancos

—

Lista todos os bancos brasileiros registrados no Banco Central (código COMPE, nome, ISPB).

7 dias

consultar_banco

codigo: string

Um banco específico pelo código COMPE (ex.: "341" para Itaú).

7 dias

feriados

ano: number

Feriados nacionais de um ano (data, nome, tipo).

30 dias

consultar_municipios

uf: string

Municípios de uma UF, com o respectivo código IBGE.

30 dias

buscar_ddd

ddd: string

Estado e lista de cidades atendidas por um DDD.

30 dias

Cada tool retorna, ao mesmo tempo, um bloco de texto legível (para o modelo ler diretamente) e um bloco structuredContent em JSON (para o modelo — ou o código que orquestra o agente — consumir de forma programática).

Resources disponíveis

URI

Descrição

brasil://uf/{sigla}

Sigla, nome e região de uma unidade federativa, via IBGE. Ex.: brasil://uf/SP → {"sigla":"SP","nome":"São Paulo","regiao":"Sudeste"}.

Transportes

O servidor suporta os dois transportes definidos pela especificação MCP:

  • stdio (padrão): usado por Claude Desktop e Claude Code, que gerenciam o processo filho e conversam com ele via stdin/stdout. Todo log vai para stderr — stdout é reservado exclusivamente para o canal JSON-RPC.

  • HTTP (streamable): para hospedar o servidor você mesmo. Ative com MCP_TRANSPORT=http; o servidor expõe POST /mcp. Roda em modo stateless (cada requisição HTTP recebe sua própria instância de servidor/transporte MCP; os caches e o rate limiter, por serem módulos singleton, continuam compartilhados entre requisições).

Arquitetura

Cliente MCP (Claude Desktop / Code / outro)
        │  JSON-RPC (stdio | HTTP)
┌───────▼────────────────────────────────┐
│ server/   McpServer (SDK oficial)      │
│   registra tools e resources           │
├─────────────────────────────────────────┤
│ tools/    uma pasta por tool           │
│   schema (Zod) + handler + format      │
├─────────────────────────────────────────┤
│ providers/ clients HTTP tipados        │
│   BrasilAPI, ViaCEP, IBGE + fallback   │
├─────────────────────────────────────────┤
│ infra/    cache, rate-limit, http,     │
│           logger, config               │
└─────────────────────────────────────────┘

Padrões usados:

  • Injeção de dependência via factory: cada handler é criado por uma função createXHandler(deps) que recebe o provider e o cache como dependências. Isso permite testar a lógica de cada tool com providers falsos, sem tocar a rede, e ainda assim conectar instâncias reais no index.ts de cada tool.

  • Provider com fallback: FallbackCepProvider tenta o ViaCEP e, só em caso de falha de infraestrutura (não de "CEP não existe"), cai para a BrasilAPI. Um CEP genuinamente inexistente nunca é mascarado tentando o próximo provider.

  • Cache com deduplicação de chamadas concorrentes: Cache.getOrLoad guarda a promise em andamento por chave, então duas chamadas simultâneas para o mesmo CEP disparam uma requisição de rede, não duas.

  • Rate limiting por provedor: um token bucket por nome de provider (viacep, brasilapi, ibge), aplicado de forma transparente em toda chamada HTTP, para não abusar das APIs públicas gratuitas usadas pelo servidor.

Estrutura de pastas

mcp-brasil/
├── bin/mcp-brasil.js            # entry point do npx
├── src/
│   ├── index.ts                 # bootstrap + escolha de transporte
│   ├── server/
│   │   ├── create-server.ts     # instancia o McpServer e registra tools/resources
│   │   └── transports/{stdio,http}.ts
│   ├── tools/                   # uma pasta por tool: schema.ts, handler.ts, format.ts, index.ts
│   ├── providers/                # clients HTTP tipados + fallback
│   ├── resources/                 # resources MCP (uf.resource.ts)
│   ├── infra/                    # cache, rate-limit, http (retry/timeout), logger, config
│   └── domain/                   # algoritmos de CPF/CNPJ, erros de domínio
├── tests/
│   ├── unit/                    # algoritmos, cache, rate limiter, handlers com providers fake
│   ├── integration/              # providers reais contra APIs mockadas (MSW), servidor via InMemoryTransport
│   └── e2e/                      # binário real via stdio e via HTTP
└── examples/                     # configs de exemplo para Claude Desktop e Claude Code

Stack técnica

Camada

Tecnologia

Motivo

Protocolo

@modelcontextprotocol/sdk

SDK oficial do MCP

Validação

Zod

Schemas viram JSON Schema das tools automaticamente

HTTP

fetch nativo (Node 20+) + p-retry

Sem dependências pesadas tipo axios

Cache

lru-cache

TTL e limite de memória configuráveis

Build

tsup

Gera um único bundle ESM executável via npx

Testes

Vitest + MSW

Determinismo — nenhum teste depende de rede real

Lint / Formatação

ESLint + Prettier

Segurança e robustez

Pontos que foram verificados e endurecidos deliberadamente, não só assumidos:

  • Rate limiting real: cada chamada HTTP passa por um token bucket por provedor antes de sair. Não é apenas uma classe isolada com testes — está de fato no caminho de toda requisição (infra/http.ts).

  • Validação de entrada em todas as tools: schemas Zod com limites de tamanho (.max()) em todo campo de texto, evitando payloads arbitrariamente grandes. O resource brasil://uf/{sigla} — que não passa pela validação automática do SDK, diferente das tools — tem validação de formato própria antes de montar a URL de saída.

  • Limite de tamanho de corpo no transporte HTTP: requisições acima de 1 MiB são rejeitadas com 413, evitando um vetor de exaustão de memória.

  • Tratamento de erro 4xx sem retry inútil: qualquer erro 4xx (não só 404) é tratado como "não encontrado", sem consumir tentativas de retry — importante porque as APIs públicas usadas aqui são inconsistentes entre si (a BrasilAPI responde 400 para um DDD malformado e 404 para um banco inexistente; o IBGE responde 200 com corpo vazio para uma UF inexistente). Cada uma dessas variações foi observada contra a API real e coberta por teste.

  • Nunca expõe stack trace ao cliente: toda falha de provider vira uma mensagem de erro legível (isError: true no formato MCP), nunca um erro bruto do runtime.

  • Logs sempre em stderr: nunca poluem o canal JSON-RPC do transporte stdio.

  • Sem segredos: todas as APIs usadas são públicas e não exigem chave de API, token ou credencial de nenhum tipo.

  • npm audit limpo em produção: npm audit --omit=dev não acusa nenhuma vulnerabilidade nas dependências que de fato vão para o pacote publicado (as únicas vulnerabilidades reportadas pelo npm audit padrão são em ferramentas de desenvolvimento — vitest/vite/esbuild — e não afetam o código em execução).

Estratégia de testes

Três camadas, sem sobreposição de responsabilidade:

  • Unitários (tests/unit): algoritmos de CPF/CNPJ contra casos válidos/inválidos conhecidos; cache (incluindo expiração por TTL e deduplicação de chamadas concorrentes); rate limiter (incluindo bloqueio, liberação por refill e reset entre testes); handler de cada tool, isoladamente, com um provider fake injetado — sem tocar em rede.

  • Integração (tests/integration): os providers HTTP reais (ViaCepProvider, BrasilApiClient, IbgeClient) testados contra respostas mockadas com MSW, com fixtures fiéis ao formato exato das respostas reais dessas APIs (verificadas manualmente contra produção durante o desenvolvimento); o servidor MCP completo testado via InMemoryTransport do SDK oficial, cobrindo o fluxo real de tools/list e tools/call.

  • E2E (tests/e2e): o binário publicado (bin/mcp-brasil.js) executado como processo real, com handshake MCP genuíno tanto via stdio quanto via HTTP (incluindo o limite de tamanho de corpo).

Executando localmente

Pré-requisito: Node.js 20+.

npm install
npm run dev              # roda via stdio, com hot-reload via tsx
npm test                 # build + suíte completa (unit + integração + e2e)
npm run test:coverage    # com relatório de cobertura
npm run lint
npm run typecheck
npm run format:check     # verifica formatação (Prettier)
npm run build            # gera dist/ (ESM + tipos)

Para testar manualmente contra um cliente MCP local, aponte-o para node bin/mcp-brasil.js (transporte stdio) — exemplos prontos de configuração em examples/claude_desktop_config.json e examples/claude-code.md.

Configuração (variáveis de ambiente)

Variável

Padrão

Descrição

MCP_TRANSPORT

stdio

stdio ou http.

MCP_PORT

3000

Porta usada quando MCP_TRANSPORT=http.

LOG_LEVEL

info

debug, info, warn ou error. Logs sempre em stderr.

Licença

Este projeto não é open source. Todos os direitos são reservados ao autor — cópia, uso, execução, modificação e distribuição são proibidos sem autorização prévia e por escrito. O texto completo está em LICENSE.

Available Tools

1 tool
validar_documentoA

Valida um CPF ou CNPJ brasileiro (dígitos verificadores) e retorna o documento formatado. Detecta automaticamente o tipo pelo número de dígitos. Funciona totalmente offline, sem consultar APIs externas. Use quando precisar checar se um número de documento informado pelo usuário é válido antes de prosseguir com um cadastro.

ParametersJSON Schema
NameRequiredDescriptionDefault
documentoYesNúmero de CPF ou CNPJ, com ou sem máscara (pontos, traço, barra).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the validation algorithm (check digits), automatic type detection by digit count, and that it is fully offline with no external API calls. The main gap is that it never states what happens on an invalid input (error vs. flag), which matters for a validator.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with what the tool does, then behavior, then the usage trigger. No filler or restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter validator with no annotations and no output schema, the description covers purpose, mechanism, input flexibility, and return shape ('retorna o documento formatado'). The only missing piece is failure/invalid-input behavior, which an agent would likely need when gating a registration flow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single 'documento' parameter, so the schema already documents mask tolerance. The description adds indirect value by explaining that type (CPF vs CNPJ) is auto-detected from digit count, meaning no type parameter is needed, but this is a baseline-level contribution.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource ('Valida um CPF ou CNPJ brasileiro'), names the exact mechanism (dígitos verificadores) and adds that it returns the formatted document. An agent can immediately tell this is an offline identifier validator rather than a lookup or formatter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit trigger condition: 'Use quando precisar checar se um número de documento informado pelo usuário é válido antes de prosseguir com um cadastro.' That is clear when-to-use guidance, though it offers no exclusions or alternative tools (none exist as siblings).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.0
    • First observedvalidar_documento

TDQS

A4.1/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of overlap or misselection. Its purpose (validate a CPF/CNPJ and return it formatted) is unambiguous and clearly stated.

Naming Consistency5/5

The single name 'validar_documento' uses a clean snake_case verb_noun pattern in Portuguese and there are no competing conventions to conflict with it. Consistency is trivially satisfied.

Tool Count2/5

A server named 'MCP Brasil' implies a broader suite of Brazilian utilities (CEP lookup, phone/currency formatting, state data, etc.), so a single validation tool is far too thin for the apparent scope. The tool itself is well-sized, but the surface overall is under-built.

Completeness4/5

For the narrow stated purpose of checking document validity before a cadastro, CPF and CNPJ are both covered with a self-contained offline implementation. Only minor adjacent operations are missing, such as format-only or generate-valid-document helpers.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Query a variety of data from Brasil resources seamlessly. Access information on postal codes, area codes, banks, holidays, taxes, and more through a unified interface. Enhance your AI agents and applications with rich and updated data from BrasilAPI effortlessly.
    6
    7
    -
  • A
    license
    A
    quality
    A
    maintenance
    MCP server providing access to Brazilian public data (CNPJ, CEP, banks, holidays) via BrasilAPI. For Claude Desktop, Claude Code, Cursor, and other MCP-compatible clients.
    15
    22 npm
    8
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Exposes the BrasilAPI as MCP tools, enabling AI agents to query Brazilian public data such as CEP, CNPJ, DDD, IBGE, banks, PIX, FIPE, NCM, exchange rates, taxes, weather, CVM information, holidays, ISBN, domains, stock tickers, and TUSS.
    41
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Enables lookup of Brazilian public data including companies (CNPJ), postal codes (CEP), banking, economy, geography, and more through 15 tools and 2 guided prompts, powered by BrasilAPI with no API key required.
    15
    MIT