Skip to main content
Glama
adambbhe
by adambbhe

sanxiao-mcp — MCP-сервер «Управление проектами по трём эффектам» Kingdee Cloud·Xingchen

GC032 Финансовый агент · модуль «Три эффекта». Идентификатор приложения bdi_projectmanagement, адрес подписки https://cloud.kingdee.com/kae/#/market/detail?sid=1285.

Реализовано на основе официальной документации «API управления проектами по трём эффектам_2025» + «Фреймворк разработки API управления проектами по трём эффектам Kingdee». Первая фаза — только чтение: все запросы открыты, код записи готов, но по умолчанию отклоняется защитой.

Форма API «Трёх эффектов» (сначала поймите это, остальное просто)

«Три эффекта» — это не «один бизнес — одна конечная точка», а универсальный CRUD для документов (Bill): все документы — карточки проектов, займы, возмещения, платежи, учёт рабочего времени, заявки на закупку — используют один и тот же набор интерфейсов, управляемых через 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 }

Поэтому структура этого сервиса — «один выход + два уровня обёртки», а не десятки констант конечных точек.

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

Аутентификация: четыре заголовка, без подписи

В отличие от kingdee-star-mcp (шлюз jdy) — по-другому — для «Трёх эффектов» не требуется HMAC-подпись, достаточно четырёх заголовков, все они заранее получаются через стандартный API Xingchen:

Заголовок

Источник значения

Token

Токен уровня учётной записи продукта, получается через стандартную аутентификацию API Xingchen

X-GW-Router-Addr

Домен IDC = поле domain в push-сообщении «Реального времени приёма авторизации»

groupname

Информация об авторизации, открытая платформа отправляет на адрес приёма сообщений песочницы

accountid

То же

Предупреждение о подводных камнях: в официальной документации явно указано, что «при отладке на маркетплейсе облачной платформы можно игнорировать X-GW-Router-Addr». Поэтому многие отлаживают на маркетплейсе, а в коде получают 404 — потому что при вызове из кода обязательно нужно передавать этот заголовок. config.headers() уже обрабатывает это, не удаляйте.

После получения четырёх элементов заполните .env (шаблон в .env.example).

Быстрый старт

pip install -r requirements.txt
cp .env.example .env        # 填入四要素
pytest -q                   # 69 项单测应全绿
python test_connection.py   # 分层联调,结果写入 connection_test_result.txt

В Windows просто дважды щёлкните run_test.bat.

Инструменты MCP (28)

Метаинформация

Инструмент

Назначение

sx_health

Адрес шлюза, переключатель только для чтения, статус готовности четырёх элементов и отсутствующие элементы

sx_list_forms

Зарегистрированные formId, китайские названия, поля по умолчанию

sx_capabilities

Доступные действия, белый список операций только для чтения, текущие разрешённые операции записи

Общий уровень — полное отображение официальных интерфейсов

Инструмент

Официальный интерфейс

sx_list_query

listQuery

sx_get_by_id

getById

sx_operation

operation (ограничено белым списком только для чтения)

sx_build_query

Локальный инструмент: переводит упрощённые условия в qParams, не отправляет запрос

Семантический уровень — не нужно запоминать 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 — это массив условий: верхние элементы соединяются и, внутри группы условий — через 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() или группу or в sx_build_query. Поля записей пишутся как «идентификатор записи.идентификатор поля», например projectfileteam.teamstaff.

Модель безопасности

Защита — белый список + отказ по умолчанию в три уровня:

  1. Классификация действийlistQuery/getById/operation — чтение, остальные семь — запись.

  2. Белый список operationKeyoperation на вид интерфейс чтения, но operationKey — свободная строка, поэтому для девяти методов из разделов 10.1–10.9 документации делается ещё один белый список.

  3. Финансовые операции запрещены навсегда — запись и действия процесса для платёжных документов (bdi_ex_pay*), даже если SX_ALLOW_WRITE_ACTIONS=* — блокируется.

Порядок открытия записи во второй фазе: SX_READONLY=false → в SX_ALLOW_WRITE_ACTIONS добавляйте действия по одному для постепенного включения. Не переходите сразу к *.

Все вызовы и блокировки записываются в логгер sanxiao.audit.

Реальные сообщения опровергают впечатление от документации

Официальный дополнительный «Справочный код API трёх эффектов» — это полное сообщение документа bdi_projectfile (сохранено как tests/fixtures/projectfile_reference.json). Оно более достоверно, чем примеры из документации, и опровергает четыре предположения, которые казались очевидными — каждое зафиксировано в tests/test_reference_payload.py, изменение обратно сразу вызовет ошибку:

Впечатление от примера в документации

Реальное сообщение

У каждого поля есть fValue

Пустые поля вообще не содержат ключ fValue, а не fValue:""

enum должен иметь fValueText

status/enable/enablecostamtctl содержат только fValue

fValue всегда строка

Встречаются нативные true / false / 0, смешанные со строкой "10"

fValueText — только для enum

bd тоже содержит его, для отображения имени базовой записи

Третье — самое критичное: раньше в field_from_dict была строка str(d["fValue"]), при {"fType":"enum","fValue":true} получался Python-стиль "True" — строка с заглавной T, сервер её не распознаёт, и сообщение об ошибке не укажет на эту проблему. Теперь fValue передаётся как есть, без изменений.

Преимущество: возврат getById можно напрямую передать в saveOrUpdate (изменить одно-два поля и сохранить), цикл без потерь, этот путь защищён тестом test_roundtrip_is_lossless.

Кроме того, из поля bd в сообщении извлечены восемь 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, и имя поля имеют такое написание. Не «исправляйте» это.

Откуда берутся идентификаторы полей

Не гадайте. Авторитетный способ — интерфейс Xingchen: список документов → Ещё → Импорт данных → Управление шаблонами → Новый шаблон.

После запуска можно также проверить обратным способом: sx_get_form_config(form_id) вызовет operation.getUserconfig и вернёт конфигурацию полей этого документа.

В forms.py зарегистрировано 15 formId: семь из официальной документации (bdi_projectfile, bdi_ex_loan, bdi_ex_bx, bdi_ex_pay, bdi_fillinworkinghours, pur_bill_request, bd_auxinfo), восемь — из ссылок на базовые записи в сообщении справочного кода. Остальные документы можно передавать formId напрямую в sx_list_query, предварительная регистрация не нужна.

Аналогично с именами полей — только поля bdi_projectfile проверены по реальному сообщению (обратите внимание: там используется status/enable, нет billstatus; это поле бизнес-документов). Поля по умолчанию для остальных документов всё ещё предполагаются по соглашению, после запуска проверьте через sx_get_form_config.

Отношение к kingdee-star-mcp

Оба — два открытых возможности одного и того же учётного экземпляра Xingchen, развёрнуты независимо:

kingdee-star-mcp

sanxiao-mcp

Шлюз

api.kingdee.com шлюз jdy

bj1-api.kingdee.com шлюз трёх эффектов

Аутентификация

HMAC-подпись + app-token, два уровня учётных данных

Четыре заголовка, без подписи

Конечные точки

/jdy/v2/{module}/{object} — сотни

common/{action} — десять

Покрытие

Финансы (проводки, возмещения, расчёты)

Управление проектами (проекты, рабочее время, бюджеты, возмещения)

Токен Token для «Трёх эффектов» нужно сначала получить через стандартный API Xingchen — если вы уже прошли цепочку авторизации в kingdee-star-mcp, можно взять полученный токен и domain/groupname/ accountid из push-уведомления об авторизации и напрямую заполнить в .env этого проекта.

Известные пробелы

  • В официальной документации нет единой схемы ответа, client._unwrap() выполняет мягкую распаковку: если распознаёт errcode/success/data — нормализует, если нет — возвращает как есть: лучше отдать больше данных, чем потерять из-за неверной структуры. После получения реальных ответов можно ужесточить.

  • Коды статусов документов в документации перечислены не полностью. В справочном коде для карточки проекта status="A", enable="1", но что означают A/B/C и допустимые значения billstatus для бизнес-документов — авторитетного объяснения нет. Параметр status в семантическом слое пока передаёт исходный идентификатор.

  • В справочном коде есть несколько полей с противоречивым fTypephaseplanenddate, phaseenddate объявлены как num, но явно являются датами. Это несогласованность в самом сообщении производителя, модель принимает как есть, без исправлений, чтобы не «навредить».

  • Загрузка вложений идёт через base64, для больших файлов нужно оценить лимит размера шлюза, в документации не указано.

F
license - not found
C
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    A
    quality
    B
    maintenance
    Read-only MCP connector for querying the Protheus (TOTVS) system, exposing 10 GET endpoints as MCP tools with OAuth2 authentication and friendly error handling.
    10
  • A
    license
    B
    quality
    C
    maintenance
    MCP 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.
    8
    1
    Apache 2.0

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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