|# OBP-MCP
|
|**OBP-MCP** is a [Model Context Protocol](https://modelcontextprotocol.io) server for the Open Bank Project API. It lets AI assistants (Claude, Opey, IDE agents, custom LLM tooling) discover and call OBP-API endpoints as MCP *tools*, without hard-coding any knowledge of the 600+ endpoints.
|
|Repository: [github.com/OpenBankProject/OBP-MCP](https://github.com/OpenBankProject/OBP-MCP)
|
|## What it does
|
|OBP-MCP is a thin protocol bridge. AI clients speak **MCP** to it; it speaks **HTTPS / REST** to OBP-API on their behalf, attaching the user's OAuth token or Consent-JWT.
|
|```
|┌──────────────────┐ MCP ┌────────────────────────┐ HTTPS ┌──────────────┐
|│ AI client │ ───────▶ │ OBP-MCP │ ─────────▶ │ OBP-API │
|│ (Claude, Opey, │ ◀─────── │ (FastMCP server) │ ◀───────── │ │
|│ IDE agent) │ tools │ │ JSON │ │
|└──────────────────┘ └────────────────────────┘ └──────────────┘
|```
|
|## Architecture diagram
|
|The full picture — Portal/API Explorer, Opey, external MCP clients (Claude Code, Claude Desktop, IDE agents), OBP-OIDC, the numbered consent flow, and OBP-API down to the core banking systems:
|
|
|
|The editable master is a Lucidchart document linked from the [OBP-MCP README](https://github.com/OpenBankProject/OBP-MCP#architecture).
|
|## Three-step discovery + call (no RAG, no vector DB)
|
|OBP-MCP avoids embedding the 4 MB OpenAPI spec into the LLM's context. Instead it exposes three tools that work together:
|
|1. **`list_endpoints_by_tag(tags)`** — returns lightweight summaries (~50–100 tokens each) from a local `endpoint_index.json`. Lets the LLM narrow down to a handful of candidate endpoints by tag (e.g. `Account`, `Transaction-Request`, `Consent`).
|2. **`get_endpoint_schema(endpoint_id)`** — lazy-loads the full OpenAPI schema for one endpoint from a local `endpoint_schemas.json`.
|3. **`call_obp_api(endpoint_id, path_params, query_params, body, headers)`** — actually executes the HTTP request against the live OBP-API.
|
|Two further tools cover the glossary itself: **`list_glossary_terms(search_query)`** and **`get_glossary_term(term_id)`**, backed by a local `glossary_index.json` of 800+ banking terms.
|
|## Three kinds of traffic
|
|It is important to understand that OBP-MCP is **not** a documentation lookup tool — it makes real, authenticated business calls:
|
|- **Documentation / discovery** — `list_endpoints_by_tag`, `get_endpoint_schema`, glossary tools. Served from local JSON, no network.
|- **Business calls** — `call_obp_api` proxies whatever the endpoint declares: `GET /banks/{BANK_ID}/accounts`, `POST .../transaction-requests/SEPA`, `PUT /accounts/{ACC}/label`, `DELETE /my/consents/{CONSENT_ID}`, etc. Real money / data moves.
|- **Index refresh** — at startup and on a timer, OBP-MCP re-fetches OBP's [Resource Docs](http://localhost:5174/glossary#Resource-Doc) and swagger to rebuild the local indexes, so discovery stays fast and offline.
|
|## Authentication and authorization
|
|OBP-MCP supports several modes via the `AUTH_PROVIDER` environment variable for client-to-MCP auth:
|
|| Mode | Use case | Notes |
||----------------|---------------------------------------|----------------------------------------------------|
|| `bearer-only` | Internal agents (e.g. Opey) | JWT validation only, multi-issuer |
|| `obp-oidc` | External MCP clients | Full OAuth 2.1 + Dynamic Client Registration |
|| `keycloak` | External MCP clients | OAuth 2.1 + minimal DCR proxy workaround |
|| `none` | Development / testing | No auth required |
|
|For onward calls to OBP-API, `OBP_AUTHORIZATION_VIA` selects:
|
|- **`oauth`** — pulls the access token from the MCP request context and sends `Authorization: Bearer ...`.
|- **`consent`** — the default mode for user-facing deployments. `call_obp_api` requires a `Consent-JWT` for **every** endpoint except a small allowlist of genuinely public ones (`GET /root`, the bank directory `/banks` and `/banks/{BANK_ID}`, glossary, resource-docs, API metadata). For any other endpoint called without a `Consent-JWT`, the tool returns a `consent_required` payload — required roles, bank / account / view scope, and `requires_view_access` / `is_user_scoped` flags — so the client can build the right consent and retry with a `Consent-JWT` header. Consent is required **by default**, not only for role-gated endpoints, because many identity-bound endpoints (`/users/current`, `/my/*`, account-access-via-view endpoints) declare no roles yet still need the caller's identity — a role-only gate would call them unauthenticated. The allowlist is deliberately conservative: a wrongly-excluded endpoint costs only an extra prompt, whereas wrongly skipping consent fails silently.
|- **`none`** — calls OBP unauthenticated (only useful for genuinely public endpoints).
|
|This means the consent flow is enforced at the MCP layer, not just at OBP-API: an agent cannot accidentally call a privileged endpoint without explicit user consent.
|
|## Why it matters
|
|OBP-MCP is the canonical way to make Open Bank Project endpoints **agent-callable**. Instead of teaching every LLM about every endpoint up front, the LLM is given five generic tools and lets the indexes and schemas guide it to the right call at runtime. The same server can serve internal agents (Opey) and external clients (Claude Desktop, IDE plugins, third-party agents) by switching auth providers.
|
|See also: [Opey](http://localhost:5174/glossary#Opey), [Resource Doc](http://localhost:5174/glossary#Resource-Doc), [Consent](http://localhost:5174/glossary#Consent), [Authentication: OAuth 2.0](http://localhost:5174/glossary#Authentication:-OAuth-2.0).
|