sanxiao-mcp
sanxiao-mcp —— Servidor MCP de «Gestión de Proyectos de Tres Efectos» de Kingdee Cloud·Star
Agente financiero GC032 · extremo de Tres Efectos. Identificador de aplicación bdi_projectmanagement,
dirección de suscripción https://cloud.kingdee.com/kae/#/market/detail?sid=1285.
Implementado según el documento oficial «API de Gestión de Proyectos de Tres Efectos API_2025» + «Marco de desarrollo de la API de Gestión de Proyectos de Tres Efectos de Kingdee». Fase uno solo lectura: todas las consultas habilitadas, el código de escritura está en su sitio pero bloqueado por defecto por el guardián.
La forma de la API de Tres Efectos (entiende esto primero, el resto es fácil)
Tres Efectos no es «un negocio, un endpoint», sino CRUD de documentos genéricos (Bill):
todos los documentos — archivo de proyecto, préstamos, reembolsos, pagos, registro de horas de trabajo, solicitudes de compra — pasan por el mismo conjunto de interfaces,
impulsados por formId + identificadores de campo.
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 }Por eso la estructura de este servicio también es «una salida + dos capas de encapsulación», en lugar de decenas de constantes de endpoints.
Related MCP server: mcp-timely
Índice
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 / clientAutenticación: cuatro cabeceras, sin firma
A diferencia de kingdee-star-mcp (puerta de enlace abierta de jdy) — no igual — Tres Efectos no requiere firma HMAC,
solo hay que llevar cuatro cabeceras, todas obtenidas previamente mediante la API estándar de Cloud Star:
Cabecera | Origen del valor |
| Token a nivel de cuenta del producto, obtenido mediante autenticación de la API estándar de Star |
| Dominio del IDC = campo |
| Información de autorización, la plataforma abierta la envía a la dirección de recepción de mensajes del sandbox |
| Ídem |
Aviso de trampa: la documentación oficial indica explícitamente que «al depurar en el mercado de API de la plataforma en la nube se puede ignorar
X-GW-Router-Addr». Por eso muchos lo prueban en el mercado y funciona, pero al pasar al código da 404 — porque la llamada desde código debe llevar esta cabecera.config.headers()ya lo gestiona, no lo borres.
Una vez obtenidos los cuatro elementos, rellena .env (plantilla en .env.example).
Inicio rápido
pip install -r requirements.txt
cp .env.example .env # 填入四要素
pytest -q # 69 项单测应全绿
python test_connection.py # 分层联调,结果写入 connection_test_result.txtEn Windows, haz doble clic en run_test.bat.
Herramientas MCP (28)
Capa de metainformación
Herramienta | Uso |
| Dirección de la puerta de enlace, interruptor de solo lectura, estado de los cuatro elementos y elementos faltantes |
| formId registrados, nombre en chino, campos por defecto |
| acciones disponibles, lista blanca de operaciones de solo lectura, acciones de escritura actualmente permitidas |
Capa genérica — mapeo completo de las interfaces oficiales
Herramienta | Interfaz oficial |
|
|
|
|
|
|
| Herramienta local: traduce condiciones simplificadas a |
Capa semántica — no hace falta memorizar 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
Capa de escritura — rechazada por defecto
sx_build_bill_payload (solo ensambla, no envía; en la fase uno también sirve para que una persona revise el mensaje)
sx_save_or_update / sx_submit / sx_un_submit / sx_audit / sx_un_audit
/ sx_delete / sx_push
Cómo escribir las condiciones de consulta
El qParams oficial es un array de condiciones: los elementos de nivel superior se combinan con and, dentro de un grupo de condiciones se conectan mediante 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')Operadores de comparación: = > >= < <= != like likeLeft. No hay in — se simula con query.any_of()
o con el grupo or de sx_build_query. Los campos de detalle se escriben como «identificador de detalle.identificador de campo»,
por ejemplo projectfileteam.teamstaff.
Modelo de seguridad
El guardián es de lista blanca + rechazo por defecto en tres capas:
Clasificación de acciones —
listQuery/getById/operationson lectura, los otros siete son escritura.Lista blanca de operationKey —
operationen apariencia es una interfaz de lectura, perooperationKeyes una cadena libre, así que se aplica una segunda lista blanca a los nueve métodos de las secciones 10.1–10.9 del documento.Prohibición permanente de escritura en clases financieras — las escrituras y acciones de flujo del documento de pago (
bdi_ex_pay*), incluso conSX_ALLOW_WRITE_ACTIONS=*, se bloquean.
Orden para abrir escritura en la fase dos: SX_READONLY=false → añadir acciones una a una en SX_ALLOW_WRITE_ACTIONS
para hacer despliegue gradual. No pasar directamente a *.
Todas las llamadas e interceptaciones se registran en el logger sanxiao.audit.
Los mensajes reales desmienten la impresión que da la documentación
El «Código de referencia de la API de Tres Efectos» que la empresa proporciona por separado es un mensaje completo del documento bdi_projectfile
(guardado como tests/fixtures/projectfile_reference.json). Es más fiable que los ejemplos de la documentación,
y desmiente cuatro suposiciones que parecían obvias — cada una está fijada en tests/test_reference_payload.py,
y cualquier cambio que las revierta fallará de inmediato:
Impresión que da el ejemplo de la documentación | Mensaje real |
Cada campo tiene | Los campos vacíos no presentan en absoluto la clave |
|
|
| Se ven |
|
|
La tercera es la más problemática: antes, en field_from_dict, una línea str(d["fValue"]),
al encontrarse con {"fType":"enum","fValue":true} producía un "True" de estilo Python —
una cadena con T mayúscula que el servidor no reconoce, y el mensaje de error no te dice que el problema está ahí.
Ahora fValue se transmite tal cual, sin transformación.
La ventaja es que la respuesta de getById se puede alimentar directamente a saveOrUpdate (cambiar uno o dos campos y guardar),
la ida y vuelta es sin pérdidas, y este camino está protegido por test_roundtrip_is_lossless.
Además, del campo bd del mensaje se han extraído ocho formId de datos maestros, registrados en forms.py:
bd_employee, bd_department, bd_customer, bdi_bd_customer_fork,
bdi_projecttypes, bdi_projectarea, bdi_projectstauts, bdi_projectroles.
bdi_projectstautsno es un error tipográfico — la empresa escribió status como stauts, y tanto el formId como el nombre del campo usan esa grafía. No lo «corrijas de paso».
De dónde salen los identificadores de campo
No adivines. La forma autoritativa es la interfaz de Star: Lista de documentos → Más → Importar datos → Gestión de plantillas → Nueva plantilla.
Una vez en marcha también se puede consultar a la inversa: sx_get_form_config(form_id) llama a
operation.getUserconfig y devuelve la configuración de campos de ese documento.
forms.py registra 15 formId: siete proceden de la documentación oficial
(bdi_projectfile, bdi_ex_loan, bdi_ex_bx, bdi_ex_pay,
bdi_fillinworkinghours, pur_bill_request, bd_auxinfo),
y ocho de las referencias a datos maestros en el mensaje del código de referencia. Para el resto de documentos basta con pasar el formId
directamente a sx_list_query, sin necesidad de registrarlo antes.
Lo mismo con los nombres de campo — solo los campos de bdi_projectfile están verificados contra el mensaje real
(observa que usa status/enable, no billstatus; ese es un campo de los documentos de negocio).
Los campos por defecto del resto de documentos siguen siendo una inferencia por convención; una vez que funcione, verifícalos con sx_get_form_config.
Relación con kingdee-star-mcp
Ambos son dos capacidades abiertas de la misma cuenta de Star, desplegadas de forma independiente:
kingdee-star-mcp | sanxiao-mcp | |
Puerta de enlace | Puerta de enlace jdy | Puerta de enlace de Tres Efectos |
Autenticación | Firma HMAC + credenciales de dos capas app-token | Cuatro cabeceras, sin firma |
Endpoints |
|
|
Cobertura | Finanzas (comprobantes, reembolsos, cuentas por cobrar/pagar) | Gestión de proyectos (proyectos, horas, presupuestos, reembolsos) |
El Token de Tres Efectos debe obtenerse primero mediante la API estándar de Star — si ya has completado el flujo de autorización
en kingdee-star-mcp, puedes rellenar directamente el token obtenido y el domain/groupname/
accountid del push de autorización en el .env de este proyecto.
Huecos conocidos
La documentación oficial no proporciona un esquema unificado del cuerpo de respuesta;
client._unwrap()hace un desempaquetado laxo: si reconoceerrcode/success/data, normaliza; si no los reconoce, devuelve tal cual — mejor dar más datos que tragarse datos por adivinar mal la estructura. Una vez que tengas respuestas reales, se puede ajustar.Los códigos de estado de los documentos no están completos en la documentación. En el código de referencia, el archivo de proyecto tiene
status="A",enable="1", pero qué significan A/B/C y el dominio de valores debillstatusen los documentos de negocio aún no tienen una explicación autoritativa. El parámetrostatusde la capa semántica transmite actualmente el identificador original tal cual.En el código de referencia hay varios campos cuyo
fTypees contradictorio —phaseplanenddate,phaseenddatese declaran comonumpero claramente son fechas. Es una inconsistencia del propio mensaje del proveedor; la capa de modelo los acepta tal cual sin corregirlos, para no «echar una mano que estorba».La subida de adjuntos va en base64; para archivos grandes hay que evaluar el límite de volumen de la puerta de enlace, la documentación no lo especifica.
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