Skip to main content
Glama
monkaS013

brasilapi-mcp

by monkaS013
README.md
# brasilapi-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server I wrote from scratch,
exposing the public [BrasilAPI](https://brasilapi.com.br) as tools an LLM client (Claude Desktop,
Claude Code, or any MCP host) can call. The tools look up a CEP, a CNPJ, banks, FIPE vehicle
prices, national holidays, and DDD area codes.

[README em português](README.pt-BR.md)

## Why this exists

Consuming someone else's MCP server is easy. I wanted to prove I can *build* one, which means
writing the tool schemas and a typed HTTP client behind a boundary that keeps the whole thing
testable. BrasilAPI is a good fit for that. It needs no API key and serves public data, so anyone
can clone this and run it immediately, and every tool is exercised in tests without touching the
network.

## Tools

| Tool | What it returns |
|------|-----------------|
| `cep` | Address for a Brazilian postal code (accepts `01001-000` or `01001000`) |
| `cnpj` | Company registration for a CNPJ (legal name, address, activity, status) |
| `banks` | Every bank registered at the Brazilian Central Bank |
| `bank` | A single bank by its numeric code (e.g. `001`) |
| `holidays` | National holidays for a given year |
| `ddd` | State and cities served by a two-digit phone area code |
| `fipe_brands` | FIPE vehicle brands for `carros`, `motos` or `caminhoes` |
| `fipe_price` | FIPE reference price table for a model code |

## Install

```bash
pip install -e .
```

Dependencies are just `mcp` (the official Python SDK, v2) and `httpx`.

## Run it

```bash
brasilapi-mcp            # runs the MCP server over stdio (what an MCP client launches)
brasilapi-mcp --help     # prints usage and exits, without opening a socket
```

The server speaks MCP over stdio, so you normally don't run it by hand. An MCP client launches it
and talks to it. `python -m brasilapi_mcp.server` works too.

## Wire it into a client

**Claude Desktop.** Add it to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "brasilapi": {
      "command": "brasilapi-mcp"
    }
  }
}
```

If `brasilapi-mcp` isn't on your PATH, point `command` at your venv's script (e.g.
`.../.venv/Scripts/brasilapi-mcp` on Windows) or use `"command": "python", "args": ["-m",
"brasilapi_mcp.server"]`.

**Claude Code.** One command:

```bash
claude mcp add brasilapi -- brasilapi-mcp
```

Then ask, in plain language: *"what's the address for CEP 01001-000?"* or *"list the national
holidays in 2026"*, and the model will call the matching tool.

## Design: why it tests offline

The network sits behind an injectable boundary. `BrasilAPIClient` takes an optional
`httpx.Client`/transport, so the test suite passes an `httpx.MockTransport` with canned JSON and runs
with no real network I/O. The tool bodies are thin wrappers over plain, synchronous functions that
take the client explicitly, which keeps the logic unit-testable in isolation. A `BrasilAPIError`
becomes a clean message the model can read instead of a traceback.

## Testing

```bash
pip install -e ".[dev]"
pytest -q
```

The suite covers the client against a mock transport, going through every endpoint, the input
normalization and the 404/500 handling. It also covers the tool logic functions and the server's
tool registration. Nothing hits the network.

## A note on the data

BrasilAPI is a public service and needs no key; this server stores no secrets and reads no
environment variables. Live responses are owned by BrasilAPI and its upstream sources.

## License

MIT. See [LICENSE](LICENSE).

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct Brazilian data resource — postal codes, CNPJ, banks, holidays, area codes, and FIPE data. There is no overlap or ambiguity; even banks and bank are clearly separated as list vs single lookup. An agent can easily select the correct tool based on the resource name.

Naming Consistency4/5

All tool names are lowercase and represent the resource they query, following a consistent pattern of using the resource name directly. The only minor inconsistency is the underscore in 'fipe_brands' and 'fipe_price' versus the single-word names like 'cep' and 'cnpj', but this is a stylistic variation that doesn't hinder predictability.

Tool Count5/5

With 8 tools, the server is well-scoped and stays within the sweet spot for usability. Each tool covers a distinct endpoint from the Brasil API, and the number is neither too thin nor overwhelming for the domain of Brazilian public data lookups.

Completeness4/5

The tool surface covers a broad range of common Brazilian data lookups, including location (cep, ddd), legal entities (cnpj), banking, holidays, and vehicle pricing. A notable gap is the lack of a FIPE model listing step between brand and price, which could force agents to work around missing intermediate data, but overall the coverage is solid for the selected domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues