关于 mcp-reportia
mcp-reportia 是向 MCP 客户端提供 Reportia HTTP API 的 MCP 服务。它封装了 66 个精选工具,涵盖会计、映射、运营和 SIIGO,并通过环境变量接收凭据。
主要功能
- 01提供 66 个 Reportia API 工具
- 02涵盖会计和账户映射
- 03支持运营及 SIIGO 工作流
- 04使用 Zod 验证工具输入
- 05使用令牌或会话凭据认证
适用场景
- 01查询 Reportia 会计数据
- 02处理账户映射和佣金
- 03使用上传及队列相关运营功能
- 04使用 Reportia 用户会话连接客户端
MCP 相关
它通过 stdio 和按行分隔的 JSON-RPC,将 Reportia REST 端点转换为 MCP 工具。MCP 客户端将其作为子进程调用,凭据通过环境配置。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @james.valencia/mcp-reportiaREPORTIA_BASE_URLBase URL of the Reportia API (without trailing slash). Example: https://reportia.example.comREPORTIA_TOKEN密钥Bearer token for M2M authentication. Mutually exclusive with REPORTIA_COOKIE; either can be paired with REPORTIA_EMAIL+REPORTIA_PASSWORD (session login) for cookie fallback.REPORTIA_COOKIE密钥Pre-issued Reportia session cookie (e.g. connect.sid=s%3A...). For upstream callers that already hold the resolved user's session and want the child to authenticate as that user without re-login. Mutually exclusive with REPORTIA_TOKEN. Skips /api/auth/login and /api/auth/logout.REPORTIA_EMAILEmail for cookie-session authentication.REPORTIA_PASSWORD密钥Password for cookie-session authentication.REPORTIA_COMPANY_IDDefault companyId used when a tool accepts it as optional.REPORTIA_TIMEOUT_MSHTTP request timeout in milliseconds (default 30000).REPORTIA_DOWNLOAD_DIRDirectory where downloaded Excel/PDF exports are saved (default ./downloads).REPORTIA_USER_AGENTCustom User-Agent header (default mcp-reportia/0.1.0).REPORTIA_MAX_DOWNLOAD_BYTESMaximum bytes for a single binary download (default 104857600 = 100MB).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
mcp-reportia
独立的 MCP(Model Context Protocol)服务,封装了 Reportia 的真实 HTTP API,并通过 stdio 传输以 换行分隔的 JSON-RPC 形式提供服务。专为 MCP 客户端(Claude Desktop、Cursor、Hermes Agent 等)调用而设计,只需运行一次 npx,无需执行自己的服务端代码。
这一层不包含业务逻辑或自有机密:它充当 MCP 协议与 Reportia REST 端点之间的转换器。凭据通过环境变量注入。
目录
索引位置
此 MCP 服务已发布并可在以下平台中发现:
| 平台 | URL | 格式 |
|---|---|---|
| 官方 MCP Registry(modelcontextprotocol.io) | io.github.javalenciacai/mcp-reportia | server.json |
| npm registry | @james.valencia/mcp-reportia | npm 包 |
| skills.sh(Agent Skills Directory) | javalenciacai/mcp-reportia | skills/reportia-mcp-usage/SKILL.md |
通过 skills.sh 安装:
npx skills add javalenciacai/mcp-reportia --skill reportia-mcp-usage
发布流程
当向 main 推送 v* 标签时,此仓库会自动发布到 npm 和 官方 MCP Registry。在 skills.sh 上的索引会自动完成(抓取 GitHub 内容)。
初始配置(仅需一次)
所选方案:npm Trusted Publishing(OIDC)
此配置位于软件包页面(而非 /settings/james.valencia/security——该 URL 用于传统令牌)。
-
在浏览器中登录为
james.valencia,然后打开 **https://www.npmjs.com/package/@james.valencia/mcp-reportia/settings**。 -
在 “Trusted Publisher” 部分,点击 “Add a trusted publisher”(也可能根据你使用的 npmjs.com 版本显示为“GitHub Actions”)。
-
按照以下准确值填写表单(官方文档中的列法如下):
字段 值 Provider GitHub Actions Organization or user javalenciacaiRepository mcp-reportiaWorkflow filename publish.yml(仅填写文件名,不含路径.github/workflows/)Environment name (留空)——工作流不使用 GitHub Environments Allowed actions npm publish(至少填写一项) -
点击 “Add” 或 “Save”。npm 不会在保存时验证配置,但如果数据不完全匹配,工作流将在运行时失败。
将工作流升级到 Node 24(Trusted Publishing 的必要条件)
Trusted Publishing 要求 npm >= 11.5.1,此版本随 Node.js 24 一起提供。当前工作流使用 Node 22(npm 10.9)——即使 publisher 配置正确,也会因 ENEEDAUTH 而失败。
你确认第 1 步后,我会做的事:将工作流升级到 Node 24,创建提交,将 tag v0.1.2 重新指向新提交,然后重新触发发布。
快速验证是否正常
手动重新触发工作流,并查看 publish-npm 任务的日志:
gh workflow run Publish --ref v0.1.2
gh run watch --exit-status
如果最后一个步骤显示 OK: @james.valencia/[email protected] publicado,说明运行正常。如果再次失败,请把 "Publish" 步骤的输出发给我(不要包含 token)。
当前需求状态
| 平台 | 需求 | 状态 |
|---|---|---|
| npm Trusted Publishing | 在 /package/@james.valencia/mcp-reportia/settings 中配置 publisher,设置为 javalenciacai/mcp-reportia + publish.yml | 轮到你了 |
| Workflow Node 24 | 升级到 Node 24(你确认后我来处理) | 待处理 |
| MCP Registry | 无 — 使用 github-oidc,由工作流自动签名 | 已就绪 |
| skills.sh | 无 — 自动抓取 | 已就绪 |
| GitHub Release | 工作流中已配置 contents: write 权限 | 已就绪 |
完成你的第 1 步后的计划
我会按以下顺序执行(无需你提供信息):
- 将发布工作流两个任务中的
node-version: '22'→'24' - 在本地运行
npm test && npm run build进行验证 - 提交并推送
- 重新创建 tag v0.1.2,使其指向新提交
- 持续观察
Publish工作流,直到publish-npm成功 - 向你报告最终结果(npm 上的版本 + 已创建的 GitHub Release)
创建 release
# 1. Bump de version (esto actualiza package.json y server.json automaticamente)
cd /c/james/mcp-reportia
npm version patch # 0.1.1 -> 0.1.2 (o minor/major)
# 2. Push del commit + tag a GitHub
git push origin main --follow-tags
# (npm version ya crea el tag v0.1.2 y lo pushea junto con el commit)
GitHub Actions 会自动触发:
- 任务
validate— typecheck + test + build + smoke。验证package.json.version和server.json.version与 tag 一致。 - 任务
publish-npm— 通过 OIDC 发布到 npm(无需长期有效的 token)。 - 任务
publish-mcp-registry— 将server.json发布到官方 MCP Registry。 - 任务
release— 创建 GitHub Release,并自动生成说明。
手动发布(不使用 tag)
如果需要在正常流程之外发布,请前往 GitHub → Actions → "Publish" → "Run workflow",并可选择传入 version override。
回滚
如果需要撤回已发布到 npm 的版本(须在 72 小时内):
npm unpublish @james.valencia/[email protected]
超过 72 小时后便无法撤回;你必须发布一个 patch。MCP Registry 不支持回滚;需要发布一个更高版本并包含修复。
安装和快速使用
发布后,通常通过 npx 使用:
# 1) Construir dist/ localmente (la primera vez, o al actualizar):
npm run build
# 2) Ejecutar el binario MCP directamente:
npx mcp-reportia
MCP 客户端(Claude Desktop、Cursor、Hermes 等)会为你将其作为子进程调用。除非要调试,否则无需手动运行。
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
REPORTIA_BASE_URL | 是 | Reportia API 的根 URL,不带末尾斜杠(例如 https://reportia.example.com)。 |
REPORTIA_TOKEN | 有条件* | Bearer 令牌。可替代会话登录。 |
REPORTIA_COOKIE | 有条件* | 预先签发的 Reportia 会话 Cookie(例如 connect.sid=s%3A...)。适用于已解析用户会话、并希望子进程以该用户身份进行身份验证而无需重新登录的调用方。 |
REPORTIA_EMAIL | 有条件* | 用于会话登录(Cookie)的电子邮件地址。 |
REPORTIA_PASSWORD | 有条件* | 用于会话登录(Cookie)的密码。 |
REPORTIA_COMPANY_ID | 否 | 工具支持时使用的默认 companyId。接受正整数。 |
REPORTIA_TIMEOUT_MS | 否(默认 30000) | 每个 HTTP 请求的超时时间,单位为 ms。 |
REPORTIA_DOWNLOAD_DIR | 否(默认 ./downloads) | 保存下载文件(二进制文件,如导出的 Excel/PDF)的文件夹。 |
REPORTIA_USER_AGENT | 否(默认 mcp-reportia/0.1.0) | 每个请求的 User-Agent 请求头。 |
* 三种身份验证方式中必须且只能设置一种:
REPORTIA_TOKENBearer 令牌,或REPORTIA_EMAIL+REPORTIA_PASSWORD会话 Cookie(package 会执行POST /api/auth/login并获取 Cookie),或REPORTIA_COOKIE预先签发的会话 Cookie(package 直接使用它,无需重新登录)。
如果同时传入 REPORTIA_TOKEN 和 REPORTIA_COOKIE,loadConfig 会抛出 ConfigError,并显示消息 REPORTIA_TOKEN y REPORTIA_COOKIE son mutuamente excluyentes — usa solo uno.,以避免令牌意外覆盖每个用户的会话。
仅设置一种方式时的优先级:cookie > bearer > session。cookie 优先,因为它与上游解析出的身份匹配;bearer 是服务账号;session 是电子邮件地址 + 密码登录(子进程会自行登录)。
如果未设置任何方式,loadConfig 会在服务器启动时抛出 ConfigError。
⚠️ 不要将
C:\james\Reportia\.env中的凭据复制到此仓库。此项目不得包含机密信息。请在调用它的 MCP 客户端环境中配置这些凭据。
查看 .env.example 了解所有变量。
MCP 客户端配置
Claude Desktop(%APPDATA%\Claude\claude_desktop_config.json)
在 mcpServers 中添加一个条目:
{
"mcpServers": {
"reportia": {
"command": "npx",
"args": ["-y", "mcp-reportia"],
"env": {
"REPORTIA_BASE_URL": "https://reportia.example.com",
"REPORTIA_TOKEN": "<tu-token>",
"REPORTIA_COMPANY_ID": "123"
}
}
}
}
开发期间,将
mcp-reportia替换为本地路径C:\\james\\mcp-reportia,并使用args: ["-y", "--prefix", "C:\\james\\mcp-reportia", "mcp-reportia"],或直接运行npm run start作为命令。
Cursor(%USERPROFILE%\.cursor\mcp.json)
{
"mcpServers": {
"reportia": {
"command": "npx",
"args": ["-y", "mcp-reportia"],
"env": {
"REPORTIA_BASE_URL": "https://reportia.example.com",
"REPORTIA_TOKEN": "<tu-token>"
}
}
}
}
Hermes Agent(通过 ~/.hermes/config.toml 或 UI 配置 MCP 插件)
添加一个名为 reportia 的 stdio MCP 服务,指向 npx mcp-reportia,并在 env 中导出变量。
典型格式:
[[mcp_servers]]
name = "reportia"
command = "npx"
args = ["-y", "mcp-reportia"]
[mcp_servers.env]
REPORTIA_BASE_URL = "https://reportia.example.com"
REPORTIA_TOKEN = "<tu-token>"
REPORTIA_COMPANY_ID = "123"
字段的确切名称因 Hermes 版本而异。请参阅
hermes mcp --help。
已持有用户会话的调用方(每用户配置,推荐用于 AI 服务)
当调用方(例如,多租户 AI 服务)已解析当前活跃用户的 Reportia 会话,并希望子进程以同一用户身份进行身份验证时——无需重新登录,也无需使用服务账号——请传入预先签发的 cookie:
{
"mcpServers": {
"reportia": {
"command": "npx",
"args": ["-y", "mcp-reportia"],
"env": {
"REPORTIA_BASE_URL": "https://reportia.example.com",
"REPORTIA_COOKIE": "connect.sid=s%3A<session-id-from-resolved-user>",
"REPORTIA_COMPANY_ID": "123"
}
}
}
}
子进程不会调用
/api/auth/login(跳过该步骤),关闭时也不会调用/api/auth/logout(会话属于调用方,而非子进程),并且所有 Reportia 请求都会使用已解析用户的身份。如果调用方运行在一个会在运行时捕获用户 cookie 的中继之后(例如,Cowork 服务基于会话派生的路径),这种身份验证模式与该流程相匹配。
可用工具
该服务提供 66 个以 reportia_ 为前缀的工具。所有工具均返回 JSON(由 JSON.stringify 美化格式化的字符串),并使用 Zod 验证输入。工具按功能域分组:
| 域 | 模块 | 数量 |
|---|---|---|
| 健康检查与身份验证 | src/tools/auth-health.ts | 3 |
| 公司 | src/tools/companies.ts | 5 |
| 会计分录 | src/tools/accounting-movements.ts | 4 |
| 科目映射 | src/tools/account-mappings.ts | 5 |
| 佣金报告 | src/tools/commission-reports.ts | 2 |
| 第三方 | src/tools/third-parties.ts | 4 |
| 销售人员 × 发票 | src/tools/salesperson-invoice.ts | 11 |
| 行 × 成本中心 | src/tools/line-cost-center.ts | 22 |
| 操作(上传、队列、SIIGO) | src/tools/operations.ts | 10 |
| 总计 | 66 |
健康检查与身份验证(src/tools/auth-health.ts)
| 工具 | 描述 |
|---|---|
reportia_health | MCP 客户端诊断 + 对 GET /api/health 执行 ping。 |
reportia_whoami | 已验证身份的用户资料(GET /api/auth/me)。 |
reportia_logout | 退出 Reportia 会话(POST /api/auth/logout)。 |
公司(src/tools/companies.ts)
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_companies_list | 列表 | 列出可访问的公司(GET /api/companies)。 |
reportia_company_get | 详情 | 获取公司详情(GET /api/companies/:id)。 |
reportia_company_settings_get | 配置 | 获取公司设置(GET /api/companies/:id/settings)。 |
reportia_company_settings_update | 修改 | 更新设置(PATCH /api/companies/:id/settings)。 |
reportia_company_activate ⚠️ | 破坏性 | 激活公司(POST /api/companies/:id/activate)。需要 confirm:true。 |
会计分录(src/tools/accounting-movements.ts)
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_movements_list | 列表 | 根据筛选条件列出分录,并支持分页。 |
reportia_movements_export_excel | 二进制下载 | 将分录导出为 Excel,并返回本地路径。 |
reportia_movements_export_pdf | 二进制下载 | 将分录导出为 PDF,并返回本地路径。 |
reportia_movements_delete_all ⚠️ | 破坏性操作 | 删除公司的所有分录。需要 confirm:true。 |
科目映射(src/tools/account-mappings.ts)
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_account_mappings_list | 列表 | 列出会计科目映射(GET /api/companies/:companyId/account-mappings)。 |
reportia_account_mapping_create | 修改 | 创建映射(POST /api/account-mappings)。 |
reportia_account_mapping_update | 修改 | 更新映射(PATCH /api/account-mappings/:mappingId)。 |
reportia_account_mapping_delete ⚠️ | 破坏性操作 | 删除映射(DELETE /api/account-mappings/:mappingId)。需要 confirm:true。 |
reportia_account_codes_search | 搜索 | 搜索会计科目代码以供自动补全(GET /api/companies/:companyId/account-codes/search)。 |
佣金报告(src/tools/commission-reports.ts)
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_commission_list | 列表 | 列出佣金计算结果(GET /api/commission-reports)。 |
reportia_commission_export_excel | 二进制下载 | 将佣金报告导出为 Excel。 |
第三方(src/tools/third-parties.ts)
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_third_parties_list | 列表 | 列出第三方(客户/供应商)。 |
reportia_third_parties_search | 搜索 | 高级搜索第三方。 |
reportia_third_parties_get_by_nit | 详情 | 根据 NIT 获取第三方。 |
reportia_third_parties_portfolio_balance | 汇总 | 按第三方汇总应收款余额。 |
销售人员 × 发票(src/tools/salesperson-invoice.ts)
销售人员 → 发票映射、销售人员选项、发票列表、发票设置,以及发票发送(单封和批量邮件)。
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_salesperson_mappings_list | 列表 | 列出一家公司的销售人员 × 发票映射。 |
reportia_salesperson_mapping_create | 修改 | 创建销售人员 × 发票映射。 |
reportia_salesperson_mapping_update | 修改 | 更新销售人员 × 发票映射。 |
reportia_salesperson_mapping_delete ⚠️ | 破坏性操作 | 删除销售人员 × 发票映射。需要 confirm:true。 |
reportia_salesperson_options_list | 列表 | 列出供选择/自动补全的销售人员选项。 |
reportia_invoices_list | 列表 | 根据筛选条件列出发票。 |
reportia_invoice_settings_get | 配置 | 读取一家公司的发票配置。 |
reportia_invoice_settings_create | 修改 | 创建发票配置。 |
reportia_invoice_settings_update | 修改 | 更新发票配置。 |
reportia_invoice_email_send | 通知 | 通过电子邮件发送一张发票(由 Reportia 服务触发发送)。 |
reportia_invoices_send_multiple | 通知 | 在一次调用中通过电子邮件发送多张发票。 |
线路 × 成本中心(src/tools/line-cost-center.ts)
功能最全面的领域:管理线路-分组映射、成本中心映射、可用成本中心,以及成本中心报表的完整生命周期(CRUD + 执行 + 复制 + 导出)。
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_line_group_mappings_list | 列表 | 列出线路-分组映射。 |
reportia_line_group_mapping_create | 变更 | 创建线路-分组映射。 |
reportia_line_group_mapping_update | 变更 | 更新线路-分组映射。 |
reportia_line_group_mapping_delete ⚠️ | 破坏性操作 | 删除线路-分组映射。需要 confirm:true。 |
reportia_line_group_suggestions_lines_groups | 建议 | 提供线路-分组建议,用于自动补全。 |
reportia_line_group_suggestions_by_type | 建议 | 提供按类型筛选的线路-分组建议。 |
reportia_line_group_description | 详情 | 提供线路-分组映射的易读描述。 |
reportia_cost_center_mappings_list | 列表 | 列出成本中心映射。 |
reportia_cost_center_mapping_create | 变更 | 创建成本中心映射。 |
reportia_cost_center_mapping_update | 变更 | 更新成本中心映射。 |
reportia_cost_center_mapping_delete ⚠️ | 破坏性操作 | 删除成本中心映射。需要 confirm:true。 |
reportia_cost_center_mappings_suggestions | 建议 | 提供成本中心映射建议。 |
reportia_cost_centers_available | 列表 | 列出某家公司的可用成本中心。 |
reportia_cost_center_reports_list | 列表 | 列出成本中心报表。 |
reportia_cost_center_report_get | 详情 | 获取成本中心报表的详情。 |
reportia_cost_center_report_create | 变更 | 创建成本中心报表。 |
reportia_cost_center_report_update | 变更 | 更新成本中心报表。 |
reportia_cost_center_report_delete ⚠️ | 破坏性操作 | 删除成本中心报表。需要 confirm:true。 |
reportia_cost_center_report_execute | 执行 | 执行成本中心报表。 |
reportia_cost_center_report_duplicate | 变更 | 复制成本中心报表(别名:副本)。 |
reportia_cost_center_report_export_excel | 二进制下载 | 将报表结果导出为 Excel。 |
reportia_cost_center_report_export_pdf | 二进制下载 | 将报表结果导出为 PDF。 |
操作(src/tools/operations.ts)— 上传、队列和 SIIGO
此模块中的所有工具均为只读:上传历史记录/状态、队列系统和 worker 的健康状况,以及用于查询 SIIGO 的工具(设置、客户、运行记录、追踪信息、计划、历史记录)。此版本中没有变更工具、multipart/form-data 上传工具或队列控制工具。
| 工具 | 类型 | 描述 |
|---|---|---|
reportia_uploads_history_list | 列表 | 某公司的上传历史记录(GET /api/companies/:companyId/upload-history)。 |
reportia_upload_status_get | 详情 | 特定上传的状态(GET /api/upload/:uploadId/status)。 |
reportia_health_queue_system | 诊断 | 队列系统的健康状况(GET /api/health/queue-system)。 |
reportia_health_workers | 诊断 | worker 的健康状况和队列延迟(GET /api/queue/workers/health)。 |
reportia_siigo_settings_get | 配置 | 某公司的 SIIGO Pyme 设置(GET /api/companies/:companyId/siigo-settings)。 |
reportia_siigo_clients_list | 列表 | 某公司可用的 SIIGO 远程客户(GET /api/companies/:companyId/siigo/clients)。 |
reportia_siigo_sync_runs_list | 列表 | SIIGO 同步运行记录(GET /api/companies/:companyId/siigo/sync/runs)。 |
reportia_siigo_run_trace_get | 详情 | SIIGO 运行记录的追踪信息(GET /api/companies/:companyId/siigo/sync/runs/:runId/trace)。 |
reportia_siigo_schedules_list | 列表 | SIIGO 同步计划(GET /api/companies/:companyId/siigo/schedules)。 |
reportia_siigo_history_get | 历史记录 | SIIGO 命令历史记录(GET /api/companies/:companyId/siigo/history)。 |
⚠️ 标记为破坏性的工具需要在输入中提供参数
{ "confirm": true }。如果未提供,处理程序会调用assertConfirmed(input, '<tool-name>')(定义于src/tool-base.ts)进行验证,并在任何 HTTP 调用发生之前返回带有code: "GUARD_REJECTED"的错误。LLM 必须在调用此类工具之前向用户明确请求确认。
如果已设置 REPORTIA_COMPANY_ID,可以省略 companyId;否则,所有涉及公司数据的工具都必须提供该参数。
已知限制
- **不支持 HTTP 流式传输 / SSE:**此服务仅通过
stdio通信。仅支持 HTTP 的客户端无法直接使用它。 - **每个进程只能有一个
ReportiaClient:**登录采用惰性初始化且为全局状态;不支持同时使用多个账户。 - 文件上传(
multipart/form-data):HTTP 客户端已做好准备(使用undici中的FormData),但当前工具未公开上传端点(没有使用multipart/form-data的 POST/PUT)。目前公开了两个用于查询现有上传历史和状态的只读工具:reportia_uploads_history_list(GET/api/companies/:companyId/upload-history)和reportia_upload_status_get(GET/api/upload/:uploadId/status)。如果 Reportia 将来添加上传端点,只需添加一个使用ctx.client.call(..., { formData })的 ToolDefinition 即可。 - **不提供持久缓存:**每次调用都会重新请求 API。LLM 可根据需要自由调用
tools/list。 - **HTTP 错误:**会转换为结构化类型(
AUTH_ERROR、NOT_FOUND、VALIDATION_ERROR、ROW_LIMIT_EXCEEDED、NETWORK_ERROR、TIMEOUT)。客户端绝不会在消息中暴露机密信息。 - 离线冒烟测试:
npm run test:smoke会通过REPORTIA_BASE_URL=http://127.0.0.1:9(端口已关闭)启动服务。它不会进行实际调用,只验证 MCP 握手。要进行真实的集成测试,请使用npm run test:integration并指向可访问的 Reportia 服务。 - **不自动重试:**遇到 5xx 错误时,服务会报告错误;LLM 可手动重试。
安全性
该服务旨在由 LLM 调用时最大限度地缩小攻击面:
- 没有通用 HTTP 工具:工具按领域精心筛选(66 个特定端点)。LLM 无法将客户端指向任意 URL 或内部 IP。
- 每个输入都经过 Zod 验证:任何处理程序在通过拒绝无效类型、范围和格式的模式验证之前,都不会访问网络。
- 破坏性工具要求
confirm: true字面值:这些工具声明为destructive: true,并会在任何 HTTP 调用之前通过assertConfirmed(...)进行验证。如果缺少confirm,则返回GUARD_REJECTED,不会触碰 API。LLM 必须先请求用户明确确认,才能调用这些工具。 - URL 中进行安全插值:数字 ID(companyId、mappingId、reportId、runId、uploadId)在插值前会通过
z.number().int().positive()验证。路径字符串(NIT、invoiceId、行/中心的 mappingId)会使用encodeURIComponent,和/或限制为安全字符集(NIT 使用[A-Za-z0-9-]+)。 - 清理 HTTP 标头:通过
REPORTIA_USER_AGENT配置的User-Agent会在src/client.ts:sanitizeUserAgent中进行 CRLF 清理(防止标头注入)。 - 日志中不包含机密信息:错误消息会显示端点和 HTTP 状态码,但绝不会包含令牌、Cookie、密码或完整响应正文。Cookie
connect.sid保存在客户端内存中,绝不会出现在 JSON 响应里。 - 使用持久 Cookie 登录:会话模式会重复使用从
/api/auth/login收到的connect.sidCookie,只有在 Reportia 更新该 Cookie 时才会轮换;绝不会写入磁盘。 - 安全回归测试(
tests/security.test.ts):16 项测试,用于验证所有破坏性工具都会检查confirm、所有模式都拒绝危险输入,以及 guard 的执行顺序(resolveCompanyId → assertConfirmed)会在配置问题导致错误时优先返回信息明确的错误,而不是GUARD_REJECTED。
已覆盖和省略的路由
已覆盖(tools/)
| Endpoint | Tool |
|---|---|
GET /api/health | reportia_health |
GET /api/auth/me | reportia_whoami |
POST /api/auth/logout | reportia_logout |
GET /api/companies | reportia_companies_list |
GET /api/companies/:id | reportia_company_get |
GET /api/companies/:id/settings | reportia_company_settings_get |
PATCH /api/companies/:id/settings | reportia_company_settings_update |
POST /api/companies/:id/activate | reportia_company_activate |
GET /api/accounting-movements(带筛选条件) | reportia_movements_list |
GET /api/accounting-movements/export/excel | reportia_movements_export_excel |
GET /api/accounting-movements/export/pdf | reportia_movements_export_pdf |
DELETE /api/accounting-movements | reportia_movements_delete_all |
GET/POST/PATCH/DELETE /api/account-mappings/... | reportia_account_mapping_* |
GET /api/account-codes/search | reportia_account_codes_search |
GET /api/commission-reports | reportia_commission_list |
GET /api/commission-reports/export/excel | reportia_commission_export_excel |
GET /api/third-parties | reportia_third_parties_list |
GET /api/third-parties/search | reportia_third_parties_search |
GET /api/third-parties/by-nit/:nit | reportia_third_parties_get_by_nit |
GET /api/third-parties/portfolio-balance | reportia_third_parties_portfolio_balance |
未包含(超出此版本范围)
- 通过工具进行会话登录(不需要:已由
ReportiaClient延迟执行)。 - 任何上传端点(
multipart/form-data)——范围仅限于GET /api/companies/:companyId/upload-history和GET /api/upload/:uploadId/status(只读)。 - 需要未公开文档中所述 scopes 的内部管理端点。
- 旧版本(
/api/v0/*)。
⚠️ 此表反映了
src/tools/*.ts的当前范围。添加新路由前,请编辑src/tools/<modulo>.ts,在src/tools/index.ts中重新导出,并运行npm run typecheck && npm test。
本地开发
要求:
- Node.js ≥ 20
- npm ≥ 9
# 1) Instalar dependencias
npm install
# 2) Compilar TypeScript a dist/
npm run build
# 3) Verificar tipos sin emitir
npm run typecheck
# 4) Ejecutar el servidor (lee dist/server.js, stdio)
npm run start
测试不需要启动 Reportia 或提供凭据;它们使用合成环境。
测试
# Suite unitaria (Vitest) — sin red, sin credenciales
npm test
# Smoke de protocolo MCP sobre stdio (sin credenciales reales)
npm run test:smoke
# Smoke de integracion contra un servidor Reportia REAL
# (configura REPORTIA_BASE_URL y REPORTIA_TOKEN en tu entorno antes).
npm run build
REPORTIA_BASE_URL=https://reportia.example.com \
REPORTIA_TOKEN=<tu-token> \
npm run test:integration
冒烟测试(scripts/jsonrpc-smoke.mjs)会将 dist/server.js 作为子进程启动,通过以换行符分隔的 JSON-RPC 向其发送 initialize + tools/list,并验证响应中至少包含一个工具。它不会向 Reportia 发起 HTTP 调用(目标地址为 127.0.0.1:9)。
集成测试(scripts/integration-smoke.mjs)会与真实的 Reportia 服务通信:执行 initialize、tools/list,调用 reportia_health(会向 /api/health 发送 ping),并调用 reportia_whoami(提供无效 token 时应返回 AUTH_ERROR,以验证错误处理)。这有助于确认已部署版本仍与真实后端兼容。
如果只想验证构建未损坏:
npm test -- --passWithNoTests
使用 MCP Inspector 进行检查
npm run inspect
这会运行 npx @modelcontextprotocol/inspector node dist/server.js,打开一个 Web UI,用于手动发送协议方法(initialize、tools/list、tools/call 等)。
内部架构
src/
├── server.ts # Arranca McpServer + StdioServerTransport y registra tools.
├── config.ts # Carga y valida env vars (Zod). Tres auth modes: bearer / session / cookie.
├── client.ts # Cliente HTTP sobre undici. Bearer, sesión cookie propia, o cookie pre-emitida.
├── errors.ts # Jerarquía ReportiaError.
├── tool-base.ts # Helpers: ToolDefinition, ok/fail, resolveCompanyId, assertConfirmed.
└── tools/
├── index.ts # allTools = union de los modulos.
├── auth-health.ts # reportia_health / whoami / logout.
├── companies.ts # reportia_companies_*.
├── accounting-movements.ts # reportia_movements_*.
├── account-mappings.ts # reportia_account_mapping_* y account_codes_search.
├── commission-reports.ts # reportia_commission_*.
└── third-parties.ts # reportia_third_parties_*.
scripts/
└── jsonrpc-smoke.mjs # Smoke de protocolo (sin red contra Reportia).
tests/
├── config.test.ts # loadConfig.
├── resolve-company-id.test.ts # helpers de tool-base.
└── schema-validation.test.ts # invariantes de allTools y Zod.
约定:
- 每个工具必须使用 Zod 架构(
z.object({...}))验证其输入。 - 处理程序必须在
try/catch中封装ctx.client.call(...),并使用tool-base.ts中的ok(...)/fail(...)。 - 执行破坏性变更的工具必须声明
destructive: true,并在其处理程序中使用assertConfirmed(...)或等效方法验证confirm: true。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。