informer-mcp
informer-mcp
一个用于 Informer 记账 API(v2)的 Model Context Protocol 服务器。它让任何 MCP 客户端都能直接访问你的往来单位、销售和采购发票、报价单、订单、收据、产品和财务报告。
每个工具都源自 Informer 自己的 OpenAPI 文档(api.informer.eu/docs/v2)。服务器附带一份文档副本,以便离线工作,并且它还能自我更新——参见与 API 变更保持同步。
非官方项目。与 Informer 无关联,也未获得其认可或支持。
快速开始
把下面这段内容粘贴到任何可以安装 MCP 服务器的 AI 助手中:
Install the following MCP server: https://github.com/vladxyz/informer-mcp and run the local setup screen for the API keys.它会克隆仓库、构建项目、向你的客户端注册服务器,然后运行 informer-mcp setup——这会在你的浏览器中打开一个位于 127.0.0.1 的页面。你的 API 凭据就在这个页面上填写;聊天中不会询问任何内容,也绝不会有任何密钥被粘贴进对话。
你会在那个页面上看到什么
每个账套一张卡片;如果你负责多个账套,外加添加账套:
┌─ Administration ────────────────────────────── Remove ─┐
│ ALIAS COMPANY NAME │
│ [ acme ] [ ACME BV ] │
│ Short handle you use Optional, shown in │
│ in prompts. tool descriptions. │
│ │
│ API KEY SECURITY CODE │
│ [ ••••••••••••••••• ] [ ••••••••••••••• ] │
│ │
│ ACCESS │
│ [ Read and write ▾ ] │
│ Read only hides every tool that changes this │
│ client's books. │
└────────────────────────────────────────────────────────┘
[ Add administration ] [ Verify & save ] ☐ Save without verifying字段 | 填写内容 |
别名 | 你将在提示词中使用的短名称——“列出 acme 的未结发票”。字母、数字、 |
公司名称 | 可选标签,显示给模型,让它知道 |
API 密钥 | 在该账套内的 app.informer.eu/settings/api 中创建。 |
安全代码 | 在该账套的设置中显示于 app.informer.eu/settings/account。 |
访问权限 | 读写,或只读,以隐藏所有可能更改此客户端账簿的工具。 |
这两组凭据都属于同一个账套,因此记账员为每个客户添加一张卡片。参见多个客户端账套。
点击“验证并保存”后会发生什么
每一组密钥/安全代码都会被拿去与 API 验证,页面会显示它实际属于哪家公司——因此即使密钥被粘贴到了错误的行,任何内容被存储之前也会一目了然。
如果某组凭据被拒绝,则不会写入任何内容,并会明确指出失败的那一行。勾选不验证即保存可无论如何都将其存储,例如当你处于离线状态时。
成功后,凭据会以
0600权限写入~/.informer-mcp.json。如果页面是通过open_setup打开的,正在运行的服务器会立即感知到这一变更——下一条消息中就可以选择新的账套了。如果是从终端打开的,请重启你的客户端。
询问*“你可以访问哪些账套?”*来确认——这会调用 list_administrations,并列出一个个别名及其对应的公司。
Related MCP server: billingo-mcp
你能获得什么
68 个工具,覆盖全部 49 个有文档记录的端点——支持读取和写入。
浏览器中设置。 让助手打开设置页面,或运行
informer-mcp setup。它会用 API 验证每个密钥、写入配置文件,而且变化无需重启任何东西即可生效。紧跟 API。 当 Informer 发布新端点时,服务器会在你的客户端保持连接的同时自动获取并添加相应工具——无需重装,无需重启。
一个服务器承载多个客户端账套。 记账员可以通过一个连接访问每个客户的账簿,只需一个
administration参数;只要配置了多个账套,该参数就是必填的。一次提问覆盖整个客户组合。 只读工具接受别名列表或
"all",并并发查询它们,返回按客户端分类的结果。完整的请求架构。 创建/更新工具会公开其负载的完整 JSON Schema,因此模型在发送任何内容之前就知道哪些字段存在、哪些是必填的。
只读还是读写,由你选择。
--read-only标志会隐藏所有会更改内容的工具,同时个别客户端可以被固定为只读,而其余保持可写。允许/拒绝列表可以进一步缩小暴露面。PDF 和附件会从 base64 解码,并可直接写入磁盘。
稳健的 HTTP。 超时、支持
Retry-After的重试,以及 Informer 的荷兰语验证错误原样呈现(HTTP 422: invoice_date: ongeldig)。
环境要求
Node.js 20 或更新版本
一个具有 API 访问权限的 InformerOnline 账户
设置你的凭据
只需在对话中说出你的需求:
“我想更改我的 Informer 账套” “为 Informer 添加一个新客户” “我的 Informer API 密钥已更改”
你的助手会调用 open_setup 工具,页面随即打开。不需要寻找配置文件,也不需要手动编辑任何内容——而且由于页面是一个浏览器表单,你的 API 密钥永远不必被输入到聊天中。
从终端打开同一个页面:
npm run setup # or: informer-mcp setup无论哪种方式,你的浏览器中都会出现 http://127.0.0.1:<port>,并带有每个账套的表单:别名、公司名称、API 密钥、安全代码,以及是否允许写入。保存时会用 API 验证每一组凭据——因此输错的密钥会立即被识别出来,你还会看到每个密钥实际属于哪家公司——然后以 0600 权限写入 ~/.informer-mcp.json。
在完全没有凭据的情况下启动服务器,会自动打开同一个页面,因为那正是你需要它的时刻。设置 INFORMER_AUTO_SETUP=false 可关闭此行为;在无头机器上设置 INFORMER_OPEN_BROWSER=false 则只打印 URL。无论以何种方式打开,始终只有一个页面:再次请求时会返回同一个 URL。
有几件事是页面刻意设计的:
它只绑定到
127.0.0.1,并且每次运行都会生成一个随机令牌,该令牌必须出现在 URL 和保存请求中,因此你浏览器中的其他网站无法向它提交数据;它绝不会把已存储的密钥发回页面——已有账套会以凭据为空的形式显示,除非你输入新值,否则它们会被保留;
它拒绝保存 API 拒绝的凭据,除非你勾选不验证即保存。
没有任何东西阻止你手动编写文件或设置环境变量;页面只是提供便利,并非必需。
密钥从哪里来
API 使用两个请求头进行身份验证,两者都是必需的:
环境变量 | 在哪里找到 |
| |
|
两者都限定于一个账套:API 密钥属于创建它的那个账套(GET /administration 返回“与此 API 密钥关联的账套”),而安全代码则用于标识该公司。不存在任何端点可以列出账套或在账套之间切换。
一个密钥即可完全访问该账套的账簿。请像对待密码一样对待它:将其保存在你的环境变量、密钥管理器中,或存放在仓库之外的配置文件里。
多个客户端账套
拥有多个客户的记账员需要为每个客户账套准备一组密钥/安全代码——有权访问某账套的会计用户可以从其设置中创建这些凭据。在设置页面中添加它们,或自行编写 ~/.informer-mcp.json(或由 INFORMER_CONFIG_FILE 指定的任何文件):
{
"administrations": {
"acme": { "label": "ACME BV", "api_key": "...", "security_code": "..." },
"bakkerij": { "label": "Bakkerij de Bol", "api_key": "...", "security_code": "...", "mode": "read-only" }
}
}当配置了多个账套时,每个工具都要求提供 administration 参数,该参数以你的别名枚举形式呈现:
list_sales_invoices({ "administration": "acme", "filter": "open" })这里有意不设置默认值。将发票记入错误客户的分类账是绝不能悄悄发生的错误,因此缺少该参数的调用会在发出任何 HTTP 请求之前就被架构验证拒绝——未配置过的别名也同样会被拒绝。
list_administrations 会显示已配置的别名;传入 verify: true 可从 API 获取每个公司名称,这既能确认凭据有效,也能确认每个别名指向的公司确实如你所想。
同时查询多个客户端
只读工具还接受别名列表或 "all":
list_sales_invoices({ "administration": "all", "filter": "open", "records": 50 })
list_sales_invoices({ "administration": ["acme", "bakkerij"], "filter": "open" })这些账套会被并发查询(INFORMER_FANOUT_CONCURRENCY,默认每次四个),返回的结果以别名为键:
{
"administrations": ["acme", "bakkerij"],
"results": {
"acme": { "pagination": { "total": 3 }, "invoices": [ ... ] },
"bakkerij": { "error": "[bakkerij] HTTP 401: Authentication failed" }
}
}有三个值得了解的属性:
一个客户端失败不会拖垮整个查询。 它的条目会带有
error,其余条目仍会返回数据。响应预算会被平均分配。 每个账套获得
INFORMER_MAX_RESPONSE_CHARS / n个字符,因此一个庞大的客户端无法挤掉其他客户端;超出其份额的内容会以{ "truncated": true, "partial": ... }的形式返回。扇出(fan-out)是只读的。 写入类工具以及 PDF/附件下载只接受单个别名——它们的架构甚至不提供数组或
"all",处理器也会再次拒绝它们。在十二个账套中创建同一张发票,绝不是值得支持的意外场景。
单个账套仍然像以前一样,直接返回未包装的 API 负载。
对于单个账套——这是最常见的情况——一切照旧:像往常一样设置 INFORMER_API_KEY 和 INFORMER_SECURITY_CODE,该参数保持可选。
安装
git clone https://github.com/vladxyz/informer-mcp.git
cd informer-mcp
npm install # also builds dist/ via the prepare script
npm run setup # opens a local page to enter your API credentials设置页面运行在 127.0.0.1 上,用 API 验证每个密钥,并写入 ~/.informer-mcp.json。参见设置你的凭据。
Claude Desktop:作为扩展安装
最友好的方式:构建一个扩展包并打开它。
npm run bundle # writes informer-mcp.mcpb在 Claude Desktop 中依次进入设置 → 扩展 → 高级设置 → 安装扩展…,然后选择 .mcpb 文件。它自带所有依赖,因此除了 Node.js 20 之外,无需先安装任何东西。
安装对话框会提供 API 密钥、安全代码和一个只读开关。你可以让这三项全部留空:服务器会在首次启动时打开其设置页面,这也是配置多个账套的唯一途径。
Claude Desktop 的设置 → 连接器 → 添加自定义连接器是另一回事:它接收的是远程 MCP 服务器的 URL。本服务器通过 stdio 在本地运行,因此它应作为扩展而非连接器安装。
Claude Desktop:手动安装
直接编辑配置文件:
macOS |
|
Windows |
|
{
"mcpServers": {
"informer": {
"command": "node",
"args": ["C:\\path\\to\\informer-mcp\\dist\\index.js"]
}
}
}之后重启 Claude Desktop。在 Windows 上,JSON 中的反斜杠必须写成两个;正斜杠也可以,而且更易读。
任何其他 MCP 客户端
服务器通过 stdio 使用 MCP 协议进行通信,因此每个客户端都以相同的方式配置它——一条命令及其参数。上面那段配置在 Claude Code(claude mcp add)、Cursor、Zed 或任何其他支持 MCP 的工具中都可以原样使用。
凭据来自 ~/.informer-mcp.json,因此不必在客户端配置中重复。如果改为按客户端传递,可以添加一个包含 INFORMER_API_KEY 和 INFORMER_SECURITY_CODE 的 env 块,或将 INFORMER_CONFIG_FILE 指向其他位置。
把 "--read-only" 加到 args 中,即可注册一个不能更改任何内容的服务器 — 参见
只读或读写。在同一个客户端下,以两个名称注册同一个服务器(一个只读、一个读写)也完全可以。
stdout 承载协议,所以所有日志都进入 stderr — 启动时运行一行横幅信息,告诉你注册多少工具以及它找到了哪些账套。
只读或读写
默认情况下,每个工具都可用。要彻底移除写入工具,启动服务器时加一个标志:
informer-mcp --read-only # only the tools that read
informer-mcp --read-write # the default: create, update and delete tooINFORMER_READ_ONLY=true 起着同样的作用,但该标志优先于环境变量 — 因此你可以在一个客户端中注册同一个服务器两次:一次只读,用于日常提问;一次读写,用于实际操作预订的会话。
在只读模式下,写入工具根本不会被注册:它们永远不会出现在工具列表中,所以模型没有任何可调用的写入工具。
按客户端
在配置文件中,可以分别固定各个账套。当你可能只需要查看某些客户的账套时,这种形式尤其有用:
{
"administrations": {
"acme": { "api_key": "...", "security_code": "..." },
"bakkerij": { "api_key": "...", "security_code": "...", "mode": "read-only" }
}
}"read_only": true 可用作简写。最严格的设置会生效:
服务端 | 客户端 | 结果 |
| 未设置 | 读写 |
|
| 只读 |
| 未设置 | 只读 |
|
| 只读 — 该标志会把一切限制为只读 |
因此,标记为只读的客户端绝不会被意外写入;而以 --read-only 启动的会话也会永远保持只读,无论配置文件如何设置。
当某些账套可写、另一些不可写时,写入工具仍会注册,但其 administration 枚举只会提供可写的账套。在只读客户端上创建发票的请求会在任何 HTTP 请求发出之前就被拒绝:
`list_administrations` 会报告每个客户端的实际模式,启动时的横幅信息会总结为:`read-write: acme, garage`。
## 配置
| 变量 | 默认值 | 说明 |
| ----------------------------------- | ------------------------------------ | --------------------------------------------------------------- |
| `INFORMER_API_KEY` | — | 单个账套的 API 密钥。 |
| `INFORMER_SECURITY_CODE` | — | 该账套的安全代码。 |
| `INFORMER_CONFIG_FILE` | `~/.informer-mcp.json` | JSON 文件,列出多个账套。如果不存在,由 `setup` 创建。 |
| `INFORMER_ADMINISTRATIONS` | — | 同一份 JSON,作为环境变量内联提供。按账套覆盖配置文件。 |
| `INFORMER_ADMINISTRATION_ALIAS` | `default` | 单个 `INFORMER_API_KEY` 组合的别名。 |
| `INFORMER_ADMINISTRATION_LABEL` | — | 该别名的可读名称。 |
| `INFORMER_ADMINISTRATION_MODE` | — | 该别名的 `read-only` 或 `read-write` 模式。 |
| `INFORMER_BASE_URL` | `https://api.informer.eu/v2` | 覆盖 API 根地址。 |
| `INFORMER_READ_ONLY` | `false` | `true` 时仅暴露读取工具,对所有账套生效。与 `--read-only` 相同。 |
| `INFORMER_TOOLS` | *(全部)* | 标签和/或工具名称的允许列表,以逗号分隔。 |
| `INFORMER_EXCLUDE_TOOLS` | *(无)* | 拒绝列表,在允许列表之后应用。 |
| `INFORMER_TIMEOUT_MS` | `30000` | 每个请求的超时时间。 |
| `INFORMER_MAX_RETRIES` | `2` | 对 408/429/5xx 和网络错误的重试次数。 |
| `INFORMER_MAX_RESPONSE_CHARS` | `100000` | 较长的工具结果会被截断并附上提示。在 fan-out 查询中平均分配。 |
| `INFORMER_FANOUT_CONCURRENCY` | `4` | fan-out 查询同时访问多少个账套。 |
| `INFORMER_AUTO_SETUP` | `true` | `false` 时,不会在未配置凭据时打开设置页面。 |
| `INFORMER_OPEN_BROWSER` | `true` | `false` 时,打印设置 URL 而不是启动浏览器。 |
| `INFORMER_SPEC_MAX_AGE_HOURS` | `24` | 缓存 API 描述在后台刷新前存放最旧多久。`0` 表示禁用。 |
| `INFORMER_SPEC_CACHE` | `~/.informer-mcp.spec.json` | 下载的 API 描述缓存所在位置。 |
| `INFORMER_SPEC_URL` | Informer 发布的文档 | 覆盖待下载的 API 描述。 |
过滤器可以接受 OpenAPI 标签或工具名称,并且匹配时不区分大小写,忽略标点:
```GXP14
## 使用
连接后,可以用自然语言提问:
* *"2026 年还有哪些销售发票未付?"* → 使用 `filter` 调用 `list_sales_invoices`
* *"为 ACME 创建一个 10 小时咨询、每小时 €125 的草稿发票。"* → 先用 `get_sales_invoice_options` 获取有效的科目/增值税/模板 ID,再调用 `create_sales_invoice`
* *"把发票 12345 以 PDF 下载到我的桌面。"* → 使用 `save_path` 调用 `get_sales_invoice_pdf`
* *"显示 2026 年第 6 期的资产负债表。"* → 调用 `get_balance_report`
### 值得了解的约定
* **明确选择账套。** 当配置了多个账套时,每个工具都接受 `administration: "<alias>"`。`list_administrations` 会把别名映射到公司,读取工具也接受列表或 `"all"`。
* **日期**始终是 `YYYY-MM-DD`。
* **列表工具是分页的**,通过 `page`(默认 1)和 `records`(默认 20)进行,并返回带 `total` 和 `pages` 的 `pagination` 对象。
* **请求负载放在单个 `body` 参数中。** 路径参数和查询参数仍留在顶层,因此 `update_relation` 接受 `{ "id": 42, "body": { ... } }`。
* **创建单据时先调用 `*_options` 工具。** `get_sales_invoice_options`、`get_quotation_options` 等会返回你的账套当前有效的科目、VAT、模板、币种和付款条件 ID。
* **报表需要显式区间。** `get_balance_report` 需要 `year_from`、`year_to` 和 `period`;`get_column_balance_report` 还需要一个总账科目范围。
### PDF 与附件
Informer 会在 JSON 中以 base64 返回文件。实现此功能的工具(`get_*_pdf`、`download_sales_invoice_attachment`)接受可选的 `save_path`:
* **带 `save_path`** — 文件会被解码并写入该路径,工具返回 `{ saved_to, filename, bytes, mime_type }`;
* **不带 `save_path`** — 文件会以正确的 MIME 类型作为内联 MCP 资源返回;对大型文档来说,这可能会在上下文中开销很大。
上传方式相反:`upload_sales_invoice_attachment` 接受 `{ filename, file }`,其中 `file` 是 base64 编码的内容(最大 10 MB;支持 PDF、PNG、JPEG、GIF、DOC(X)、XLS(X))。
## 工具参考
`npm run tools` 会根据当前 spec 打印此列表;`npm run tools -- --md` 会重新生成下面的表格。
除了各端点工具之外,服务器还提供三个工具:
| 工具 | 说明 |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| `list_administrations` | 已配置哪些客户端账套、它们对应的公司,以及哪些可以写入。 |
| `open_setup` | 打开用于添加、更改或删除账套及其凭据的本地页面。 |
| `refresh_api_spec` | 重新读取 Informer 的 API 描述并更新工具。 |
<details>
<summary><strong>按 API 区域分组的全部 68 个端点工具</strong></summary>
### 账套
| 工具 | 端点 | 说明 |
| ---------------------- | ------------------------ | ---------------------- |
| `get_administration` | `GET /administration` | 获取账套详情 |
### 往来单位
| 工具 | 端点 | 说明 |
| ------------------- | ----------------------- | ------------------------ |
| `get_relation` | `GET /relations/{id}` | 获取单个往来单位 |
| `update_relation` | `PUT /relations/{id}` | 更新往来单位 |
| `list_relations` | `GET /relations` | 获取往来单位列表 |
| `create_relation` | `POST /relations` | 创建新的往来单位 |
### 联系人
| 工具 | 端点 | 说明 |
| ----------------- | ------------------- | -------------------- |
| `get_contact` | `GET /contact/{id}` | 获取一个联系人 |
| `update_contact` | `PUT /contact/{id}` | 更新联系人 |
| `create_contact` | `POST /contact` | 创建新的联系人 |
### 销售发票
| 工具 | 端点 | 说明 |
| ------------------------------------------- | ------------------------------------------------------- | -------------------------------------- |
| `get_sales_invoice` | `GET /invoices/sales/{id}` | 获取一张销售发票 |
| `update_sales_invoice` | `PUT /invoices/sales/{id}` | 更新销售发票 |
| `list_sales_invoices` | `GET /invoices/sales` | 获取销售发票列表 |
| `create_sales_invoice` | `POST /invoices/sales` | 创建新的销售发票 |
| `get_sales_invoice_options` | `GET /invoices/sales/options` | 获取销售发票选项 |
| `get_sales_invoice_pdf` | `GET /invoices/sales/pdf/{id}` | 获取销售发票 PDF |
| `send_sales_invoice` | `POST /invoices/sales/send/{id}` | 发送销售发票 |
| `upload_sales_invoice_attachment` | `POST /invoices/sales/{id}/attachments` | 上传发票专用附件 |
| `download_sales_invoice_attachment` | `GET /invoices/sales/{id}/attachments/{attachment_id}` | 下载发票附件 |
| `delete_sales_invoice_attachment` | `DELETE /invoices/sales/{id}/attachments/{attachment_id}` | 删除发票专用附件 |
### 采购发票工具 | 端点 | 描述 |
|
| 获取单个采购发票 |
|
| 获取采购发票列表 |
|
| 创建新的采购发票 |
|
| 获取采购发票选项 |
|
| 获取采购发票 PDF |
定期发票
工具 | 端点 | 描述 |
|
| 获取单个定期发票 |
|
| 更新定期发票 |
|
| 获取定期发票列表 |
|
| 创建新的定期发票 |
|
| 获取定期发票选项 |
销售订单
工具 | 端点 | 描述 |
|
| 获取单个销售订单 |
|
| 更新销售订单 |
|
| 获取销售订单列表 |
|
| 创建新的销售订单 |
|
| 获取销售订单选项 |
|
| 获取销售订单 PDF |
|
| 发送销售订单 |
报价
工具 | 端点 | 描述 |
|
| 获取单个报价 |
|
| 更新报价 |
|
| 获取报价列表 |
|
| 创建新的报价 |
|
| 获取报价选项 |
|
| 获取报价 PDF |
|
| 发送报价 |
销售簿
工具 | 端点 | 描述 |
|
| 获取单个销售簿发票 |
|
| 更新销售簿发票 |
|
| 获取销售簿发票列表 |
|
| 创建新的销售簿发票 |
|
| 获取销售簿选项 |
|
| 获取销售簿 PDF |
付款条件
工具 | 端点 | 描述 |
|
| 获取所有付款条件 |
模板
工具 | 端点 | 描述 |
|
| 获取所有模板 |
增值税
工具 | 端点 | 描述 |
|
| 获取所有增值税选项 |
分类账
工具 | 端点 | 描述 |
|
| 获取所有分类账账户 |
成本
工具 | 端点 | 描述 |
|
| 获取所有成本中心账户 |
货币
工具 | 端点 | 描述 |
|
| 获取所有货币 |
日记账
工具 | 端点 | 描述 |
|
| 获取所有日记账 |
订阅类型
工具 | 端点 | 描述 |
|
| 获取所有订阅类型 |
附件
工具 | 端点 | 描述 |
|
| 获取所有附件 |
产品
工具 | 端点 | 描述 |
|
| 获取所有产品 |
收据
工具 | 端点 | 描述 |
|
| 获取单个收据 |
|
| 更新收据 |
|
| 获取收据列表 |
|
| 创建新的收据 |
备忘录
工具 | 端点 | 描述 |
|
| 获取单个备忘录条目 |
|
| 更新备忘录条目 |
|
| 获取备忘录条目列表 |
|
| 创建新的备忘录条目 |
报表
工具 | 端点 | 描述 |
|
| 获取资产负债表 |
|
| 获取列余额 |
工具命名
名称源自 HTTP 方法和路径,而非描述文字,因此在规范更新时保持稳定:
模式 | 示例 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
命名表无法识别的端点会回退到 <verb>_<path slug>,因此规范刷新永远不会产生损坏的工具。
跟上 API 变更
这些工具是根据 Informer 的 OpenAPI 文档生成的,因此当 Informer 添加端点时,唯一缺少的就是该文档的新副本。服务器可以自行获取。
三层结构,按优先级排序:
下载的副本,缓存在
~/.informer-mcp.spec.json。捆绑的副本,位于
openapi/api-docs.json,随服务器一起提供,始终可离线使用。两者都不会被盲目信任——下载的文件必须能解析为包含至少一个可用操作的 OpenAPI 3 文档,否则将被拒绝,当前工具保持不变。强制门户或维护页面无法清除你的工具集。
按计划
每天一次,在启动后不久,服务器会在后台检查是否有更新的文档。启动永远不会被阻塞,失败的检查会被记录并忽略。INFORMER_SPEC_MAX_AGE_HOURS=0 可将其关闭。
按需
当你要求时,refresh_api_spec 工具会执行相同的操作——当你期望的端点缺失,或某个参数被拒绝为未知时,这很有用:
"刷新 Informer API 描述并告诉我发生了什么变化。"
{
"adopted": true,
"api_version": "2.0.0",
"endpoints": 49,
"tools": 68,
"changes": {
"added": [{ "tool": "list_projects", "endpoint": "GET /projects" }],
"removed": [],
"changed": [{ "tool": "create_sales_invoice", "endpoint": "POST /invoices/sales",
"notes": ["body now requires: project_id"] }],
"unchanged": 66
},
"note": "The tool list has been updated; no restart is needed."
}传递 dry_run 即可在不应用任何更改的情况下查看该报告。
差异报告刻意保持具体:它会指出出现和消失的工具,对于发生变化的工具,它会说明什么发生了变化——新增的参数、已删除的参数、现在必填的字段。这是单纯的路径比较所遗漏的部分,通常也是否则会以令人困惑的 422 错误出现的那部分。
采用文档会更新正在运行的服务器:新工具被注册,撤回的工具被移除,变更的工具被重新通告,并发出 tools/list_changed 通知,以便你的客户端在会话中途重新加载列表。
仓库中的副本
npm run update-spec 会更新捆绑的文档,并报告哪些路径新增和移除。当你希望为所有安装服务器的人提交更改时,应运行此命令;refresh_api_spec 仅影响你自己的机器。
资源
服务器还将 OpenAPI 文档本身作为 MCP 资源暴露在 informer://openapi.json,当你希望模型无需猜测即可检查字段定义时,这很方便。
开发
npm install # install + build
npm run setup # enter credentials in the browser
npm run bundle # package as informer-mcp.mcpb for one-click install
npm run dev # run from source with tsx
npm test # vitest
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
npm run tools # print the tool surface
npm run update-spec # re-download openapi/api-docs.json and report added/removed paths项目结构
openapi/api-docs.json vendored OpenAPI 3.0 document — the source of truth
src/openapi.ts spec → operations: tool names, JSON Schema conversion
src/client.ts HTTP client: auth headers, retries, error formatting
src/tools.ts operations → MCP tools, filtering, result formatting
src/server.ts server assembly (tools + openapi resource)
src/spec.ts download, validate, cache and diff the OpenAPI document
src/setup.ts local setup server: verify credentials, write the config file
src/setup-page.ts the HTML it serves
src/index.ts stdio entry point and CLI
manifest.json extension manifest: entry point and install-time settings
scripts/update-spec.mjs refresh the vendored spec
scripts/list-tools.ts print/regenerate the tool reference
scripts/bundle.mjs stage production dependencies and pack the .mcpb添加端点通常根本不需要更改代码——运行中的服务器会自动获取它们,npm run update-spec 会将相同的更改提交到捆绑副本。只有真正新的 URL 形式才需要在 src/openapi.ts 的 RESOURCES 表中添加规则;即使没有规则,它们仍会成为工具,只是名称更平淡。
模式如何转换
OpenAPI 3.0 并不完全是 JSON Schema。在转换为 MCP 工具定义的过程中:
#/components/schemas/X引用变为#/$defs/X,仅内联每个操作实际需要的传递闭包——因此工具定义保持精简;nullable: true变为["type", "null"]联合类型;路径和查询参数变为顶级属性,请求体放在
body下,additionalProperties: false可防止拼写错误到达 API。
在进行任何 HTTP 调用之前,参数都会根据该模式进行验证。
安全说明
此服务器能够创建、更新和删除真实的记账记录。如果只需要报表,可以用
--read-only启动;用"mode": "read-only"将个别客户端固定为只读,并让你的 MCP 客户端在写入工具上征求你的批准。在同一个进程中容纳多个客户端的凭据意味着一次误路由的调用就会触及他人的账簿。为此需要
administration参数、已知别名的枚举、扇出时的只读限制,以及每条错误消息上的别名前缀([acme] HTTP 422: ...)。请将配置文件放在版本控制之外,并只允许你自己读取。这些工具都带有
readOnlyHint、destructiveHint和idempotentHint注解,因此使用这些提示的客户端可以对危险的工具进行拦截。不会向 stdout 记录任何内容,凭据也绝不会在工具输出中显示或发送回设置页面。
open_setup返回的是 URL,绝不是密钥——助手无法读取你的凭据,也没有任何理由在聊天中向你索要它们。API 描述是在不带凭据的情况下下载的;凡是无法解析为可用 OpenAPI 3 文件的文档都会被拒绝,而不会被采用。
许可证
MIT — 参见 LICENSE。
This server cannot be installed
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
- AlicenseBqualityCmaintenanceMCP server to interact with the Cuéntica accounting API, allowing users to manage invoices, expenses, income, clients, providers, and bank accounts via natural language.592MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for the Billingo V3 Hungarian invoicing API. Manage invoices, partners, products, spendings, and bank accounts from any MCP client.10MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that wraps the cebelca.biz accounting API, exposing tools for operations like managing partners, invoices, proformas, and fetching PDFs.2
- AlicenseBqualityAmaintenanceRead-only MCP server for self-hosted Manager.io bookkeeping, providing curated GET tools to access accounting data like invoices, balances, and reports.101MIT
Related MCP Connectors
Hosted MCP server for Mini Accountant: invoices, expenses, customers, analytics, tax estimates.
MCP server for the PDFGate API. Generate PDFs, manage documents and handle e-signatures.
A basic MCP server to operate on the Postman API.
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/vladxyz/informer-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server