MCP Brazil Public Data

# MCP Brazil Public Data
A modern [Model Context Protocol](https://modelcontextprotocol.io) server for
Brazilian public data, backed by [BrasilAPI](https://brasilapi.com.br) — no API key required.
Exposes 15 tools and 2 guided prompts covering companies (CNPJ), postal codes (CEP), banking, economy, geography, and more.
Inspired by the project [`alanpcf/brasil-data-mcp`](https://github.com/alanpcf/brasil-data-mcp), but adding Streamable-HTTP transport.
## Requirements
- Python 3.10+
- [uv](https://github.com/astral-sh/uv) (or Docker, for the containerized setup)
## Installation
```bash
uv venv
uv pip install -e ".[dev]"
```
## Running
The server supports two transports, selected via the `MCP_TRANSPORT` environment variable (see [Configuration](#configuration)).
### STDIO
The server speaks MCP over **stdio** by default (the transport used by most MCP
clients such as Claude Desktop and Claude Code):
```bash
source .venv/bin/activate
mcp-brazil-public-data
```
### Streamable HTTP
To serve over **streamable HTTP** instead:
```bash
source .venv/bin/activate
MCP_TRANSPORT=http mcp-brazil-public-data
```
The HTTP endpoint is then available at `http://0.0.0.0:8080/mcp/`.
### Docker
Build the image and run it in HTTP mode (the image defaults to HTTP on port 8080):
```bash
docker build -t mcp-brazil-public-data .
docker run --rm -p 8080:8080 mcp-brazil-public-data
```
Override any setting at runtime with `-e`, e.g. a different port:
```bash
docker run --rm -p 9000:9000 -e MCP_PORT=9000 mcp-brazil-public-data
```
## Configuration
| Variable | Default | Description |
| --------------- | --------- | ------------------------------------------------------------------- |
| `MCP_TRANSPORT` | `stdio` | Transport to use: `stdio` or `http` (streamable HTTP). |
| `MCP_HOST` | `0.0.0.0` | Host/interface to bind when using HTTP. Use `0.0.0.0` to expose it. |
| `MCP_PORT` | `8080` | Port to listen on when using HTTP. |
## Available Tools
### Companies & Finance
| Tool | Description | Source |
| --------------- | -------------------------------------------------------------- | --------------- |
| `lookup_cnpj` | Company registration data (legal name, status, partners, CNAE) | Federal Revenue |
| `lookup_broker` | CVM-authorized brokerage firm by CNPJ | CVM |
| `list_banks` | List of ~250 registered banks | BACEN |
| `get_bank` | Bank data by COMPE code | BACEN |
### Location & Geography
| Tool | Description | Source |
| --------------------- | --------------------------------------------- | --------------- |
| `lookup_cep` | Full address from a postal code (CEP) | Correios/ViaCEP |
| `lookup_ddd` | State and cities served by an area code (DDD) | — |
| `list_states` | 27 states (UFs) with IBGE codes | IBGE |
| `list_municipalities` | Municipalities of a state with IBGE codes | IBGE |
### Economy
| Tool | Description | Source |
| ------------------- | ------------------------------------------- | ------ |
| `list_rates` | Current economic indices (SELIC, CDI, IPCA) | BACEN |
| `get_rate` | Current value of an index by symbol | BACEN |
| `list_currencies` | Foreign currencies available for quotes | BACEN |
| `get_exchange_rate` | PTAX quote of a currency on a date | BACEN |
### Reference
| Tool | Description | Source |
| ----------------- | ---------------------------- | ---------------- |
| `list_holidays` | National holidays for a year | — |
| `lookup_isbn` | Book metadata by ISBN | CBL/Google Books |
| `check_br_domain` | Status of a `.br` domain | Registro.br |
### Guided Prompts
| Prompt | Description |
| ------------------- | ---------------------------------------------------------- |
| `analyze_company` | Looks up a CNPJ and produces a structured company analysis |
| `economic_overview` | Combines current economic rates with the year's holidays |
## Development
### Testing
Run the test suite with:
```bash
pytest
```
## License
[MIT](./LICENSE)
TDQS
Scored across 15 tools
Most tools are distinct (CNPJ, CEP, DDD, ISBN, bank, broker, domain are clearly separate). However, list_rates/get_rate and list_currencies/get_exchange_rate are legitimate duos, but list_banks/get_bank alongside list_rates/get_rate create a repetitive pattern where the list/get pairing could cause an agent to pick the wrong 'get' for a given symbol/code. list_states and list_municipalities are related but distinct enough.
The set follows a mostly consistent pattern: list_X for enumeration (list_states, list_banks, list_holidays, list_rates, list_currencies, list_municipalities), lookup_X for single-record lookups by identifier (lookup_cnpj, lookup_cep, lookup_ddd, lookup_isbn, lookup_broker), and get_X for fetching specific values (get_bank, get_rate, get_exchange_rate). The mixing of 'lookup' and 'get' for similar operations is the only inconsistency, though both are clear.
15 tools is slightly on the higher side but reasonable for a broad 'public data' server covering multiple domains (geography, companies, finance, telecom, books, domains). Each tool targets a distinct data source, so none feel redundant. Could arguably be trimmed, but the scope justifies the count.
The server covers a broad but shallow set of disjoint domains. Within each domain there are clear gaps: holidays has no state/municipal holidays (noted in description), banks has list+get but no search-by-name, rates/currencies are read-only with no historical range beyond specific date for exchange. The domain is inherently a heterogeneous reference service, so completeness is hard to define, but several common lookups (e.g., CNPJ search by name, CEP range) are absent.