Files
Auto-Finance/src/mcp
wandering 7e900ebdea fix(requisition): 模板三级解析,空白模板入库,产物只写会话 artifacts
历史清洗删掉了根目录两份 低值易耗品申购*.xls——它们其实是**已填写的真实申购单**
(半导体型号、单价、项目名都在),不是模板;同时旧实现「项目根 glob 取名字最大者」会把
上一次生成的产物当模板,所以一并修掉:

- 新增 resolve_requisition_template():REQUISITION_TEMPLATE 环境变量 → templates/ → 项目根(兼容旧位置);
  环境变量指向不存在的文件时告警并继续回退,不静默失败
- 入库 templates/低值易耗品申购.xls 空白件(由旧文件删掉第 3 行起的全部内容得到,UsedRange 只剩 2 行:
  标题 + 表头;真实采购明细不进仓库)
- generate_requisition 默认输出改为 <会话>/artifacts/低值易耗品申购<ts>.xls,不再写模板旁边
- mcp/tools/documents.py 的 _find_template 改为复用同一解析函数,避免两处规则漂移
- 模块 docstring 与 CLI help 里 src/web/uploads 的过时示例改为 cases/
- tests:5 个纯单测覆盖解析优先级(env 优先 / templates 胜过根目录 / 根目录取最新 /
  env 指向不存在的文件时回退 / 全都没有时返回 None),不依赖 COM

验证:真实 Excel COM 端到端 2 项 → 产物 UsedRange 5 行(标题/表头/2 明细/合计),第 6 行起为空,
无旧明细残留;fill_requisition_excel 原本就会先删第 3 行起内容,这条也实测确认过。
门禁:ruff / format --check / mypy src / deptry 全绿,pytest 112 passed,mcp_smoke 17 工具。
2026-10-19 23:57:44 +08:00
..

last_reviewed
last_reviewed
2026-10-19

src/mcp — 工具与协议层

MCP 服务器的全部对外面。17 个工具的参数表在 docs/MCP.md(那份表由运行时 schema 生成,与代码同源)。

文件 职责
server.py MCPServer(name=auto-reimbursement, instructions=INSTRUCTIONS)、TOOLS 注册表、build_server()、main() 走 stdio
tools/materials.py 会话与材料:create / list / status / add_files / inbox / reset
tools/extraction.py 抽取交接:render_pages / read_text / save_extraction / patch_extraction / extraction_spec
tools/analysis.py 匹配与校验:match_payments / info_skeleton / save_info / validate_info / rules_get
tools/documents.py 产物:doc_requisition(经 run_com)
schemas.py 七类票据的字段定义、日期与金额规范化;invoice_type 非法直接拒收
envelope.py ok(**data) / fail(reason, next_action=..., **detail)

写工具的规矩

  • 返回信封,不抛异常穿透协议:文件缺失、参数不合法、COM 失败都转成 ok: false + reason + next_action
  • next_action 写给 Agent 看,尽量是具体工具名,让它照着做
  • 不返回密码、令牌明文等敏感值;上传令牌只从 case_create 的页面地址里给一次
  • 未实现的能力不要出现在 INSTRUCTIONS 里,也不要在工具描述里暗示存在
  • 新增工具后:make mcp-smoke 验 wire 清单;宿主侧要重连(杀掉 stdio 子进程会自动重启并重同步工具)

已知宿主侧坑

  • DSH 会清洗 stdio 子进程的环境变量(抹掉含 KEY/PASSWORD/SECRET/TOKEN 的以及全部 DSH_*), 所以凭据只能来自 scripts/data/config.json
  • DSH 的参数绑定要求 JSON 无损:Windows 路径必须正斜杠,反斜杠会被拒
  • 结果可能被包在 content[0].text(JSON 字符串)里,同时给 structuredContent
  • 服务器 import 与构造必须无副作用:stdio 协商阶段会先起一个临时探针进程