mcpField
M
mercury-multiorg-mcp

mercury-multiorg-mcp

本地服务
github.com/dkaleganov金融数据06 周前更新

关于 mercury-multiorg-mcp

mercury-multiorg-mcp 是非官方的只读 MCP 服务,可在一个 AI 会话中访问多个 Mercury 组织。它通过明确的实体键路由调用,并用字段白名单限制返回的结构化数据。

主要功能

  1. 01在一个会话中访问多个组织
  2. 02每次调用显式指定实体
  3. 03只读访问 Mercury API
  4. 04结构化结果字段采用白名单
  5. 05可选获取对账单和发票 PDF

适用场景

  1. 01查看多个 Mercury 组织的数据
  2. 02按实体获取账户和交易信息
  3. 03为需要原始文档的会话启用 PDF 获取

MCP 相关

该服务通过本地 stdio MCP 工具提供 Mercury 组织数据。只有明确启用文档访问后,才会注册 PDF 工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"dkaleganov-mercury-multiorg": {
"command": "uvx",
"args": [
"mercury-multiorg-mcp"
],
"env": {
"MERCURY_TOKEN_ACME_MAIN": "<MERCURY_TOKEN_ACME_MAIN>",
"MERCURY_ENTITIES_FILE": "<MERCURY_ENTITIES_FILE>",
"MERCURY_API_BASE": "<MERCURY_API_BASE>",
"MERCURY_ALLOW_DOCUMENTS": "<MERCURY_ALLOW_DOCUMENTS>"
}
}
}
}
启动命令uvx mercury-multiorg-mcp
需要配置的环境变量
MERCURY_TOKEN_ACME_MAIN密钥Example only. Each organization needs one read-only Mercury API token in the environment variable named by its token_env in your registry. Names are yours to choose but must match MERCURY_TOKEN_[A-Z0-9_]+ (for example MERCURY_TOKEN_<ENTITY_KEY>); set one per organization and rename this example to match.
MERCURY_ENTITIES_FILEAlternative to --entities: path to the entity registry YAML. Ignored when --entities is passed.
MERCURY_API_BASEMercury API host. Allowed without extra flags: https://api.mercury.com, https://api-sandbox.mercury.com (with sandbox tokens), or a loopback mock.
MERCURY_ALLOW_DOCUMENTSSet to true to register get_statement_pdf and get_invoice_pdf, which return statement and invoice PDFs unredacted. Off by default.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimercury-multiorg-mcp0.1.6

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mercury-multiorg-mcp

非官方项目,与 Mercury 无关联,也未获其认可。

只读 MCP 服务,可将多个 Mercury 组织接入同一个 AI 会话。Mercury API 令牌是在单个组织内部创建的,因此此服务会为每个组织保存一个只读令牌,并根据显式的 entity 键路由每次工具调用。

版本 0.1.6(参见 CHANGELOG.md)。维护者使用 vX.Y.Z 标记发布版本;可通过以下命令查找用于固定版本的提交: git ls-remote --tags https://github.com/dkaleganov/mercury-multiorg-mcp 'v0.1.6^{}'。 包含所有返回字段的完整工具参考见 docs/tools.md;设计说明和构建历史见 GitHub 上的项目简介 CLAUDE.md (未随 sdist 一同发布)。

安全模型

此服务发出的内容分为四类,各类的保障措施有所不同:

类别内容保障措施
结构化字段工具结果中每个对象的所有键每一层都使用允许列表:每个对象及其中的每个嵌套对象,都会通过从实时架构复制的显式允许列表进行筛选。未列出的键不会离开此服务,无论其位于哪一层。账号号码和税号仅显示最后四位;路由号码、交易对手银行信息、邮寄地址、银行卡到期日、预签名下载 URL、发票付款页面 slug、webhook 接收方 URL 和 webhook 签名密钥均不会返回。
工具错误is_error 结果中的文本上游 HTTP 状态错误会包含状态码、经过掩码处理的端点标签和固定提示。验证错误和配置错误使用各自可操作的格式。已解析的已知令牌值若至少有八个字符,就会被清除。不会引用 Mercury 响应正文或标头中的任何内容,也不会回显你传入的任何参数(无效 ID 会报告为“ID 格式无效”)。参数验证失败(类型错误、缺少必需参数)会由此服务仅以字段路径和预期类型呈现,例如 year: expected an integer (int_parsing);MCP SDK 自身会引用你传入值的错误呈现内容不会到达客户端。
自由文本字段交易备注、交易对手名称、银行描述、发票备注和说明、附件文件名、客户和用户名称原样返回。这些是第三方文本,可能包含任何内容,包括针对模型的指令,以及由人工输入的标识符。应将每个工具结果都视为不可信数据,绝不能将其视为指令。
文档get_statement_pdf / get_invoice_pdf 返回的对账单和发票 PDF原样返回,不做删改,仅在选择启用后提供。对账单 PDF 包含完整账号号码、路由号码、地址和所有交易。只有在启动服务时使用 --allow-documents(或设置 MERCURY_ALLOW_DOCUMENTS=1),才会提供这两个工具;server_info.documents_enabled 会报告该设置。正文必须以 application/pdf(或 application/octet-stream)形式传入,以 %PDF- 开头,并且在忽略末尾 PDF 空白字符后,最后 2 KiB 内必须包含 %%EOF 标记;否则会返回明确错误。这只是信封检查,并非 PDF 解析:通过检查的文档内部仍可能格式错误,且返回的字节与收到时完全一致。

安全模型的其余部分:

  • 只读。 客户端方法仅对应 GET 端点;此软件包没有任何可转移资金、编辑收款人或更改其他内容的代码路径。
  • 仅使用 Stdio。 服务不会打开网络监听器。
  • 实体必须明确指定。 调用 list_entities 以发现实体键。每个访问 Mercury 的工具都必须显式指定 entity,并在成功结果中标明该实体。list_entities 和 server_info 无需实体参数。不存在默认实体。
  • 令牌保留在环境中。 注册表会为每个组织指定一个环境变量(变量名必须为 MERCURY_TOKEN_…,因此注册表无法让服务指向其他密钥);服务只读取该环境变量,不读取其他内容。错误和日志中显示的令牌字符数不会超过末尾 4 个。对长度不少于 8 个字符的值,会执行已知令牌的字面值脱敏;较短的配置值不会进行字面值脱敏(secret-token: 格式脱敏和 Authorization 标头脱敏仍然适用,而且消息本身不会引用上游或调用方数据)。启动时,如果某个实体的配置值不带 Mercury 文档所述的 secret-token: 前缀,服务会针对该实体发出警告。
  • 仅限 Mercury 主机。 --api-base / MERCURY_API_BASE 必须是 https://api.mercury.com、https://api-sandbox.mercury.com 或环回模拟服务;除非在命令行中传入 --allow-custom-api-base。仅靠继承的环境变量绝不能将 bearer 令牌重定向到其他主机。
  • 限制线上字节数。 每个请求都会拒绝压缩(Accept-Encoding: identity)。读取 JSON/PDF 前会拒绝非 identity 编码。保持连接时会关闭响应体而不读取。PDF 限制为 10 MiB(10,485,760 字节),JSON 限制为 32 MiB(33,554,432 字节);限制针对流式接收的实际字节数进行强制执行。小型压缩响应体不再可能在内存中扩展至超过限制。完全不读取错误响应。
  • 要么完整,要么明确报错。 遍历会在达到请求的限制或 API 末尾时停止。缺失或错误的 page 对象会导致失败;可选的末尾 nextPage 可以缺失或为 null。完全重复的 ID 会被丢弃并计数;内容冲突则会导致失败。如果还有更多数据的提示,但某一页没有新增的可用行,则会导致失败。需要超过 200 页的遍历会失败;不是非负整数的 treasury cursor 也会导致失败。每个分页结果和 reportable_totals.totals 中都会报告 duplicates_dropped,因此总数绝不会基于停滞、格式错误或重复计数的遍历生成。
  • 完整遍历窗口化数据流。 Mercury 未为事件或 treasury 交易指定排序键,因此客户端窗口(list_events 中的 since,以及 list_treasury_transactions 中的 start / end)会完整遍历有界数据流(90 天的事件;最多 200 页的 treasury 账本),在此处筛选并按最新优先排序,然后再应用 limit。truncated 的值准确无误。开销与数据流大小成正比,而非与窗口大小成正比。
  • 二进制文档保留在内存中。 PDF 会以嵌入式 application/pdf blob(base64)形式返回,绝不会写入磁盘。
  • 验证路径 ID。 每个会成为请求路径一部分的 ID 都必须是单个安全路径段;无法借此将调用重定向到其他端点。
  • 启动错误仅输出一行,退出码为 2。 注册表缺失或格式错误(包括非字符串 YAML 键)、文件无法读取、--env-file 无效或 API 主机不允许时,都会向 stderr 输出一行并以状态码 2 退出。脱敏异常钩子会在加载任何内容前安装,因此任何启动路径都不会输出未经脱敏的回溯信息。
  • 绝不处理申报文件。 reportable_totals 用于申报前交叉核对。Mercury 没有 1099 申报端点;申报在各组织的仪表板中进行。 安全卫生。 这个软件包位于一个公开仓库中。受跟踪的文件、 测试夹具和提交消息均不包含令牌、账户号码或 金融标识符,但有两个特意保留的例外。第一, 维护者本人的姓名出现在软件包的 authors 元数据中(经 仓库所有者批准);其他任何人的商业和个人姓名都不会出现。第二, 一条历史记录:第一笔 Phase 1 提交中的测试夹具 曾使用一个真实、公开的 ABA 路由号码作为示例数据;下一笔提交中已将其替换 为明显的虚构值,因此它不在任何已打标签的文件树中,但仍保留在这些文件树的 提交历史中。它标识的是一家银行,而非账户,且历史记录有意未被重写。本次发布通过了对完整历史记录的 gitleaks 扫描。

仓库历史。 本软件包最初在一个多项目单体仓库中开发,直至 v0.1.3;在 v0.1.4 时迁移至此仓库, 并保留了历史记录(相同的提交,按此仓库的布局重写,因此其 SHA 与原始版本不同)。截至 0.1.3 的版本在 原仓库中使用 mercury-v0.1.x 标记,在此仓库中使用 v0.1.x 标记;从现在起,发布标签采用 vX.Y.Z 格式。上述两项安全卫生例外在这段历史中也同样存在,且未作更改。

安装

从 PyPI 使用 uvx 运行固定版本(无需克隆):

uvx [email protected] --entities /private/path/entities.yaml

uvx <package>@<version> 会在隔离的缓存环境中运行指定版本。pip install 'mercury-multiorg-mcp==0.1.6' 也可用,并会将 mercury-multiorg-mcp 和 mercury-multiorg-mcp-keepalive 放入你的 PATH。

需要 Python 3.11+ 和 uv(用于 uvx)。

从源代码安装 / 固定提交

从克隆的仓库安装:

git clone https://github.com/dkaleganov/mercury-multiorg-mcp.git   # or [email protected]:dkaleganov/mercury-multiorg-mcp.git
cd mercury-multiorg-mcp
uv sync
uv run mercury-multiorg-mcp --entities /private/path/entities.yaml

也可以使用 uvx 固定完整提交 SHA(应固定 SHA,而非标签:完整 SHA 不可变且可安全用于缓存,而标签可能被移动):

uvx --from 'git+https://github.com/dkaleganov/mercury-multiorg-mcp@<FULL_COMMIT_SHA>' \
  mercury-multiorg-mcp --entities /private/path/entities.yaml

配置

  1. 在每个 Mercury 组织中:组织切换器 → All Settings → Tokens → 创建一个 只读令牌(无需 IP 允许列表)。
  2. 将 entities.example.yaml 复制到此仓库之外的私有位置,并 列出你的组织(key、display_name、token_env;环境变量名称必须以 MERCURY_TOKEN_ 开头)。
  3. 在启动服务的环境中,为每个组织导出一个环境变量,名称按注册表中的设置填写(.env.example 展示了这些名称)。配置 仅从进程环境变量中读取;除非传入 --env-file <path>,否则不会读取 .env 文件,因此不会意外从 仓库、主目录或 uvx 缓存中加载任何内容。
  4. 可选:使用沙盒中创建的令牌时,设置 MERCURY_API_BASE=https://api-sandbox.mercury.com。
  5. 可选:设置 --allow-documents(或 MERCURY_ALLOW_DOCUMENTS=1)以注册 两个 PDF 工具。除非会话确实需要 未脱敏的文档,否则请勿启用。
命令行
标志 / 环境变量含义
--entities PATH / MERCURY_ENTITIES_FILE实体注册表 YAML。必需(标志优先于环境变量);没有隐式默认值。
--env-file PATH在解析令牌前加载此 dotenv 文件。现有环境变量优先。未指定此标志时,不会从任何位置读取 dotenv 文件。
--api-base URL / MERCURY_API_BASEMercury API 主机,默认为 https://api.mercury.com。允许使用:生产环境、https://api-sandbox.mercury.com,或用于模拟的 localhost / 127.0.0.1 上的纯 http://。
--allow-custom-api-base允许使用其他任意 https:// 主机。切勿通过环境变量设置此项;此选项的存在是为了确保自定义主机始终由命令行明确指定。
--allow-documents / MERCURY_ALLOW_DOCUMENTS=1注册 get_statement_pdf 和 get_invoice_pdf(返回的文档不会经过脱敏)。默认关闭:不启用时有 24 个工具,启用后有 26 个。
--version打印软件包版本并退出。

启动问题(注册表缺失或格式错误、YAML 无效、文件不可读、API 主机地址错误)会向 stderr 打印一行错误信息并以状态码 2 退出。Stdout 保留给 MCP 协议使用。

Mercury 会在 API 令牌闲置 45 天后将其删除(令牌闲置计时),并单独降级 45 天未使用的权限。请定期运行 mercury-multiorg-mcp-keepalive,以确保闲置计时永不过期;cron 和 launchd 示例请参阅 docs/keepalive.md。

适用于本地 stdio MCP 客户端

兼容支持本地 stdio 服务和协商后的协议版本的 MCP 客户端。在客户端主机上配置以下命令,并确保其可以访问私有注册表和环境文件。各客户端的文档显示和审批策略各不相同。此服务不提供 HTTP 或 SSE。所有客户端使用的命令和参数都相同:

command: uvx
args:    [email protected] --entities /private/path/entities.yaml
optional extra arg: --allow-documents   (registers the two unredacted PDF tools)

若要运行固定提交版本而非 PyPI 发行版,请将第一个参数替换为 --from、git+https://github.com/dkaleganov/mercury-multiorg-mcp@<FULL_COMMIT_SHA>、mercury-multiorg-mcp(参见“从源码安装 / 固定提交版本”)。

令牌会作为注册表中指定名称的环境变量传递给服务。提供令牌有两种方式:在客户端配置中使用 env 块(仅适用于会从 shell 展开 ${MERCURY_TOKEN_ACME_MAIN} 等占位符的客户端;在配置文件中直接写入令牌会使其成为磁盘上的秘密),或使用私有 dotenv 文件。通过 --env-file /private/path/mercury.env 传入私有 dotenv 文件,可避免依赖特定客户端的占位符展开。客户端主机必须能够读取该文件;现有进程环境变量优先。请将注册表和 dotenv 文件保存在所有代码仓库之外,并确保只有你的用户可以读取。

Claude Code(.mcp.json)

Claude Code 会从其环境中展开 ${VAR}。本仓库包含一个示例 .mcp.json;能够发现此格式的客户端可能会提供启动选项。该文件指向合成示例注册表,不含凭据(因此 list_accounts 会返回干净的逐实体错误)。

{
  "mcpServers": {
    "mercury-multiorg": {
      "command": "uvx",
      "args": [
        "[email protected]",
        "--entities",
        "/private/path/entities.yaml"
      ],
      "env": {
        "MERCURY_TOKEN_ACME_MAIN": "${MERCURY_TOKEN_ACME_MAIN}"
      }
    }
  }
}
Claude Desktop(claude_desktop_config.json)

打开 Settings → Developer → Edit Config。使用 --env-file,使此配置不依赖特定客户端的占位符展开:

{
  "mcpServers": {
    "mercury-multiorg": {
      "command": "uvx",
      "args": [
        "[email protected]",
        "--entities",
        "/private/path/entities.yaml",
        "--env-file",
        "/private/path/mercury.env"
      ]
    }
  }
}
Codex CLI(~/.codex/config.toml)
[mcp_servers.mercury-multiorg]
command = "uvx"
args = [
  "[email protected]",
  "--entities", "/private/path/entities.yaml",
  "--env-file", "/private/path/mercury.env",
]
# `env = { MERCURY_TOKEN_ACME_MAIN = "..." }` is also accepted, but values there are
# literal, so prefer --env-file over putting a token in this file.
Cursor / Windsurf 旧版 Cascade(mcp.json)

Cursor 使用 .cursor/mcp.json 或 ~/.cursor/mcp.json。Windsurf 旧版 Cascade 使用 ~/.codeium/windsurf/mcp_config.json。当前默认的 Devin Local Agent 使用自己的 CLI 配置;此示例针对旧版 Cascade。两者都使用 mcpServers 映射。除非客户端文档说明其会展开环境变量占位符,否则请使用 --env-file。

{
  "mcpServers": {
    "mercury-multiorg": {
      "command": "uvx",
      "args": [
        "[email protected]",
        "--entities",
        "/private/path/entities.yaml",
        "--env-file",
        "/private/path/mercury.env"
      ]
    }
  }
}
VS Code(.vscode/mcp.json)

VS Code 使用 servers 映射(而非 mcpServers),并显式指定 "type": "stdio":

{
  "servers": {
    "mercury-multiorg": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "[email protected]",
        "--entities", "/private/path/entities.yaml",
        "--env-file", "/private/path/mercury.env"
      ]
    }
  }
}
Gemini CLI(~/.gemini/settings.json 或 .gemini/settings.json)
{
  "mcpServers": {
    "mercury-multiorg": {
      "command": "uvx",
      "args": [
        "[email protected]",
        "--entities",
        "/private/path/entities.yaml",
        "--env-file",
        "/private/path/mercury.env"
      ]
    }
  }
}
其他 stdio 客户端

任何支持本地 stdio 服务和协商后的协议版本、且运行所在主机可以读取私有注册表和环境文件的客户端:将其指向相同的 uvx 命令和参数即可。服务不会打开网络监听器,因此不提供 HTTP 或 SSE 传输。

工具

每个访问 Mercury 的工具都需要显式指定 entity,并在成功结果中标明该实体;list_entities 和 server_info 无需实体参数。七个带有 limit 参数的工具会返回 count 和 truncated。完整列表工具没有公开的限制。分页结果还会显示重复项诊断信息(duplicates_dropped:遍历过程中丢弃的相同行)。完整的逐字段参考文档: docs/tools.md。

工具参数返回值
list_entities—实体键、显示名称、各令牌环境变量是否已设置
server_info—软件包版本、API 基址、实体数量、documents_enabled(不含机密)
list_accountsentity账户及余额、accountNumberLast4
list_transactionsentity、account_id?、start?、end?、search?、limit=100按 Mercury API 的 desc 顺序排列的交易、truncated 标志
reportable_totalsentity、year、threshold?(截至 2025 年默认为 600,自 2026 年起默认为 2000,适用于非雇员服务和某些 MISC 付款;必须为有限数值,且不超过 1,000,000,000)每位收款人的 1099 交叉核对总额;needs_review 分类、unclassified、excluded_summary
list_recipientsentity收款人:ID、姓名、昵称、状态、默认付款方式、最近付款日期、电子邮件、isBusiness
list_tax_docsentity每位收款人的税务表单附件,以及 recipients_without_docs
get_orgentityID、法定名称、DBA、类别、订阅层级、账单周期、einLast4
list_statementsentity、account_id、start?、end?、limit=100按 Mercury API 的 desc 顺序排列的对账单元数据(已屏蔽的账户号码和 EIN、transactionCount)
get_statement_pdf(可选启用)entity、statement_id以嵌入式 blob 返回对账单 PDF(≤ 10 MB),未脱敏;仅在启用 --allow-documents 时可用
list_treasuryentity国库账户及余额和月度净收益
list_treasury_transactionsentity、treasury_id、start?、end?、limit=100按 Mercury API 的 desc 顺序排列的国库账本行;指定日期范围时,会遍历整个账本、筛选并按 canonicalDay 从新到旧排序
list_treasury_statementsentity、treasury_id、document_type?国库对账单和税务文件(元数据)
list_credit_accountsentity信用账户及余额
list_cardsentity、account_id?、status?、limit=100卡片:末四位数字、姓名、昵称、类别、类型、状态、限额、预算、锁定状态
get_cardentity、card_id单张卡片,字段相同
list_categoriesentity自定义支出类别
list_merchantsentity、search?、limit=100优先商户(ID、名称)
list_customersentity应收账款客户:ID、姓名、电子邮件、deletedAt
list_invoicesentity、status?、start?、end?、limit=100应收账款发票(完整遍历后在客户端应用筛选条件)
get_invoiceentity、invoice_id单张发票,含服务期间和行项目
get_invoice_pdf(可选启用)entity、invoice_id以嵌入式 blob 返回发票 PDF(≤ 10 MB),未脱敏;仅在启用 --allow-documents 时可用
list_invoice_attachmentsentity、invoice_id附件 ID 和文件名(不含 URL)
list_usersentity用户:ID、名字和姓氏、电子邮件、角色
list_eventsentity、since?、resource_type?、limit=100按 Mercury API 的 desc 顺序排列的变更事件;指定 since 时,会遍历整个 90 天事件流、筛选并按 occurredAt 从新到旧排序;按资源允许列表重新投影补丁
list_webhooksentitywebhook 端点:ID、url_fingerprint、状态、enabled、事件类型、筛选路径(绝不返回密钥或接收端 URL 的任何部分)

list_transactions 中的 start / end 按 createdAt 筛选(格式为 YYYY-MM-DD 或 ISO 8601)。Mercury 控制面板可能显示 postedAt,因此日期范围可能与界面不同。

第 1 和第 2 阶段工具的返回值
list_entities               entities[] {entity, display_name, token_configured}
server_info                 name, version, api_base, entity_count, entities_with_token, transport, read_only,
                            documents_enabled
list_accounts               entity, duplicates_dropped, accounts[] {id, name, nickname, legalBusinessName, kind, type,
                            status, availableBalance, currentBalance, createdAt, canReceiveTransactions,
                            dashboardLink, accountNumberLast4}
list_transactions           entity, filters, count, truncated, duplicates_dropped, transactions[] {id, accountId,
                            amount, status, kind, createdAt, postedAt, estimatedDeliveryDate, failedAt,
                            reasonForFailure, counterpartyId, counterpartyName, counterpartyNickname,
                            bankDescription, externalMemo, note, mercuryCategory,
                            categoryData {id, name, visibleForCardSpend, visibleForOther, visibleForReimbursements} | null,
                            merchant {id, category, categoryCode, currency, amount}, checkNumber, cardId,
                            currencyExchangeInfo {convertedFromAmount, convertedFromCurrency, convertedToAmount,
                            convertedToCurrency, exchangeRate, feeAmount, feePercentage, feeTransactionId},
                            dashboardLink}
list_recipients             entity, count, duplicates_dropped, recipients[] {id, name, nickname, status,
                            defaultPaymentMethod, dateLastPaid, emails [strings], contactEmail, isBusiness}
list_tax_docs               see the `list_tax_docs` section below (documents[] {id, recipientId, recipientName,
                            fileName, formType, uploadedAt})
reportable_totals           see the `reportable_totals` section below
阶段 3 工具的返回值
get_org                     entity, organization {id, legalBusinessName, dbas [{dbaName, dbaIsDefault}], kind,
                            subscriptionTier, billingCadence, einLast4}
list_statements             entity, account_id, filters, count, truncated, duplicates_dropped,
                            statements[] {id, startDate, endDate, endingBalance, companyLegalName,
                            accountNumberLast4, einLast4, transactionCount}
get_statement_pdf           content[0] text {entity, statement_id, mimeType, bytes, encoding, redacted: false};
                            content[1] embedded resource {uri, mimeType: application/pdf, blob (base64)}
list_treasury               entity, count, duplicates_dropped, treasury_accounts[] {id, status, availableBalance, currentBalance,
                            createdAt, netReturns[] {month, netAmount, treasuryFee, status,
                            dividends[] {id, type, securityName, amount}}}
list_treasury_transactions  entity, treasury_id, filters, count, truncated, duplicates_dropped, transactions[] {id, accountId, type,
                            amount, balance, canonicalDay, description, additionalDetails, security,
                            details {creditDescription, depositCounterpartyId, feeDescription,
                            manualAmendmentDescription, security, sweepDirection, tradeAction,
                            withdrawalCounterpartyId}}
list_treasury_statements    entity, treasury_id, filters, count, duplicates_dropped, statements[] {id, accountId, documentType,
                            description, periodStart, periodEnd, creationDate, createdAt, updatedAt}
list_credit_accounts        entity, count, credit_accounts[] {id, status, availableBalance, currentBalance, createdAt}
list_cards                  entity, filters, count, truncated, duplicates_dropped, cards[] {id, accountId, userId, nameOnCard, nickname,
                            lastFour, kind, type, status, physicalCardStatus, isAgentCard, spendLimitType,
                            spendLimit {amountCents, atmAmountCents, interval},
                            budgets[] {id, name, amountCents, remainingAmountCents}, merchantLock {id, name},
                            categoryLocks [strings], createdAt, updatedAt}
get_card                    entity, card {same fields as one list_cards row}
list_categories             entity, count, duplicates_dropped, categories[] {id, name, visibleForCardSpend, visibleForOther,
                            visibleForReimbursements}
list_merchants              entity, filters, count, truncated, duplicates_dropped, merchants[] {id, name}
list_customers              entity, count, duplicates_dropped, customers[] {id, name, email, deletedAt}
list_invoices               entity, filters, count, truncated, duplicates_dropped, invoices[] {id, invoiceNumber, status, amount,
                            currencyCode, customerId, destinationAccountId, invoiceDate, dueDate, createdAt,
                            updatedAt, canceledAt, poNumber, payerMemo, internalNote, ccEmails, achDebitEnabled,
                            creditCardEnabled, useRealAccountNumber}
get_invoice                 entity, invoice {list fields + servicePeriodStartDate, servicePeriodEndDate,
                            lineItems[] {name, quantity, unitPrice, salesTaxRate}}
get_invoice_pdf             same two blocks as get_statement_pdf, keyed by invoice_id
list_invoice_attachments    entity, invoice_id, count, attachments[] {id, fileName}
list_users                  entity, count, duplicates_dropped, users[] {userId, firstName, lastName, email, organizationRole}
list_events                 entity, filters, count, truncated, duplicates_dropped, events[] {id, resourceType,
                            resourceId, operationType, resourceVersion, occurredAt, changedPaths, mergePatch,
                            previousValues, patchOmitted?}
list_webhooks               entity, count, duplicates_dropped, webhooks[] {id, url_fingerprint (first 8 hex chars of sha256 of the
                            receiver URL), status, enabled, eventTypes, filterPaths, createdAt, updatedAt}

上方每个嵌套对象都有自己的允许列表;Mercury 明天在任何深度新增的键都会被丢弃,不会直接传递。

列表保持 API 的默认顺序(按未公开的排序键升序排列),但交易、对账单、资金管理交易和事件除外,这些数据会按 Mercury API 的 desc 顺序请求。Mercury 未说明排序键,因此只有带时间窗口的调用才能保证按时间顺序(最新的在前)排列:带时间窗口的资金管理调用按 canonicalDay 排序,带 since 的事件按 occurredAt 排序,然后才应用 limit。不带时间窗口的调用会原样返回 Mercury API 的 desc 顺序。当 truncated 为 true 时,保留的行是适用顺序中的开头部分。

对于 Mercury API 没有服务端筛选器的已记录参数(事件的 since、资金管理交易和发票的 start/end、发票的 status),工具会遍历整个数据流,在此处应用筛选,并在 docs/tools.md 中说明。

reportable_totals

仅统计已完成资金转移(状态为 sent)且金额为支出的记录,并按 UTC 时区的 postedAt 归入日历年(仪表板可能显示的日期)。API 查询使用前后各延长一天的 postedStart / postedEnd;年份以外的记录会在客户端过滤,并计入 excluded_summary.outside_year。系统会遍历该年度的所有分页;若无法完成遍历,则视为错误,绝不会返回部分总额。在线文档未定义交易 kind 的含义,因此此表仅根据 kind 名称所支持的含义作出判断;2026 年 9 月对实际组织的验收发现,负数金额的 externalTransfer 记录是该组织关联的外部账户及跨组织转账,而真正由供应商发起的 ACH 扣款则以 kind other 返回。因此,这两种 kind 会暂不计入,留待人工审核。

决策Kinds备注
纳入outgoingPayment付款详情中的方式:ach、domesticWire、internationalWire、check 或 unknown
纳入exogenousWireDrawdown(负数金额)电汇提款,推定由交易对手发起;未记录在文档中(wireDrawdown)
需审核externalTransfer(负数金额)linked_account_transfers:通常是你自己的关联/外部账户或跨组织转账;也可能是供应商发起的 ACH 扣款
需审核other(负数金额)unlabeled_debits:没有方式标识;通常是供应商发起的 ACH 扣款或 Mercury 产品付款
排除internalTransfer、treasuryTransfer组织自己的账户
排除creditCardTransaction、debitCardTransaction、creditCardCredit、debitCardCredit发卡处理机构会提交 1099-K 表格
排除wireFee、personalBankingSubscriptionFee、billingEngineSubscriptionFee、cardInternationalTransactionFee*银行费用和返款
排除incomingDomesticWire、incomingInternationalWire、checkDeposit、interestPayment收到的款项
排除currencyCloudReturn被退回的国际电汇;原始款项可能已计入,需手动冲减
排除任何可纳入、需审核或未分类的 kind,但状态不是 sent 或金额非负not_settled:<status> / incoming
未分类表中未列出的任何 kind,或缺少金额逐条列出并说明原因

收款方按 counterpartyId 分组(与 GET /recipients 中的收款方匹配时,置信度为 high),否则按交易对手名称分组(置信度为 low)。名称标准化后相同的 ID 分组会相互交叉引用,以便发现付款对象被拆分到两个 ID 的情况。默认门槛会根据年份调整:截至 2025 纳税年度为 600,从 2026 年起为 2000(从 2027 年起按通胀指数调整)。该默认门槛适用于非雇员服务及某些 MISC 付款;请提供适用的类别/年份门槛(参阅 IRS 的 1099-MISC 和 1099-NEC 表格说明)。解析后的数值会在结果中回显。门槛必须是介于 0 和 1,000,000,000 之间的有限数字;否则会报错(绝不会静默设为 0)。实时付款会显示为 ach 或 unknown,具体取决于 API 是否返回其路由详情。

返回:

entity, year, threshold            resolved threshold (default depends on year)
date_basis                         {field: "postedAt", timezone: "UTC",
                                    fallback_to_createdAt_count, api_filter: {postedStart, postedEnd}}
status_basis                       ["sent"]
totals                             reportable_total, reportable_payment_count, recipient_count,
                                   flagged_count, needs_review_total, needs_review_count,
                                   reportable_total_upper_bound (= reportable_total + needs_review_total),
                                   unclassified_count, transactions_scanned,
                                   duplicates_dropped (transaction rows), recipient_duplicates_dropped
recipients[]                       display_name, recipient_id (known recipient) | null, counterparty_id | null,
                                   grouping (counterparty_id | name | transaction), confidence (high | medium | low),
                                   total, payment_count, by_method {label: {count, total}}, flagged,
                                   possible_same_payee [other counterparty ids with the same normalised name],
                                   name_merged_total, flagged_for_review
needs_review                       {linked_account_transfers: [...], unlabeled_debits: [...]}; each entry:
                                   display_name, counterparty_id | null, count, total, by_kind {kind: {count, total}},
                                   would_flag (total >= threshold), sample_transaction_ids (max 3), hint (fixed string),
                                   possible_same_payee [ids], name_merged_total, would_flag_merged
unclassified[]                     id, kind, status, amount, postedAt, counterpartyName, reason
excluded_summary                   {category: {count, amount (signed, as returned by Mercury)}}

fallback_to_createdAt_count 统计缺少 postedAt、因此改用 createdAt 归类的已纳入记录数。这类记录无法通过已入账日期筛选查询到,因此该计数通常为 0。提示内容是固定字符串,根据 kind 和 Mercury 名称前缀选择;交易对手文本本身只是数据,绝不是指令。

list_tax_docs

返回:

entity
document_count, recipient_count, recipients_with_docs
duplicates_dropped                 {attachments, recipients}
documents[]                        id, recipientId, recipientName | null, fileName (verbatim third-party text),
                                   formType (w9 | w8BEN | w8BENE | unknown | null), uploadedAt
recipients_without_docs[]          id, name | null, status | null   (every recipient of any status with no attachment)

绝不会返回下载 URL。

保活

uvx --from 'mercury-multiorg-mcp==0.1.6' mercury-multiorg-mcp-keepalive --entities /private/path/entities.yaml

保活可执行文件的名称与软件包名称不同,因此 uvx 需要 --from;从克隆的仓库运行时,uv run mercury-multiorg-mcp-keepalive 会运行 相同的命令。

每个已配置实体执行一次经过身份验证的 GET /accounts,每个实体输出一行 (<timestamp> OK|FAIL <entity> HTTP <status>);如果任何实体失败,或没有实体配置令牌,则退出码为 1;配置错误时退出码为 2。主机规则与服务相同(非生产、沙盒或环回地址时使用 --allow-custom-api-base)。详情、运行频率以及 cron / launchd 示例见 docs/keepalive.md。

开发

uv sync
uv run pytest

测试仅使用合成 JSON 固定数据和模拟 HTTP 传输。本软件包、其测试或历史记录中均不得包含真实姓名、令牌或账户标识符(唯一的历史例外是公开的银行路由号码,见上文的历史记录说明)。

许可证

MIT;请参阅 LICENSE,该文件也随软件包一同发布。

评论

支持 Markdown

第一次接触 MCP?

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

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