内容
# monzo-mcp
[](https://github.com/s-block/monzo-mcp/actions/workflows/ci.yml)
[](https://github.com/s-block/monzo-mcp/blob/main/LICENSE)
[](https://www.python.org/)
`monzo-mcp` 让 MCP 客户端可以通过 [Monzo 开发者 API](https://docs.monzo.com/) 与 Monzo 账户进行交互。它提供了用于读取账户、余额、储蓄罐和交易的功能。可选的写入工具可以将资金在账户和储蓄罐之间转移或为交易添加元数据。
服务器使用 MCP 的可流式 HTTP 传输,并作为 Docker 镜像分发。读取工具默认可用;写入工具必须在服务器启动时启用。
> [!WARNING]
> 这是具有金融数据访问权限的 alpha 软件。将其作为私有服务运行,并在连接账户之前查看 MCP 客户端的数据处理设置。
Monzo 表示其开发者 API 不适合通用公共应用程序。该项目旨在用于个人、自我托管或以其他方式允许的集成。
该项目独立且不隶属于 Monzo 或得到 Monzo 的认可。
## 工具
以下读取工具始终可用:
| 工具 | 描述 |
| --- | --- |
| `monzo_connection_status` | 检查当前的 Monzo 授权是否有效 |
| `monzo_list_accounts` | 列出 Monzo 账户 |
| `monzo_get_balance` | 获取账户余额 |
| `monzo_list_pots` | 列出储蓄罐及其余额 |
| `monzo_get_transaction` | 获取交易 |
| `monzo_list_transactions` | 列出一页交易 |
交易列表默认返回 30 个项目,时间范围为前 30 天。日期范围和页面大小可以由调用者更改,最多 100 个项目/请求。货币价值使用整数小单位,因此 `100` 代表 GBP 的 `£1.00`。
这些写入工具在启用 `MONZO_MCP_ENABLE_WRITES=true` 或 `--enable-writes` 时添加:
| 工具 | 描述 |
| --- | --- |
| `monzo_deposit_into_pot` | 将资金从账户转移到储蓄罐 |
| `monzo_withdraw_from_pot` | 将资金从储蓄罐转移到账户 |
| `monzo_annotate_transaction` | 设置或删除交易元数据 |
储蓄罐转账需要支持 MCP 表单诱导的客户端。客户端在转账进行前立即请求确认。
账户列表和交易结果省略了银行详细信息和其他这些工具不需要的字段。有关完整的输入、输出、分页规则和 Monzo API 限制,请参见 [工具和数据](docs/wiki/Tools-and-Data.md)。
## 部署模式
同一个镜像支持两种提供 Monzo 凭证的方式:
| 模式 | 用例 | 凭证存储 |
| --- | --- | --- |
| `local`(默认) | 私有部署,适用于单个 Monzo 连接 | 挂载卷上的加密文件 |
| `broker` | 已经管理 Monzo OAuth 的多用户主机 | 外部凭证代理 |
大多数用户应首先使用本地模式。代理模式适用于已经可以识别用户、存储其 OAuth 凭证并协调令牌刷新的现有服务。
## 入门指南
您需要:
- Docker 引擎或 Docker 桌面版;
- 支持 Streamable HTTP 和自定义标头的 MCP 客户端;
- 来自 [Monzo 开发者门户](https://developers.monzo.com/) 的机密 OAuth 客户端;以及
- OpenSSL 用于生成本地机密文件。
### 1. 获取镜像
构建当前源代码:
```bash
git clone https://github.com/s-block/monzo-mcp.git
cd monzo-mcp
docker build --tag monzo-mcp:local .
export MONZO_MCP_IMAGE=monzo-mcp:local
```
或者,使用已发布的镜像:
```bash
docker pull ghcr.io/s-block/monzo-mcp:latest
export MONZO_MCP_IMAGE=ghcr.io/s-block/monzo-mcp:latest
```
使用不可变的 `sha-<commit>` 标签或镜像摘要进行可重复部署。
### 2. 注册回调 URL
在 Monzo 开发者门户中创建一个机密 OAuth 客户端,并注册此确切的重定向 URI:
```text
http://127.0.0.1:8765/oauth/callback
```
保留客户端 ID 以备后用。客户端密钥将在下一步中保存到私有文件中。
### 3. 创建本地文件
```bash
MONZO_MCP_CONFIG_DIR="$HOME/.config/monzo-mcp"
install -d -m 700 \
"$MONZO_MCP_CONFIG_DIR" \
"$MONZO_MCP_CONFIG_DIR/credentials"
umask 077
openssl rand -base64 32 > "$MONZO_MCP_CONFIG_DIR/monzo-mcp.key"
openssl rand -hex 32 > "$MONZO_MCP_CONFIG_DIR/monzo-mcp-endpoint-token"
printf 'Monzo 客户端密钥: '
IFS= read -r -s monzo_mcp_client_secret
printf '\n'
printf '%s\n' "$monzo_mcp_client_secret" \
> "$MONZO_MCP_CONFIG_DIR/monzo-client-secret"
unset monzo_mcp_client_secret
chmod 600 \
"$MONZO_MCP_CONFIG_DIR/monzo-mcp.key" \
"$MONZO_MCP_CONFIG_DIR/monzo-mcp-endpoint-token" \
"$MONZO_MCP_CONFIG_DIR/monzo-client-secret"
```
凭证目录存储加密的 OAuth 授权。加密密钥、MCP 端点令牌和 OAuth 客户端密钥保留为单独的文件。
### 4. 授权 Monzo
在以下命令中替换 `YOUR_MONZO_CLIENT_ID`:
```bash
MONZO_MCP_CONFIG_DIR="$HOME/.config/monzo-mcp"
docker run --rm -it \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--user "$(id -u):$(id -g)" \
--tmpfs /tmp:rw,noexec,nosuid,size=16m,mode=1777 \
--publish 127.0.0.1:8765:8765 \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/credentials,dst=/credentials" \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/monzo-mcp.key,dst=/run/secrets/monzo-mcp.key,readonly" \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/monzo-client-secret,dst=/run/secrets/monzo-client-secret,readonly" \
"$MONZO_MCP_IMAGE" \
auth login \
--client-id YOUR_MONZO_CLIENT_ID \
--redirect-uri http://127.0.0.1:8765/oauth/callback \
--client-secret-file /run/secrets/monzo-client-secret \
--callback-bind 0.0.0.0
```
打开命令打印的 URL 并完成登录。在提示时,在 Monzo 移动应用中批准新的连接。
### 5. 启动服务器
```bash
MONZO_MCP_CONFIG_DIR="$HOME/.config/monzo-mcp"
docker run --rm --name monzo-mcp \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--user "$(id -u):$(id -g)" \
--tmpfs /tmp:rw,noexec,nosuid,size=16m,mode=1777 \
--publish 127.0.0.1:8000:8000 \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/credentials,dst=/credentials" \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/monzo-mcp.key,dst=/run/secrets/monzo-mcp.key,readonly" \
--mount "type=bind,src=$MONZO_MCP_CONFIG_DIR/monzo-mcp-endpoint-token,dst=/run/secrets/monzo-mcp-endpoint-token,readonly" \
--env MONZO_MCP_HTTP_HOST=0.0.0.0 \
--env MONZO_MCP_HTTP_ALLOWED_HOSTS=127.0.0.1:8000 \
"$MONZO_MCP_IMAGE"
```
MCP 端点是 `http://127.0.0.1:8000/mcp`。健康检查可在 `http://127.0.0.1:8000/healthz` 获得。
### 6. 配置 MCP 客户端
将客户端指向:
```text
http://127.0.0.1:8000/mcp
```
发送 `monzo-mcp-endpoint-token` 的内容作为 bearer 令牌:
```http
Authorization: Bearer <endpoint-token>
```
连接后,调用 `monzo_connection_status`,然后调用 `monzo_list_accounts` 以检查设置。
## 使用凭证代理
代理模式适用于已经管理 Monzo OAuth 的多用户 MCP 主机。设置:
```text
MONZO_MCP_ACCESS_TOKEN_PROVIDER=broker
MONZO_MCP_TOKEN_BROKER_URL=http://credential-broker:8000/access-token
```
每个传入的 MCP 请求还需要一个短期的委托标头:
```http
X-MCP-Credential-Delegation: Bearer <delegation>
```
代理端点、响应模式、刷新行为和部署示例在 [外部代理模式](docs/wiki/External-Broker-Mode.md) 中有文档记录。
## 配置
命令行选项覆盖其对应的环境变量。运行 `monzo-mcp --help` 或 `monzo-mcp <command> --help` 以查看可用的选项。
### 服务器
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `MONZO_MCP_ACCESS_TOKEN_PROVIDER` | `local` | 凭证模式:`local` 或 `broker` |
| `MONZO_MCP_ENABLE_WRITES` | `false` | 添加写入工具 |
| `MONZO_MCP_ENDPOINT_TOKEN_FILE` | `/run/secrets/monzo-mcp-endpoint-token` | 包含 MCP bearer 令牌的文件 |
| `MONZO_MCP_HTTP_HOST` | `0.0.0.0` | HTTP 绑定主机 |
| `MONZO_MCP_HTTP_PORT` | `8000` | HTTP 监听端口 |
| `MONZO_MCP_HTTP_ALLOWED_HOSTS` | 环回主机 | 以逗号分隔的 `Host` 值 |
| `MONZO_MCP_HTTP_ALLOWED_ORIGINS` | 空 | 以逗号分隔的浏览器源 |
| `MONZO_MCP_HTTP_MAX_REQUEST_BODY_BYTES` | `1048576` | 最大请求正文大小 |
| `MONZO_MCP_HTTP_MAX_CONCURRENT_REQUESTS` | `100` | 最大并发请求 |
当服务器绑定到非环回地址时,必须设置 `MONZO_MCP_HTTP_ALLOWED_HOSTS`,包括其默认 Docker 绑定。
### 本地模式
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `MONZO_MCP_CREDENTIAL_DIR` | `/credentials` | 可写的加密凭证目录 |
| `MONZO_MCP_KEY_FILE` | `/run/secrets/monzo-mcp.key` | 凭证加密密钥 |
只有一个本地模式进程可以同时使用一个凭证目录。
### 代理模式
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `MONZO_MCP_TOKEN_BROKER_URL` | 必需 | 凭证代理端点 |
| `MONZO_MCP_DELEGATION_HEADER_NAME` | `X-MCP-Credential-Delegation` | 传入的委托标头 |
| `MONZO_MCP_TOKEN_BROKER_TIMEOUT_SECONDS` | `5` | 代理请求超时 |
参见 [.env.example](.env.example) 和 [配置指南](docs/wiki/Configuration.md),了解验证规则和所有 CLI 等价项。
## 管理本地凭证
服务器在运行时保持凭证目录打开。在使用身份验证命令之前停止服务器。
要检查授权:
```bash
monzo-mcp auth status
```
要替换过期的或无效的授权,请再次运行 `auth login` 并重启服务器。
要使当前授权失效并在本地清除:
```bash
monzo-mcp auth logout
```
当这些命令在 Docker 中运行时,使用与登录命令相同的凭证目录和加密密钥挂载。 [操作指南](docs/wiki/Operations.md) 涵盖备份、恢复和凭证轮换。
## 安全性和部署
本地凭证在静止时加密,服务器需要一个单独的 bearer 令牌用于其 MCP 端点。请将服务保留在环回或私有网络上。对于远程访问,请将其置于 TLS 终止的反向代理后面,并将入口限制为预期的 MCP 客户端。
Docker 镜像以非 root 用户身份运行,并支持只读根文件系统。上面的示例还删除了 Linux 功能并启用了 `no-new-privileges`。
在远程部署服务器或启用写入之前,请阅读 [安全指南](docs/wiki/Security.md)。安全问题应通过 [GitHub 私有漏洞报告](https://github.com/s-block/monzo-mcp/security/advisories/new) 报告。
## 限制
- 该项目是 alpha 版本,其接口可能会在 1.0 版本之前更改。
- 本地模式支持每个凭证目录的 Monzo 授权。
- OAuth 登录和重新授权是命令行操作。
- 流式 HTTP 是唯一支持的 MCP 传输。
- 容器中不包含 TLS 终止。
- 代理模式需要单独的凭证代理。
- Monzo 权限、验证要求、受保护的储蓄罐规则、速率限制和交易历史记录限制仍然适用。
## 文档
[文档索引](docs/README.md) 链接到本地设置、Docker 部署、代理集成、配置、工具、操作和故障排除的版本指南。
## 开发
安装锁定后的开发依赖项:
```bash
uv sync --dev --frozen
```
完整的检查还需要 Node.js 进行 Markdown 验证。容器验证需要 Docker。
运行 Python 检查:
```bash
make check
```
运行 Docker 构建、烟雾测试和安全扫描:
```bash
make docker-check
```
其他有用的目标包括:
```bash
make help
make format
make docs-check
make type-check
make test
make test-cov
```
参见 [开发指南](docs/wiki/Development.md) 和 [贡献指南](CONTRIBUTING.md),了解仓库布局和贡献工作流程。
## 贡献
欢迎提出问题和拉取请求。在阅读 [`CONTRIBUTING.md`](CONTRIBUTING.md) 和 [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) 之前,请勿提交。
## 许可证
在 [MIT 许可证](https://github.com/s-block/monzo-mcp/blob/main/LICENSE) 下许可。