Skip to main content
Glama
brunovicco

openfinance-br-mcp

by brunovicco

English · Português

openfinance-br-mcp

Experimental MCP server for Open Finance Brasil, with a complete mock environment and an evolving implementation toward FAPI-BR integration. Not certified, and not yet validated against real institutions - see VALIDATION.md and the implementation plan in IMPLEMENTATION_PLAN.md before relying on this outside environment=mock.

Python 3.12 uv Code style: black Ruff


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..."

Related MCP server: MCP Conta Azul

Supported banks

Mock adapters are implemented for the ten institutions below - each returns realistic, in-memory sample data with zero credentials or network access, and is the primary way to explore this project today. Real (non-mock) support is experimental: it has not been exercised against any bank's actual sandbox or production environment, is not FAPI-BR certified, and several endpoints/paths are still being brought in line with the official OpenAPI specs (tracked in IMPLEMENTATION_PLAN.md).

Bank

ISPB

Mock adapter

Real integration

Nubank

18236120

experimental, unvalidated

Sicoob

04891850

experimental, unvalidated

Caixa Econômica

00360305

experimental, unvalidated

Banco do Brasil

00000000

experimental, unvalidated

Bradesco

60746948

experimental, unvalidated

Itaú Unibanco

60701190

experimental, unvalidated

Santander

90400888

experimental, unvalidated

XP

33264668

experimental, unvalidated

PicPay

22896431

experimental, unvalidated

BTG Pactual

30306294

experimental, unvalidated

PIX payment initiation (initiate_pix) and list_pix_keys are currently restricted to environment=mock, the real Open Finance Brasil Payments API journey (dedicated payment consent, signed JWS requests/responses, persistent idempotency) is not yet implemented; see IMPLEMENTATION_PLAN.md, phase P2.

New banks: implement BankAdapter (or subclass DefaultOpenFinanceAdapter) 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 (mock-only, see below)

2

initiate_pix

Idempotent PIX payment (mock-only, see below)

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

  1. Create src/openfinance_br_mcp/adapters/my_bank.py

  2. Inherit from DefaultOpenFinanceAdapter (or BankAdapter directly for a fully custom implementation)

  3. Override bank_id, and pass base_url/token_endpoint defaults

  4. Add its ISPB to directory/client.py's _ISPB_BY_BANK and register the adapter class in context.py

Documentation

License

MIT

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/brunovicco/openfinance-br-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server