mcpField
M
mcp-reportia

mcp-reportia

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

关于 mcp-reportia

mcp-reportia 是向 MCP 客户端提供 Reportia HTTP API 的 MCP 服务。它封装了 66 个精选工具,涵盖会计、映射、运营和 SIIGO,并通过环境变量接收凭据。

主要功能

  1. 01提供 66 个 Reportia API 工具
  2. 02涵盖会计和账户映射
  3. 03支持运营及 SIIGO 工作流
  4. 04使用 Zod 验证工具输入
  5. 05使用令牌或会话凭据认证

适用场景

  1. 01查询 Reportia 会计数据
  2. 02处理账户映射和佣金
  3. 03使用上传及队列相关运营功能
  4. 04使用 Reportia 用户会话连接客户端

MCP 相关

它通过 stdio 和按行分隔的 JSON-RPC,将 Reportia REST 端点转换为 MCP 工具。MCP 客户端将其作为子进程调用,凭据通过环境配置。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"javalenciacai-mcp-reportia": {
"command": "npx",
"args": [
"-y",
"@james.valencia/mcp-reportia"
],
"env": {
"REPORTIA_BASE_URL": "<REPORTIA_BASE_URL>",
"REPORTIA_TOKEN": "<REPORTIA_TOKEN>",
"REPORTIA_COOKIE": "<REPORTIA_COOKIE>",
"REPORTIA_EMAIL": "<REPORTIA_EMAIL>",
"REPORTIA_PASSWORD": "<REPORTIA_PASSWORD>",
"REPORTIA_COMPANY_ID": "<REPORTIA_COMPANY_ID>",
"REPORTIA_TIMEOUT_MS": "<REPORTIA_TIMEOUT_MS>",
"REPORTIA_DOWNLOAD_DIR": "<REPORTIA_DOWNLOAD_DIR>",
"REPORTIA_USER_AGENT": "<REPORTIA_USER_AGENT>",
"REPORTIA_MAX_DOWNLOAD_BYTES": "<REPORTIA_MAX_DOWNLOAD_BYTES>"
}
}
}
}
启动命令npx -y @james.valencia/mcp-reportia
需要配置的环境变量
REPORTIA_BASE_URLBase URL of the Reportia API (without trailing slash). Example: https://reportia.example.com
REPORTIA_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+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@james.valencia/mcp-reportia0.3.2

工具

还没有获取到工具列表

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

详细介绍

mcp-reportia

MCP Registry skills.sh npm License: MIT

独立的 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-reportiaserver.json
npm registry@james.valencia/mcp-reportianpm 包
skills.sh(Agent Skills Directory)javalenciacai/mcp-reportiaskills/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 用于传统令牌)。

  1. 在浏览器中登录为 james.valencia,然后打开 **https://www.npmjs.com/package/@james.valencia/mcp-reportia/settings**。

  2. 在 “Trusted Publisher” 部分,点击 “Add a trusted publisher”(也可能根据你使用的 npmjs.com 版本显示为“GitHub Actions”)。

  3. 按照以下准确值填写表单(官方文档中的列法如下):

    字段值
    ProviderGitHub Actions
    Organization or userjavalenciacai
    Repositorymcp-reportia
    Workflow filenamepublish.yml(仅填写文件名,不含路径 .github/workflows/)
    Environment name(留空)——工作流不使用 GitHub Environments
    Allowed actionsnpm publish(至少填写一项)
  4. 点击 “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 步后的计划

我会按以下顺序执行(无需你提供信息):

  1. 将发布工作流两个任务中的 node-version: '22' → '24'
  2. 在本地运行 npm test && npm run build 进行验证
  3. 提交并推送
  4. 重新创建 tag v0.1.2,使其指向新提交
  5. 持续观察 Publish 工作流,直到 publish-npm 成功
  6. 向你报告最终结果(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 会自动触发:

  1. 任务 validate — typecheck + test + build + smoke。验证 package.json.version 和 server.json.version 与 tag 一致。
  2. 任务 publish-npm — 通过 OIDC 发布到 npm(无需长期有效的 token)。
  3. 任务 publish-mcp-registry — 将 server.json 发布到官方 MCP Registry。
  4. 任务 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_TOKEN Bearer 令牌,或
  • 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.ts3
公司src/tools/companies.ts5
会计分录src/tools/accounting-movements.ts4
科目映射src/tools/account-mappings.ts5
佣金报告src/tools/commission-reports.ts2
第三方src/tools/third-parties.ts4
销售人员 × 发票src/tools/salesperson-invoice.ts11
行 × 成本中心src/tools/line-cost-center.ts22
操作(上传、队列、SIIGO)src/tools/operations.ts10
总计66
健康检查与身份验证(src/tools/auth-health.ts)
工具描述
reportia_healthMCP 客户端诊断 + 对 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.sid Cookie,只有在 Reportia 更新该 Cookie 时才会轮换;绝不会写入磁盘。
  • 安全回归测试(tests/security.test.ts):16 项测试,用于验证所有破坏性工具都会检查 confirm、所有模式都拒绝危险输入,以及 guard 的执行顺序(resolveCompanyId → assertConfirmed)会在配置问题导致错误时优先返回信息明确的错误,而不是 GUARD_REJECTED。

已覆盖和省略的路由

已覆盖(tools/)
EndpointTool
GET /api/healthreportia_health
GET /api/auth/mereportia_whoami
POST /api/auth/logoutreportia_logout
GET /api/companiesreportia_companies_list
GET /api/companies/:idreportia_company_get
GET /api/companies/:id/settingsreportia_company_settings_get
PATCH /api/companies/:id/settingsreportia_company_settings_update
POST /api/companies/:id/activatereportia_company_activate
GET /api/accounting-movements(带筛选条件)reportia_movements_list
GET /api/accounting-movements/export/excelreportia_movements_export_excel
GET /api/accounting-movements/export/pdfreportia_movements_export_pdf
DELETE /api/accounting-movementsreportia_movements_delete_all
GET/POST/PATCH/DELETE /api/account-mappings/...reportia_account_mapping_*
GET /api/account-codes/searchreportia_account_codes_search
GET /api/commission-reportsreportia_commission_list
GET /api/commission-reports/export/excelreportia_commission_export_excel
GET /api/third-partiesreportia_third_parties_list
GET /api/third-parties/searchreportia_third_parties_search
GET /api/third-parties/by-nit/:nitreportia_third_parties_get_by_nit
GET /api/third-parties/portfolio-balancereportia_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。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

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

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