cjt2mcp

cjt2mcp

Converts Chanjet T+ OpenAPI into MCP endpoints, enabling AI clients to query inventory, archives, and sales/purchase orders from T+ systems.

Category
访问服务器

README

cjt2mcp — 畅捷通 OpenAPI → MCP 转换服务

把畅捷通 T+ 开放平台接口转换成 MCP(streamable-http), 让 WorkBuddy 等 AI 客户端能直接查询 T+ 的库存、档案、单据数据。

技术栈:FastAPI + Jinja2 + HTMX + SQLite,单 Docker 容器部署,适合轻量多客户单机场景。


架构模型:多自建应用托管

每个租户(客户)对应畅捷通开放平台上一个独立的自建应用,拥有自己的一套凭据 (appKey / appSecret / 消息秘钥 / certificate)。平台管理员在后台添加租户时录入这些凭据 (敏感字段 AES-GCM 加密入库),再在租户下配置 MCP Key 交付给 AI 客户端。

两类端点均为每租户独立

端点 谁调用 如何区分租户
消息接收 POST /webhook/chanjet/{client_code} 畅捷通平台推送 URL 中的 client_code → 取该租户消息秘钥解密
MCP 端点 POST /chanjet/{client_code}/mcp WorkBuddy 等 AI 客户端 URL client_code + Authorization: Bearer <MCP Key>

消息 webhook 必须带 client_code:外层信封只有密文 encryptMsg,解密需要该租户的消息秘钥, 而租户身份恰在密文里——鸡生蛋,故身份由 URL 携带。每个租户在自己自建应用的「消息订阅」 菜单里把消息接收地址配成 .../webhook/chanjet/{自己的 code}

鉴权模型(消息驱动,非 OAuth 重定向)

  • 平台每 10 分钟向 webhook 推送 appTicket(30 分钟有效,滚动更新)。
  • certificate 由管理员在畅捷通控制台手动授权后获得,录入后台。
  • 换 token:appKey + appSecret + appTicket + certificategenerateToken, 返回 accessToken(约 6 天有效)。无独立刷新接口,过期直接重新换取。

首版工具(只读查询,按 MCP Key 的 scope 裁剪)

scope 工具 畅捷通 T+ 接口
stock:read query_current_stock 现存量 /tplus/api/v2/currentStock/Query
archive:read query_inventory 存货 /tplus/api/v2/inventory/Query
archive:read query_customer 客户 /tplus/api/v2/partner/Query(PartnerType=客户)
archive:read query_warehouse 仓库 /tplus/api/v2/warehouse/Query
sales:read query_sales_order 销售订单 /tplus/api/v2/saleOrder/Query
purchase:read query_purchase_order 采购订单 /tplus/api/v2/purchaseOrder/Query

快速开始

1. 准备环境变量

cp .env.example .env

编辑 .env,填入平台级机密(租户畅捷通凭据不在此,走后台录入):

# AES-GCM 主密钥(加密租户凭据),生成:
python -c "import os,base64; print(base64.b64encode(os.urandom(32)).decode())"

# Session 签名密钥,生成:
python -c "import secrets; print(secrets.token_hex(32))"

必填:MASTER_KEYADMIN_PASSWORDSESSION_SECRETPUBLIC_BASE_URL 填对外访问域名(用于生成 webhook / MCP 地址)。

2. Docker 部署(推荐)

docker compose up -d --build

访问后台 http://<host>:8000/admin,用 .env 里的管理员账号登录。

3. 本地开发

pip install -r requirements.txt
export $(grep -v '^#' .env | xargs)   # 或用 direnv
uvicorn app.main:app --reload
pytest                                # 46 项测试

交付一个客户的流程

  1. 后台「添加客户」,录入该租户自建应用的 appKey/appSecret/消息秘钥/certificate。
  2. 详情页复制消息接收地址,填入该租户自建应用的「消息订阅」菜单。
  3. 等待平台推送 appTicket(10 分钟内)。
  4. 生成 MCP Key,勾选所需权限(库存/档案/销售/采购)。
  5. 「测试连接」验证链路(身份→凭据→appTicket→token→业务接口)。
  6. 一键复制 WorkBuddy MCP 配置,交付客户。

可信域名(畅捷通拨测)

畅捷通平台会不定期拨测 http://<可信域名>/CHANJET_CHECK.txt 校验域名所有权。本服务按请求 Host 头区分租户,返回各自的验证文件内容,因此多个租户可各用独立子域名、互不干扰。

每个租户的配置步骤:

  1. 后台配置:详情页「可信域名」卡片,填域名(如 sdfx.hacka.cn,可带端口),上传从畅捷通控制台下载的 CHANJET_CHECK.txt(或直接粘贴内容)。上传新文件即覆盖,只改域名不会清空已存内容。
  2. Nginx 反代:把该域名反代到本服务,必须透传 Host 头(服务靠它分流):
    server {
        server_name sdfx.hacka.cn;
        location / {
            proxy_pass http://127.0.0.1:8002;
            proxy_set_header Host $host;   # 必须:按域名定位租户
        }
    }
    
  3. 畅捷通控制台:在「可信域名」里填入 sdfx.hacka.cn,平台拨测 http://sdfx.hacka.cn/CHANJET_CHECK.txt 命中该租户内容即验证通过。

要点:

  • 文件名固定为 CHANJET_CHECK.txt(畅捷通硬性要求,不可改名)。
  • 每个一级域名只能被一个 ISV 认领,务必一租户一子域名
  • 每个 ISV 最多 5 个可信域名,不够需联系畅捷通客服扩容。

安全设计

  • 租户畅捷通凭据(appSecret / 消息秘钥 / certificate / token):AES-GCM 加密入库,页面永不回显。
  • MCP Key:只存 SHA-256 哈希 + 前缀,完整 Key 仅创建时返回一次;日志不记录 Key。
  • 平台级机密(主密钥 / 管理员密码 / Session 密钥):走环境变量,不入库不入库。
  • 调用日志:仅记录租户/工具/状态/错误码/耗时,不记录 Key、Token、查询条件、业务数据。
  • MCP 端点强制 Bearer 校验,且 Key 必须匹配 URL 租户,防跨租户访问。

⚠️ 公开部署时务必置于 HTTPS 反向代理之后,并设置强管理员密码。


镜像

GitHub Actions 在 push 到 main 或打 tag 时自动构建并发布镜像到 GitHub Container Registry:

docker pull ghcr.io/hkxiaoyao/cjt2mcp:latest

目录结构

app/
├── main.py            # FastAPI 入口,挂载三组路由
├── config.py          # 平台级机密(env)
├── db.py              # SQLite 建表 + 迁移
├── crypto.py          # AES/ECB 消息解密 + AES-GCM 字段加密
├── security.py        # MCP Key 哈希、管理员登录、Session
├── store.py           # 数据访问层
├── chanjet/           # 畅捷通对接:client / token_mgr / webhook / conntest
├── mcpsrv/            # MCP 协议:server(JSON-RPC)/ tools(工具+权限)
└── admin/             # 后台管理(Jinja2 + HTMX)

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选