mcpField
M
Monexa

Monexa

远程服务
monexa.world金融数据02 周前更新

关于 Monexa

Monexa MCP 是供 AI 助手访问用户 Monexa 财务记录的远程服务。它提供记录、类别、支付方式、定期支出、趋势和设置相关工具,并通过委派令牌和路由白名单控制访问。

主要功能

  1. 01管理收入和支出记录
  2. 02访问类别和支付方式
  3. 03管理定期支出
  4. 04读取趋势报告和设置
  5. 05使用 OAuth 或个人访问令牌认证

适用场景

  1. 01查看收入与支出记录
  2. 02管理定期支出条目
  3. 03检查类别和支付方式
  4. 04通过 OAuth 或个人令牌连接助手

MCP 相关

通过 Streamable HTTP 在 `https://mcp.monexa.world/mcp` 提供 Monexa 工具。MCP 客户端使用 OAuth 访问令牌或个人访问令牌认证;委派的作用域控制读写权限。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.monexa.world/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

Monexa MCP 服务

Monexa 的远程 Model Context Protocol 服务,通过 Streamable HTTP 在 https://mcp.monexa.world/mcp 上提供服务。它让 AI 助手能够读取和管理用户的记录、类别、付款方式、定期支出、趋势报告和设置。

本 README 面向开发者和可自托管用户。要连接助手,请参阅用户指南。工具列表见 TOOLS.md。采用 MIT 许可证发布。

工作原理

  1. AI 应用使用 Monexa OAuth 访问令牌(mnx_at_…,通过后端提供的 OAuth 流程获取),或使用个人访问令牌(mnx_pat_…)通过 Authorization: Bearer 进行连接。
  2. 服务在后端交换 bearer 令牌(RFC 8693,POST /oauth/token,以 MCP 客户端身份进行身份验证),以获取短时有效的委托 JWT。成功的交换结果会按令牌哈希作为键缓存在内存中,最长 4 分钟;后端拒绝的令牌会在内存中缓存 30 秒后再响应。
  3. 每次工具调用都会使用该 JWT 调用 Monexa REST API(MONEXA_API_URL)。后端只允许委托令牌访问允许列表中的路由(internal/middlewares/delegated_access.go),并检查 monexa.read / monexa.write 范围。
  4. 服务通过受保护资源元数据将后端声明为其授权服务,以便 OAuth 客户端发现登录位置。服务会镜像后端的元数据文档,该文档在启动时获取。
  5. 服务是无状态的,不保留任何用户数据。每个请求都会创建自己的 MCP 服务实例。

环境变量

请在服务上设置这些变量。如果某个变量缺失或格式错误,服务将无法启动,并显示明确的提示信息。

变量必需必须与后端一致描述
PORT否监听端口,默认为 8080。
MCP_PUBLIC_URL是MCP_RESOURCE_URL(此值加上 /mcp)此服务的公开源,例如 https://mcp.monexa.world。不能包含路径。仅当主机为 localhost、127.0.0.1 和 [::1] 时才接受 http。
MONEXA_OAUTH_ISSUER是OAUTH_ISSUER_URL公开 OAuth 签发者,例如 https://api.monexa.world。必须是不带尾部斜杠的纯源,并与后端元数据中的 issuer 逐字匹配。
MONEXA_API_URL是此服务可访问的后端基础 URL,例如 http://backend:8080。不一定是公开地址。
MCP_CLIENT_ID是MCP_CLIENT_ID后端用于识别令牌交换请求的 OAuth 客户端。
MCP_CLIENT_SECRET是MCP_CLIENT_SECRET至少 32 个字符。使用 openssl rand -hex 32 生成。
ALLOWED_HOSTS生产环境必需以逗号分隔的主机名列表,用于校验 Host 标头;必须包含 MCP_PUBLIC_URL 的主机。非生产环境下默认为 localhost,127.0.0.1(设置 NODE_ENV=production 后此变量为必需)。
OPENAI_APPS_CHALLENGE_TOKEN否在 /.well-known/openai-apps-challenge 以纯文本形式提供,用于 OpenAI 域名验证;未设置时不会提供该路由。

相同配置在后端一侧对应 OAUTH_ISSUER_URL、MCP_RESOURCE_URL、MCP_CLIENT_ID 和 MCP_CLIENT_SECRET,还可选配 OAUTH_ACCESS_TOKEN_TTL(默认为 1h)和 OAUTH_REFRESH_TOKEN_TTL(默认为 2160h)。后端必须全部设置这四个变量,或全部不设置;未设置时不会提供任何 OAuth 路由。部署详情见 docs/DEPLOYMENT.md。

路由

路由说明
POST /mcpMCP 端点。需要持有者令牌。
GET /.well-known/oauth-protected-resource/mcp受保护资源元数据。
GET /.well-known/oauth-authorization-server后端授权服务器元数据的镜像。
GET /.well-known/openai-apps-challengeOpenAI 域名验证令牌(如已配置)。
GET /healthz后端元数据加载完成后返回 200 {"status":"ok","version":…},此前返回 503。此路由不受主机验证限制,因此容器可通过 127.0.0.1 进行探测。
GET /icon.svg、GET /icon.pngserverInfo.icons 中公布的 Monexa 图标。

在后端元数据加载完成前,除 /healthz 外的所有路由都会返回带有 Retry-After 的 503。启动时,服务会每隔 2 秒获取 ${MONEXA_API_URL}/.well-known/oauth-authorization-server,最多尝试 30 次;如果始终未成功,或 issuer 与 MONEXA_OAUTH_ISSUER 不同,则以代码 1 退出。后端故障或客户端密钥被拒绝时,客户端会收到 503,而不是 401,因此不会陷入重新认证循环。

本地开发

需要 Node 22,以及已启用 OAuth 并正在运行的后端。在后端环境中设置

OAUTH_ISSUER_URL=http://localhost:9000
MCP_RESOURCE_URL=http://localhost:3001/mcp
MCP_CLIENT_ID=monexa-mcp
MCP_CLIENT_SECRET=<at least 32 characters>

然后使用相同的客户端凭据运行 MCP 服务。npm run dev 会在 mcp-server/.env 文件存在时加载该文件(已被 git 忽略),因此请将凭据放在那里:

PORT=3001
MCP_PUBLIC_URL=http://localhost:3001
MONEXA_OAUTH_ISSUER=http://localhost:9000
MONEXA_API_URL=http://localhost:9000
MCP_CLIENT_ID=monexa-mcp
MCP_CLIENT_SECRET=<same secret as the backend>
cd mcp-server
npm install
npm run dev

将 MCP Inspector(npx @modelcontextprotocol/inspector)指向 http://localhost:3001/mcp,并通过 OAuth 登录;或者粘贴在 Web 应用的 Settings、Connected apps 下创建的个人访问令牌。

脚本

脚本功能
npm run dev使用 tsx watch 运行 src/index.ts。
npm run build使用 tsc -p tsconfig.build.json 将 src 编译到 dist/。
npm start运行编译后的服务:node dist/index.js。
npm run typecheck对 src、scripts 和 test 执行 tsc --noEmit。
npm run check运行下文所述的漂移检查。
npm run docs根据工具注册表重新生成 TOOLS.md。
npm test运行 test/ 中的 vitest 测试套件。根据项目规定,测试仅在本地运行:绝不会提交测试,CI 也不会运行测试。
漂移检查

如果以下条件未全部满足,npm run check 会以代码 1 退出并显示易读的提示:

  • ../docs/api-routes.json 中的每条路由(由后端路由清单 go run ./cmd/routes -write 写入)都恰好由一个工具的 covers 列表覆盖,或在 src/tools/excluded.ts 中列出并附有原因;此外,每个 covers 条目或排除条目都必须存在于清单中。
  • 工具覆盖的每条路由在清单中都标记为 "delegated": true,这表示 internal/middlewares/delegated_access.go 中的后端允许列表允许已连接的应用调用该路由。
  • 工具名称唯一,采用 snake_case 格式且不超过 64 个字符;每个工具都具有标题和四个注解提示,其中 openWorldHint: false。
  • 带有 readOnlyHint: true 的工具只能覆盖 GET 路由。
  • TOOLS.md 与 npm run docs 生成的内容一致。
  • server.json 的 version 与 package.json 相同,且描述不超过 100 个字符。

当后端新增路由或其委派允许列表发生变化时,go run ./cmd/routes -check 会首先失败。使用 -write 运行该命令,然后添加一个覆盖该路由的工具或在 excluded.ts 中添加条目,再运行 npm run docs,并将结果一并提交。

工具

22 个工具覆盖后端 65 个 API 路由中的 24 个;其余 41 个有意排除,例如登录、会话和账户安全路由、OAuth 端点、法律文档、数据导出和趋势报告编辑(参见 src/tools/excluded.ts 和 TOOLS.md 末尾)。工具名称使用 snake_case,输入名称使用 camelCase(例如 includeDetails),并且在调用任何 API 前都会使用 zod 验证输入。每个工具都声明 title、readOnlyHint、destructiveHint、idempotentHint 和 openWorldHint: false,并同时返回 structuredContent 和 JSON 文本块。

运维

  • 日志记录。 每个 /mcp 请求记录一行 JSON,包含 HTTP 和 JSON-RPC 方法、工具名称、状态、耗时(毫秒)以及 OAuth 客户端 ID。绝不记录令牌和工具参数。
  • 关闭。 收到 SIGTERM 或 SIGINT 后,服务停止接受连接,并等待正在处理的请求完成。请求完成后以 0 退出,8 秒后强制以 1 退出。
  • 容器。 Dockerfile 构建一个以非 root 用户运行并探测 /healthz 的 node:22-alpine 镜像;启动等待期为元数据重试留出了时间。

版本控制与发布

package.json 中的版本遵循 SemVer;server.json 必须使用相同版本,且 npm run check 会对此进行检查。

  • 主版本:移除或重命名工具,或对工具的架构进行不兼容的更改。
  • 次版本:新增工具或新增可选参数。
  • 修订版本:不更改架构的修复。

在 CHANGELOG.md 的 ## [Unreleased] 下记录更改(Keep a Changelog),发布时将这些更改移至新版本标题下。将新工具的 since 设置为引入该工具的版本。

发布时,更新 package.json、server.json 和变更日志中的版本,合并到 master,然后推送标签 mcp-vX.Y.Z(例如 git tag mcp-v2.0.0 && git push origin mcp-v2.0.0)。CI 会推送镜像 ghcr.io/emilijan-koteski/monexa-mcp:vX.Y.Z,并将 server.json 以 io.github.emilijan-koteski/monexa 的名称发布到官方 MCP Registry。合并到 master 后,无论是否有标签,都会独立部署 sha-<short> 镜像到生产环境。

支持

问题和错误报告请发送至:[email protected],或在 GitHub 上提交 issue。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。