MCP Server for the Open Bank Project API - enables AI assistants to interact with 600+ OBP API endpoints via tag-based routing and glossary access.
Top to bottom: users reach OBP through the OBP-Portal / API Explorer II frontend, which talks to Opey; Opey and external MCP clients (Claude Code, Claude Desktop, IDE agents) call OBP-MCP over MCP/HTTP; OBP-MCP makes the authenticated HTTPS calls to OBP-API, which in turn reaches core banking systems via its southbound connectors. OBP-OIDC issues and validates the tokens used at each hop. The numbered orange flow shows how user consent is obtained when a tool call requires a Consent-JWT: OBP-MCP returns consent_required, Opey surfaces it to the frontend as an SSE event, the frontend creates an implicit consent on OBP-API, and the tool call is retried with the Consent-JWT header.
Opey also makes some direct (non-MCP) HTTP calls to OBP-API for its own infrastructure — session validation, admin operations, checkpoint persistence and health probes — covered by a separate detail diagram.
The editable masters live in Lucidchart: architecture overview · Opey direct-HTTP detail. To update the image: edit the Lucid doc, export the page as PNG, upload it to a GitHub issue comment, and replace the github.com/user-attachments/assets/... URL here (and in the Opey README and the OBP-API glossary, which embed the same image).
MacOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh- Create
.envfile:
OBP_BASE_URL=https://apisandbox.openbankproject.com
OBP_VERSION_TO_CALL=v7.0.0
API_VERSION_OF_INTEREST=v7.0.0
FASTMCP_HOST=127.0.0.1
FASTMCP_PORT=9100- Generate indexes:
uv run python scripts/generate_endpoint_index.py
uv run python scripts/generate_glossary_index.py- Run server:
uv sync
./run_server.shServer starts at http://0.0.0.0:9100
Two separate settings control auth. Don't mix them up — both can involve OAuth:
| Setting | Controls | Values |
|---|---|---|
AUTH_PROVIDER (with ENABLE_OAUTH) |
How a client connects to this MCP server | bearer-only, obp-oidc, keycloak, or off |
OBP_AUTHORIZATION_VIA |
How this server's calls to OBP-API are authorized | consent (Consent mode) or oauth (OAuth mode) |
- Consent mode — every call to OBP-API carries a
Consent-JWTsupplied by the client with the tool call. AnyAuthorizationheader from the client is dropped. Without a Consent-JWT, calls to non-public endpoints returnconsent_required. Use this for Opey. - OAuth mode — every call to OBP-API carries the OAuth access token the user logged in to this MCP server with. Use this for Claude Code, Claude Desktop, VS Code and other general MCP clients.
- Any other value (including unset): the server starts, logs a prominent warning, and
call_obp_apirefuses every request.
The server's home page (/) and /status page show which mode it is in at the top, and /status?format=json reports it as auth.mode.
OBP-MCP supports three connection authentication providers:
| Mode | Use Case | AUTH_PROVIDER |
|---|---|---|
| bearer-only | Internal agents (Opey), microservices | bearer-only |
| obp-oidc | External MCP clients (VS Code, Claude Desktop) | obp-oidc |
| keycloak | External MCP clients with Keycloak | keycloak |
Use bearer-only authentication together with Consent mode (full setup in Appendix 1). This mode:
- Does NOT expose OAuth discovery endpoints
- Simply validates JWT tokens against OBP-OIDC's JWKS
- Is designed for architectures where OAuth is handled externally (e.g., by a frontend portal)
# .env
ENABLE_OAUTH="true"
AUTH_PROVIDER=bearer-only
OBP_OIDC_ISSUER_URL=http://localhost:9000/obp-oidc
OBP_AUTHORIZATION_VIA="consent"Opey authenticates to the MCP server with its own client-credentials token, not the user's token. The user's identity travels only in the per-call Consent-JWT:
Authorization: Bearer <Opey's client-credentials token>
Use obp-oidc or keycloak authentication. These modes expose the full OAuth 2.1 discovery flow, allowing MCP clients to:
- Discover authorization endpoints via
/.well-known/oauth-protected-resource - Perform Dynamic Client Registration (RFC 7591)
- Complete the OAuth authorization code flow with PKCE
# .env
ENABLE_OAUTH="true"
AUTH_PROVIDER=obp-oidc
OBP_OIDC_ISSUER_URL=http://localhost:9000/obp-oidc
BASE_URL=http://localhost:9100For development or testing without authentication:
ENABLE_OAUTH="false"This only turns off login for connecting to the MCP server. Calls to OBP-API still follow OBP_AUTHORIZATION_VIA. Note that OAuth mode with login turned off has no user token to send, so OBP-API calls go out without one.
for more information about auth and how to configure your OIDC providers see the docs.
Run the server normally then start the inspector with:
npx @modelcontextprotocol/inspector \You can then configure the connection to the server from there.
Configure in the servers section of ~/.config/Code/User/mcp.json:
{
"servers": {
"obp-mcp": {
"url": "http://0.0.0.0:9100/mcp",
"type": "http"
}
}
}Configure in ~/.config/zed/settings.json:
{
"context_servers": {
"obp-mcp": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://127.0.0.1:9100/mcp"]
}
}
}Configure in ~/.claude.json. The relevant section is:
"mcpServers": {
"obp-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://127.0.0.1:9100/mcp"
],
"env": {}
}
}
This is a global config that makes the obp-mcp server available to all projects. It connects to http://127.0.0.1:9100/mcp using mcp-remote.
Endpoint Tools:
list_endpoints_by_tag- Filter 600+ endpoints by categoryget_endpoint_schema- Fetch full OpenAPI schemacall_obp_api- Execute API requests
Glossary Tools:
list_glossary_terms- Search 800+ OBP termsget_glossary_term- Get full definitions
See docs/HYBRID_ROUTING.md for details.
Opey-II uses Consent mode. Opey authenticates to OBP-MCP with its own client-credentials token (service identity), and passes the user's Consent-JWT with each tool call (user identity). The user's own OAuth token never reaches OBP-MCP.
OBP-MCP .env:
ENABLE_OAUTH="true"
AUTH_PROVIDER=bearer-only
OBP_OIDC_ISSUER_URL=http://localhost:9000/obp-oidc
OBP_AUTHORIZATION_VIA="consent"
OBP_OPEY_CONSUMER_KEY=<opey's consumer key (same as the OBP_CONSUMER_KEY in Opey)>In Opey's mcp_servers.json (inside the servers array):
{
"name": "obp",
"url": "http://0.0.0.0:9100/mcp",
"transport": "http",
"use_service_token": true
}And in Opey's .env, the credentials Opey uses to get its service token from OBP-OIDC (all three are required, otherwise Opey sends no Authorization header):
OPEY_OIDC_TOKEN_URL=http://localhost:9000/obp-oidc/token
OPEY_OIDC_CLIENT_ID=<opey's OIDC client id>
OPEY_OIDC_CLIENT_SECRET=<opey's OIDC client secret>[!NOTE]
forward_bearer_token: true(which forwarded the user's own OAuth token to OBP-MCP) is the older setup and should no longer be used with Consent mode. In Consent mode OBP-MCP ignores that token for OBP calls anyway.
[!WARNING]
bearer-onlyrequires the scopesopenid,profileandscopeparameter, and OBP-OIDC then issues it with an empty scope, so OBP-MCP will reject it. Until that is resolved, a local setup can run withENABLE_OAUTH="false"(no login needed to connect; OBP calls are still protected by the Consent-JWT).
[!NOTE] A server in Consent mode is not useful to general MCP clients (Claude Code, VS Code, …): they can connect and use the discovery and glossary tools, but
call_obp_apireturnsconsent_requiredbecause they can't create consents. Run a second instance in OAuth mode for those clients.
AGPLv3
