sanxiao-mcp
sanxiao-mcp —— 金蝶云・星辰「三效プロジェクト管理」MCP Server
GC032 財務エージェント・三效端。アプリ識別子 bdi_projectmanagement、
購読アドレス https://cloud.kingdee.com/kae/#/market/detail?sid=1285。
『三效プロジェクト管理 API_2025』公式ドキュメント + 『金蝶三效プロジェクト管理API開発フレームワーク』に基づいて実装。 一期は読み取り専用:クエリ系は全開放、書き込み系はコードは配置済みだがデフォルトでガードにより拒否される。
三效 API の形状(これを先に理解すれば、他はすべてうまくいく)
三效は「1ビジネス1エンドポイント」ではなく、汎用伝票(Bill)CRUD:
すべての伝票 —— プロジェクトマスタ、借入、経費精算、支払、工数入力、購買申請 —— は同じ一連のインターフェースを経由し、
formId + フィールド識別子で駆動される。
POST https://bj1-api.kingdee.com/bdiprojectapi/common/{action}
后端 openapi/ierp/kapi/app/bdi_projectmanagement/{action}
action ∈ { listQuery, getById, saveOrUpdate, submit, unSubmit,
audit, unAudit, delete, push, operation }したがって、本サービスの構造も「1つの出口 + 2層のカプセル化」であり、数十のエンドポイント定数ではない。
Related MCP server: mcp-timely
目次
sanxiao/
├── config.py 环境与鉴权四要素;url() / headers() 在这里定形
├── forms.py formId 登记表 + 中文别名解析(项目档案 → bdi_projectfile)
├── query.py qParams 结构化查询 DSL:构造、校验、还原成类 SQL 可读串
├── models.py saveOrUpdate 字段模型(8 种 fType + 分录 + 下推 + 附件)
├── guards.py 白名单 + 默认拒绝 + 审计
├── client.py 唯一 HTTP 出口 _post(),读写方法都从这里过
└── server.py 28 个 MCP 工具(通用层 + 语义层)
test_connection.py L1 配置 → L2 网络 → L3 鉴权 → L4 只读 → L5 守卫
tests/ pytest:query / models / guards / client認証:4つのリクエストヘッダ、署名なし
kingdee-star-mcp(jdy オープンゲートウェイ)とは異なる —— 三效は HMAC 署名を必要とせず、
4つのヘッダを携帯するだけでよい。すべて雲星辰標準 API で事前に取得する:
ヘッダ | 取得元 |
| 製品帳票レベルのトークン。星辰標準 API 認証で取得 |
| IDC ドメイン = 【リアルタイム受信認可】プッシュメッセージ内の |
| 認可情報。オープンプラットフォームがサンドボックスメッセージ受信アドレスにプッシュ |
| 同上 |
落とし穴のヒント:公式ドキュメントには「雲プラットフォーム API マーケットでデバッグする際は
X-GW-Router-Addrを無視してよい」と明記されている。そのため多くの人がマーケットで疎通確認できても、コードにすると 404 になる —— コード呼び出しでは必ずこのヘッダを付ける必要があるからだ。config.headers()で処理済みなので、削除しないこと。
4要素を取得したら .env に記入する(テンプレートは .env.example 参照)。
クイックスタート
pip install -r requirements.txt
cp .env.example .env # 填入四要素
pytest -q # 69 项单测应全绿
python test_connection.py # 分层联调,结果写入 connection_test_result.txtWindows は run_test.bat をダブルクリックするだけ。
MCP ツール(28個)
メタ情報
ツール | 用途 |
| ゲートウェイアドレス、読み取り専用スイッチ、4要素の準備状態と欠落項目 |
| 登録済みの formId、中国語名、デフォルトフィールド |
| 利用可能な action、読み取り専用 operation ホワイトリスト、現在許可されている書き込みアクション |
汎用層 —— 公式インターフェースを完全マッピング
ツール | 公式インターフェース |
|
|
|
|
|
|
| ローカルツール:簡略化条件を |
セマンティック層 —— formId を覚える必要はない
sx_list_projects / sx_list_reimbursements / sx_list_loans /
sx_list_payments / sx_list_working_hours / sx_get_bill
sx_query_cost_budget / sx_query_material_budget / sx_query_working_hour_budget
sx_get_user_permission / sx_get_form_config / sx_workflow_status / sx_get_app_parameter
書き込み層 —— デフォルトで拒否
sx_build_bill_payload(組み立てるだけで送信しない。一期でも人手によるメッセージ確認に使える)
sx_save_or_update / sx_submit / sx_un_submit / sx_audit / sx_un_audit
/ sx_delete / sx_push
クエリ条件の書き方
公式 qParams は条件配列:最上位の各項目間は and、条件グループ内は joinKey で接続される。
[
{ "childGroup": false, "qKey": "number", "qCp": "like", "qValue": "ew" },
{ "childGroup": true, "joinKey": "or", "childCondition": [
{ "childGroup": false, "qKey": "number", "qCp": "=", "qValue": "new5" },
{ "childGroup": false, "qKey": "number", "qCp": "=", "qValue": "New" }
]}
]
// 等价于 number like '%ew%' and (number='new5' or number='New')比較演算子:= > >= < <= != like likeLeft。in はない —— query.any_of()
または sx_build_query の or グループで代替する。明細フィールドは「明細識別子.フィールド識別子」と書く。
例:projectfileteam.teamstaff。
セキュリティモデル
ガードはホワイトリスト + デフォルト拒否の3層:
action 分類 ——
listQuery/getById/operationは読み取り、残りの7つは書き込み。operationKey ホワイトリスト ——
operationは表面的には読み取りインターフェースだが、operationKeyは自由文字列なので、ドキュメント 10.1–10.9 の9メソッドに対して再度ホワイトリストを適用。資金系は永久書き込み禁止 —— 支払伝票(
bdi_ex_pay*)の書き込みとフローアクションは、SX_ALLOW_WRITE_ACTIONS=*でもブロックされる。
二期で書き込みを開放する順序:SX_READONLY=false → SX_ALLOW_WRITE_ACTIONS
にアクションを1つずつ追加してグレイリリースする。一気に * にしないこと。
すべての呼び出しとブロックは sanxiao.audit logger に出力される。
実際のメッセージがドキュメントの印象を覆した
公式が別途提供する『三效-API参考コード』は完全な bdi_projectfile 伝票メッセージ
(tests/fixtures/projectfile_reference.json として保存済み)。これはドキュメントの例より信頼でき、
4つの思い込みを覆した —— それぞれ tests/test_reference_payload.py で固定されており、
元に戻すと即座にテストが失敗する:
ドキュメント例が与える印象 | 実際のメッセージ |
すべてのフィールドに | 空値フィールドはキー自体が存在しない |
|
|
| ネイティブの |
|
|
その中の3番目が最も致命的:以前の field_from_dict 内の str(d["fValue"]) が、
{"fType":"enum","fValue":true} に遭遇すると Python スタイルの "True" を生成する ——
大文字 T の文字列で、サーバーは認識できず、エラーメッセージもこの問題を教えてくれない。
現在は fValue を常にそのまま透過させる。
利点として、getById の戻り値をそのまま saveOrUpdate に渡せる(1、2フィールド変更して保存)、
往復で損失がなく、この経路は test_roundtrip_is_lossless で保護されている。
さらに、メッセージの bd フィールドから8つの基本資料 formId を抽出し、forms.py に登録済み:
bd_employee、bd_department、bd_customer、bdi_bd_customer_fork、
bdi_projecttypes、bdi_projectarea、bdi_projectstauts、bdi_projectroles。
bdi_projectstautsは誤字ではない —— 公式が status を stauts と綴っており、 formId とフィールド名は両方この綴り。勝手に「修正」しないこと。
フィールド識別子の入手元
推測するな。 権威ある取得方法は星辰の画面: 伝票リスト → その他 → データインポート → テンプレート管理 → 新規テンプレート。
起動後は逆引きも可能:sx_get_form_config(form_id) で
operation.getUserconfig を呼び、その伝票のフィールド設定を返す。
forms.py には15個の formId を登録:7つは公式ドキュメント由来
(bdi_projectfile、bdi_ex_loan、bdi_ex_bx、bdi_ex_pay、
bdi_fillinworkinghours、pur_bill_request、bd_auxinfo)、
8つは参考コードのメッセージ内の基本資料参照由来。その他の伝票は formId
を直接 sx_list_query に渡せばよく、事前登録は不要。
フィールド名も同様 —— bdi_projectfile のフィールドのみ実際のメッセージで検証済み
(status/enable を使用し、billstatus はないことに注意。それは業務伝票のフィールド)。
その他の伝票のデフォルトフィールドは慣例に基づく推測のままなので、疎通後は sx_get_form_config で検証すること。
kingdee-star-mcp との関係
両者は同じ星辰帳票の2つのオープン能力であり、それぞれ独立してデプロイされる:
kingdee-star-mcp | sanxiao-mcp | |
ゲートウェイ |
|
|
認証 | HMAC 署名 + app-token 2層の資格情報 | 4ヘッダ、署名なし |
エンドポイント |
|
|
カバレッジ | 財務(伝票、経費精算、往来) | プロジェクト管理(プロジェクト、工数、予算、経費精算) |
三效の Token は星辰標準 API で事前に取得する必要がある —— すでに kingdee-star-mcp
で認証チェーンを疎通しているなら、取得したトークンと認可プッシュ内の domain/groupname/
accountid をそのまま本プロジェクトの .env に記入できる。
既知の未対応事項
公式ドキュメントは統一されたレスポンスボディスキーマを提供しておらず、
client._unwrap()は緩いアンラップを行う:errcode/success/dataを認識できれば正規化し、認識できなければそのまま返す —— データを多めに渡す方を選び、 構造を誤推測してデータを飲み込まない。実際のレスポンスを取得したら厳密化できる。伝票ステータスコードはドキュメントに完全には記載されていない。参考コードではプロジェクトマスタ
status="A"、enable="1"だが、 A/B/C がそれぞれ何を意味するか、業務伝票のbillstatusの値域は、まだ権威ある説明がない。 セマンティック層のstatusパラメータは現在、元の識別子をそのまま透過する。参考コードには
fTypeが自己矛盾しているフィールドがいくつかある ——phaseplanenddate、phaseenddateはnumと宣言されているが明らかに日付。これはベンダーメッセージ自体の不整合であり、 モデル層はそのまま受け入れ、修正しない —— 「余計な手助け」をしないため。添付ファイルのアップロードは base64 で行われ、大容量ファイルはゲートウェイのサイズ上限を評価する必要があるが、ドキュメントには記載がない。
Maintenance
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
- FlicenseNot gradedqualityBmaintenanceExposes enterprise WeChat approval, report, and check-in data reading capabilities through the MCP protocol, enabling WorkBuddy and CodeBuddy to read historical business data.7
- AlicenseAqualityBmaintenanceA read-only MCP server for querying Timely time tracking data, providing tools for project overviews, time spent summaries, and work log entries.3MIT
- FlicenseAqualityBmaintenanceRead-only MCP connector for querying the Protheus (TOTVS) system, exposing 10 GET endpoints as MCP tools with OAuth2 authentication and friendly error handling.10
- AlicenseBqualityCmaintenanceMCP server for Kingdee Cloud (K3Cloud) ERP that enables AI assistants to query and operate ERP data through natural language, supporting bills, metadata, and read/write operations.81Apache 2.0
Related MCP Connectors
A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud
Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
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/adambbhe/kingdee-sanxiao-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server