EU Open Banking MCP
EU Open Banking MCP
一个自托管、只读的 MCP 服务器,用于通过 Enable Banking 访问个人欧洲银行账户,并部署于 Cloudflare Workers 之上、具备安全保护。
[!IMPORTANT] 请把每一次部署都当作一个私有金融系统来对待。本仓库是开源的;但你的 Worker、MCP URL、密钥、会话 ID、账户 ID 和财务数据都是私密的。
为什么会有这个项目
ChatGPT Finances 展示了当助手能够对真实余额和交易进行推理时,一切会变得多么不同。它的账户连接由 Plaid 驱动,目前仅在美国可用。
我构建这个项目,是因为我找不到一条同样直接、可自托管的路径来覆盖欧洲个人账户。欧洲虽然已经有 Open Banking,但个人仍然需要通过受监管的中间服务商才能访问银行数据,而这些服务商的生产环境接入流程和 API 差异很大。Plaid 发布的 MCP 服务器 对开发人员工具和生产诊断很有用,但它们不会把个人的余额和交易作为个人财务 MCP 工具暴露出来。
这个项目填补了这一小片空白:由一个人部署一个私有 MCP,只授权他自己的银行账户,并让他所选择的 MCP 客户端执行受限的只读分析。它是供个人使用的基础设施,而不是一个云端的金融产品,也不是多用户聚合器。
Related MCP server: openbanking-mcp
为什么选择 Enable Banking
在评估过的提供商中,Enable Banking 为自托管个人部署提供了最简路径。它的受限生产模式明确允许应用在签署商业协议之前,通过关联所有者自己的账户来激活使用,包括用于个人非商业用途。之后,该应用也只能读取这些被关联的账户。请参阅 Enable Banking 的 关联账户指南。
这个模式恰好与项目的安全边界一致:
Enable Banking 控制面板就是账户白名单;
银行的授权流程会创建可撤销的 API 授权;
MCP 只对两者共同覆盖的账户暴露固定的只读操作。
在控制面板里关联账户,并不等于 API 授权。部署之后,/setup 仍会让所有者走一遍银行的授权同意流程,并保存生成的 Enable Banking 会话 ID。即使同一个账户已经在控制面板里关联过,这一步仍然是必需的。
架构
flowchart LR
C[ChatGPT, Codex, or another MCP client] --> A[Cloudflare Access]
A -->|platform-validated ctx.access| W[Stateless MCP Worker]
W -->|session IDs only| K[Workers KV]
W -->|fresh RS256 JWT per call| E[Enable Banking]
E --> B[Your bank]客户端 → MCP:通过 Cloudflare Access Managed OAuth 进行验证,并且只限定为本部署的所有者。
MCP → Enable Banking:一个 1 小时的 RS256 JWT,用存在 Worker 密钥里的 RSA 私钥签名。
存储:KV 中只存有通过受保护 setup 流程产生的 Enable Banking 会话 ID。
在线账户读取:Worker 会把连接方 IP 和 MCP 客户端的 User-Agent 作为 Enable Banking 的
Psu-Ip-Address/Psu-User-Agent请求头转发过去,这些值只存在于请求上下文中,不会被持久化存储或记录。这告诉银行,正是已登录的所有者在主动请求这些数据。
Worker 不保存余额、交易、账户 UUID、IBAN、授权码或任何服务端响应。响应使用 Cache-Control: no-store。
工具
工具 | 用途 | 边界限制 |
| 返回活动账户和银行元数据 | 20 个已授权会话、最多 20 个活动账户 |
| 获取一个发现的账户或全部活动账户 | 或按账户返回部分结果、在每个银行内顺序执行 |
| 分页标准化交易数据 | 366 天、每次请求最多 200 条 |
| 对交易元数据进行文本搜索 | 366 天、5 个服务商分页、最多 100 个匹配 |
| 按币种汇总已入账的信用卡、借记与净额 | 366 天、最多 20 个分页、10000 条交易 |
finance_list_accounts 返回一个不透明、限定的 accountId,并按会话区分。做定向账户调用的工具都会接受该类,并在真正访问之前与本次生效 Enable Banking 会话确认。你不需要别名,更不需要手工复制 UUID。
分页的 nextCursor 包含编码的续页状态;它是不透明的,但不是机密。请在同账户、同筛选下原样回传。Worker 在启用前会执行校验嵌入其中的上下信息,因此不要篡改它。
所有工具都是只读、非破坏、幂等的。供应商代码会被规范化为语义化,例如 interim(临时)、accounted、和 professional。一个账户的多个余额是对同一资金的不同备选计量,不能把它们加总。货币计算使用十进制,不能跨币种合并。
如果想要完整刷新的一次请求,不传 accountId 调用一次 finance_get_balances 即可。该方法会自行发现所有有效会话,因此不需要先调用 finance_list_accounts。如果某个账户失败,返回仍会保留成功账户的余额,并另外对失败的账户报告更安全的错误。被标记为 aspsp_rate_limited 的账户不要立刻重试。
安装
安装过程会建立三层独立信任关系:Worker 需要向 Enable Banking 证明身份,银行授予 Worker 一个可撤回的授权,而且 Cloudflare Access 会控制谁能调用这套 MCP。
步骤 | 建立的信任 | 意义 |
注册 Enable Banking 应用 | Worker → Enable Banking 身份 | 应用程序 UUID 与 RSA 私钥用于对服务商请求签名 |
在 Enable Banking 控制面板关联账户 | 生产账户白名单 | 受限的应用只能访问在此前预审单上已知的个人账户 |
部署 Worker | 私有 MCP 运行时、会话存储 | 由 Cloudflare 执行代码,并租用 KV 保存会话 ID |
开启 Cloudflare Access 和 Managed OAuth | MCP 客户端 → Worker 身份 | 私有 Worker 拒绝对显式许可的调用者 |
通过 | 银行的授权及活跃的会话 ID | 白名单圈定账号;真正的 API 访问边界银行授权 |
1. 准备 Cloudflare 和 Enable Banking
你需要以下内容:
一个 Cloudflare 账号,并拥有
workers.dev子域和 Zero Trust;一个可打开受限生产模式 Enable Banking 应用;
该应用的 UUID 与 RSA 私钥。
在注册 Enable Banking 应用之前先确定 Worker 的名称。注册回调 URL 的时候,把两个占位符替换成实际值:
https://<worker-name>.<account-subdomain>.workers.dev/callback提交生产应用时,要在浏览器之外生成 RSA 密钥,再上传对应的 PEM 公钥证书。私钥要机密保存:部署流程会把它的主动隐。并且绝不能提交或泄露。
在 Enable Banking 控制面板内,将受限应用可能要访问的全部账户都做关联。控制面板的关联只是生产环境的白名单,并不能替应用签发会话授权。这个第二层授权需要部署后通过 /setup 去完成,参见 Enable Banking 的 关联账户指南。
本仓库是为个人、非商业用途设计的。请确认自己的部署符合 Enable Banking 当下的服务条款。
2. 部署到 Cloudflare
使用上方 Deploy to Cloudflare 按钮。Cloudflare 的部署流程会执行以下步骤:
复制仓库到你自己的 GitHub 或 GitLab 账户中;
请求提供
ENABLE_BANKING_APPLICATION_ID和ENABLE_BANKING_PRIVATE_KEY_PEM;预置在
SESSION_STOREKV 命名空间;关联该项目所需的 Cloudflare Access 策略;
通过 Workers Builds 构建并发布 Worker。
这两个密钥字段最初是从 .dev.vars.example 中取到的掩码占位值:一个全为 0 的 UUID 和一个 replace- 参数。用实际生产环境页命 UUID 和私钥替换之后再部署。
Cloudflare 会把 Access 当成可选项,因为一个默认公开 Worker 是可行的,但在本项目里它是必须项。在部署页上打开 Protect with Cloudflare Access,选择 All traffic,并添加认证策略。个人部署时,只允许你本人的身份(如果可信成员,或你的 Cloudflare 账户只让可信成员属于它)。Previews only(仅预览)不会保护生产 Worker。
这一行为 Cloudflare 文档中已有:请阅读 Deploy to Cloudflare buttons。
3. 启用 Managed OAuth
打开 Zero Trust → Access Controls → Access Applications → 已自动创建的那个 Access 应用。
进入 Advanced settings(高级设置),打开 Managed OAuth,并保存。
如果部署时没有选择 Protect with Cloudflare Access,请先手动可以为该 Worker 挂上 Worker 级轻量 Access,否则 Worker 在缺少内置的 ctx.access 时只能以 403 access_required 拒绝请求(fail closed)。Worker 级 Access 会保护 /、/setup、/callback 和 /mcp,该保护跨 Worker 所有关联域下生效。参见 Cloudflare 的 Worker-level Access guide。
Managed OAuth 会将受保护和 IsGrant from OAuth2 发现元数据提供给 MCP 客户端。Cloudflare 在处理到 Worker 之前的请求验证并不重复;本项目不会复制 Cloudflare 的 JWT 验证器。
4. 授权你的银行网络
打开
https://<your-worker>.workers.dev/setup。选择所在国家,以及登录身份是个人还是企业,再从 Enable Banking 当前支持的银行 list 选中。
在银行页完成授权。回调会校验
state,兑换一次性 code,并把得到的 Enable Banking 会话 ID 写回 KV。对每个登录有所不同进行重复。授权一次,可能有多个账户被开放。
如果授权过期或已撤销,回 custom-op /setup,删除那个不活跃会话,然后重新连。移除时也会让 Enable Banking 同步关闭它的授权。Enable Banking 在重新经过授权时会给新的 Session ID / Account ID ;MCP 会自动发现它们。
5. 连接 MCP 客户端
使用这个 MCP URL:
https://<your-worker>.workers.dev/mcp验证
在接入模型之前,请确认以下均满足:
未认证访问被 Cloudflare Access 请求;
/setup只显示本次部署所创建的会话;MCP
tools/list只暴露上表中的五个工具;finance_list_accounts只存在问题;一次余额或小额交易能够成功
一个“所有银行一次余额”的请求在其他 bank 失败时仍能返回成功 bank;
Cloudflare 日志中没有财务有效载荷、密钥、码、auth code或会话 ID。
项目刻意没有提供 /health 端点。云,也不是 Worker 上的必需端点;/mcp 和受保护 /setup 页面已经足以作为有效检查。
安全属性
修复上游来源(origin):请求只能发送到
https://api.enablebanking.com。修复提供商调用(provider operations):设置流程可以启动、完成和关闭账户授权;MCP 工具仅执行文档中所述的只读调用。
用户触发的账户读取会转发从传入的 Cloudflare 请求中派生出的有界
Psu-Ip-Address和Psu-User-Agent值;会话发现和授权请求不会接收这些请求头。账户强制校验:提供的每个账户 ID 都必须属于一个已存储的活跃会话。
设置与回调路由受到 Worker 级 Access 保护,并校验 origin/state。
授权码会立即完成兑换,且绝不持久化保存。
KV 仅存会话 ID,并由 Cloudflare 在静态存储时加密。
输入、日期、页数、结果数、上游响应及超时时间均有边界限制。
提供商故障仅记录规范化工具状态、HTTP 状态码、白名单内的允许错误码及有界的
Retry-After值——绝不记录标识符、请求头、提供商响应体或财务数据。不提供支付功能、通用 HTTP 工具、财务数据持久化、响应缓存或 CORS,也不记录敏感日志。
关于威胁模型和信息披露政策,请参阅 SECURITY.md。
开发
bun run typecheck
bun run test
bun run check测试在 Cloudflare Workers 运行时中运行,覆盖配置、Access 的fail-closed行为、设置授权、会话发现、账户强制校验、MCP 工具 schema、Enable Banking JWT 构造、规范化(normalization)以及有界响应。
提供商范围
Enable Banking 是第一个供应商模块。未来的提供商应透过相同的窄接口化、规范化财务接口来暴露能力,而不是将以可调 HTTP 的通用供应商操作泄漏给 MCP 工具。所有贡献必须保持 MCP 侧只读,并包含标识符验证与响应规范化的测试。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that exposes Enable Banking API tools for interacting with bank accounts through Open Banking. It enables users to authenticate sessions, list accounts, and fetch transaction history or balances via a secure self-hosted server.2
- AlicenseBqualityBmaintenanceEnables read-only access to personal bank accounts via the TrueLayer API, allowing querying of accounts, balances, transactions, and generating financial analytics such as spending by category, subscriptions, and monthly summaries.9MIT
- AlicenseNot gradedqualityCmaintenanceA remote MCP server on Cloudflare Workers that gives Claude read-only access to your Monzo account, enabling balance checks, transaction listing, and pot management via natural language.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI tools to interact with a Firefly III personal finance instance via MCP protocol, deployed on Cloudflare Workers for low-latency global access.12ISC
Related MCP Connectors
Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth
Brazilian Open Finance MCP — 30+ banks (Itaú, Nubank, etc.) to Claude/Cursor. Read-only.
Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/cver-me/EU-Open-Banking-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server