MCP server exposing Brazilian Open Finance (Banco Central do Brasil) APIs as tools for Claude
Project description
English · Português
openfinance-br-mcp
MCP Server for Open Finance Brasil - connects Claude directly to the Banco Central APIs, covering Fases 2, 3, and 4.
What it is
An MCP Server that abstracts away the complexity of Open Finance Brasil (FAPI 1.0 Advanced, OAuth2, consent, mTLS) and exposes simple tools to Claude:
Claude → "how much did I spend on food in March?"
Claude uses list_transactions(bank=nubank, categorize=true, date_from=2024-03-01)
Claude → "You spent R$ 847.30 on food in March..."
Supported banks
| Bank | ISPB | Fase 2 | Fase 3 (PIX) | Fase 4 (Investments) |
|---|---|---|---|---|
| Nubank | 18236120 | ✅ | ✅ | ✅ |
| Sicoob | 04891850 | ✅ | ✅ | ✅ |
| Caixa Econômica | 00360305 | ✅ | ✅ | ✅ |
| Banco do Brasil | 00000000 | ✅ | ✅ | ✅ |
| Bradesco | 60746948 | ✅ | ✅ | ✅ |
| Itaú Unibanco | 60701190 | ✅ | ✅ | ✅ |
| Santander | 90400888 | ✅ | ✅ | ✅ |
| XP | 33264668 | ✅ | ✅ | ✅ |
| PicPay | 22896431 | ✅ | ✅ | ✅ |
| BTG Pactual | 30306294 | ✅ | ✅ | ✅ |
New banks: implement
BankAdapter(or subclassDefaultOpenFinanceAdapter) and register it - see "Adding a new bank" below.
Available MCP tools
| Tool | Description | Fase |
|---|---|---|
list_accounts |
Lists checking, savings, and prepaid accounts | 2 |
get_balance |
Available, blocked, and invested balance | 2 |
list_transactions |
Statement with filters and DSPy categorization | 2 |
list_credit_cards |
Credit cards and limits | 2 |
get_credit_card_bills |
Open and past bills | 2 |
list_pix_keys |
Registered PIX keys | 2 |
initiate_pix |
Idempotent PIX payment | 3 |
list_investments |
Fixed income (CDB, LCI, LCA) | 4 |
start_consent |
Starts the FAPI-BR consent/authorization flow | - |
complete_consent |
Completes consent after the user authorizes at the bank | - |
check_consent_status |
Checks the status of an existing consent | - |
revoke_consent |
Revokes an existing consent | - |
Quick start
Prerequisites
- Python 3.12+
- uv installed
# Clone the repository
git clone https://github.com/brunovicco/openfinance-br-mcp.git
cd openfinance-br-mcp
# Configure the environment
cp .env.example .env
# Edit .env with your CLIENT_ID, CLIENT_SECRET, etc.
# Install dependencies
uv sync
# Run the server
uv run openfinance-mcp
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"openfinance-br": {
"command": "uv",
"args": ["run", "--directory", "/path/to/openfinance-br-mcp", "openfinance-mcp"],
"env": {
"CLIENT_ID": "your_client_id",
"CLIENT_SECRET": "your_client_secret",
"MTLS_ENABLED": "false"
}
}
}
}
Development
# Install with dev-dependencies
uv sync
# Run the tests
uv run pytest tests/ -v
# Lint and formatting
uv run ruff check src/ tests/
uv run black src/ tests/
# Type check
uv run mypy src/
Docker
# Build
docker build -t openfinance-br-mcp .
# Run the tests
docker compose --profile test up
# Run the server
docker compose up openfinance-mcp
Kubernetes
# Create the namespace
kubectl create namespace fintech
# Apply the configuration (edit the secrets first!)
kubectl apply -f k8s/config-and-secrets.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
Runs streamable-http behind 2 replicas, with CLIENT_ID/CLIENT_SECRET/
ANTHROPIC_API_KEY mounted as secret files rather than env vars, and a
shared Redis backend (REDIS_URL) so token/consent state is visible
across replicas.
Architecture
Claude (MCP Client)
│ stdio or streamable-http
▼
openfinance-br-mcp (MCP Server)
├── Auth + Consent (FAPI-BR 2.2.0: private_key_jwt, PAR/JAR, PKCE, mTLS)
├── MCP Tools (12 tools, input validated with Pydantic v2)
│ └── Categorizer (DSPy + Claude for transaction classification)
├── Bank Adapters (10 banks - extensible)
└── Directory Client (resolves real bank endpoints from the BCB
Directory of Participants)
│ HTTPS/mTLS
▼
Open Finance BR (BCB) - Directory of Participants
│
▼
Nubank · Sicoob · Caixa · + 100 participating institutions
Design principles
- SOLID: BankAdapter ABC (O/C, LSP), single-responsibility tools, constructor-based DI
- 12-Factor: config via env, stateless, logs to stdout
- Security: mTLS, SecretStr, in-memory tokens, mandatory PKCE
- Idempotency: asyncio.Lock on token refresh, X-Idempotency-Key on PIX
- DSPy: transaction categorization framed as an LLM classification problem
Environment variables
| Variable | Required | Description |
|---|---|---|
ENVIRONMENT |
❌ | mock (default, no credentials needed), sandbox, or production |
CLIENT_ID |
⚠️ non-mock | Client ID registered with the institution |
CLIENT_SECRET |
⚠️ non-mock | Client secret |
PRIVATE_KEY_PATH |
⚠️ non-mock | RSA private key for private_key_jwt/JAR signing |
MTLS_CERT_PATH |
⚠️ prod | Path to the mTLS certificate |
MTLS_KEY_PATH |
⚠️ prod | mTLS private key |
ANTHROPIC_API_KEY |
⚠️ DSPy | Required for categorize=true |
REDIS_URL |
❌ | Shares TokenStore/ConsentManager state across replicas |
MCP_TRANSPORT |
❌ | stdio (default) or streamable-http |
LANGFUSE_OTLP_ENDPOINT |
❌ | Enables tracing to Langfuse (with LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY) |
LOG_LEVEL |
❌ | INFO, DEBUG, WARNING (default: INFO) |
LOG_FORMAT |
❌ | json or console (default: json) |
See .env.example for the full list.
Adding a new bank
- Create
src/openfinance_br_mcp/adapters/my_bank.py - Inherit from
DefaultOpenFinanceAdapter(orBankAdapterdirectly for a fully custom implementation) - Override
bank_id, and passbase_url/token_endpointdefaults - Add its ISPB to
directory/client.py's_ISPB_BY_BANKand register the adapter class incontext.py
Documentation
- docs/en/authorization.md - the two token universes (MCP client auth vs. FAPI-BR bank auth), and why they can never cross
- CONTRIBUTING.md - dev setup, CI checks, adding a bank adapter
- SECURITY.md - scope, disclaimer, and how to report a vulnerability
- SOURCES.md - specs and RFCs this implementation follows
- VALIDATION.md - what's actually been validated, and what hasn't (no real BCB sandbox run)
- CHANGELOG.md - release history
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openfinance_br_mcp-0.1.0.tar.gz.
File metadata
- Download URL: openfinance_br_mcp-0.1.0.tar.gz
- Upload date:
- Size: 309.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfb19a13847d0e66041f894dc332763e1a1504b42cfbf90f8197fd56133ed132
|
|
| MD5 |
672432fa4f111e84b1eaaccd84aedb0b
|
|
| BLAKE2b-256 |
260397da1901fdd41cf75c2f9d81e2de56af79373af9c9db5dd4a4f9dcbed268
|
File details
Details for the file openfinance_br_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openfinance_br_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 102.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64f83efb1a034fabccd42bd8f8e7db1753161468a7b14e1b7f6b3700e13d2093
|
|
| MD5 |
a443066bdb5167f3b49c5a9e92468300
|
|
| BLAKE2b-256 |
26148a0a5ec047dde613babe89d38f7e42b263a27166d59632e12d709159d6dc
|