mcpBPMSoft
The mcpBPMSoft server acts as a bridge between LLM agents and BPMSoft CRM, abstracting away OData complexities, authentication, and business logic to enable natural language interaction.
Reading & Searching Data
List, filter, sort, and paginate records from any collection (
bpm_get_records)Get a single record by UUID or count records matching a filter
Search with human-readable criteria (e.g., "contacts from Moscow") — automatically compiled into OData
$filter(bpm_search_records)Cross-entity search across Contact, Account, Lead, and Opportunity by name substring (
bpm_search_unified)
Creating & Modifying Data
Create, update (PATCH), and delete records with automatic lookup UUID resolution from human-readable text
Bulk update or delete by OData filter with a required
expected_countsafety guard to prevent accidental mass changes
Batch Operations (OData v4)
Perform bulk creates, updates, or deletes in a single
$batchrequest, with an option to continue on error
Schema & Lookup Discovery
List all available collections (EntitySets) with optional filtering
Get collection schema including field types, nullability, lookup relations, and captions
Resolve lookup UUIDs from human-readable values (with fuzzy search support)
Get all values for an enumeration/lookup field
Find fields by name fragment across loaded schemas
Get an instance overview (entity counts, custom
Usr*collections/fields)Access a workflow/scenario catalog with typical use cases and BPMSoft limitations
High-Level Workflow Tools
Register a contact — finds or creates an Account, creates a Contact, and links them in one call
Log an activity (call, meeting, task) with automatic type/owner resolution and record linking
Set a record's status by human-readable name — server resolves the correct field and UUID
Business Processes
Run BPMSoft business processes via
ProcessEngineService.svcwith parameters and optional output retrievalResume a suspended process element by its UID
File Operations
Upload/download files to/from
SysImageor any binary entity fieldClear binary fields
Social Feed
Post messages to a record's activity feed (
SocialMessage), with optional reply threading
Connection & Authentication
Initialize connection with username/password (when environment credentials are permitted)
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcpBPMSoftShow me contacts from Moscow last month."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP-сервер для BPMSoft
Подключение BPMSoft 1.8 к LLM-агенту (Claude Desktop, Cursor, любой клиент Model Context Protocol) — чтобы спросить «найди контакты из Москвы за последний месяц» или «зарегистрируй Иванова из Ромашки», а не вручную набирать OData-фильтры.
Сервер берёт на себя всё, что обычно мешает:
авторизацию, CSRF-токены и сессии BPMSoft;
разницу между OData v3 и v4 (форматы ID, имена полей, $batch);
перевод «Город = Москва» в
CityId = <UUID>через справочники;защиту от случайного массового удаления, переполнения контекста модели и SSRF;
запуск бизнес-процессов через
ProcessEngineService.
В коробке 31 операционный инструмент (+ bpm_init при включённом env-creds opt-in), 6 prompts, 4 ресурса — от низкоуровневого CRUD до готовых сценариев «зарегистрировать контакт + контрагента» и «найти всё про Иванова».
Содержание
Related MCP server: SAP OData to MCP Server
Что это решает
BPMSoft предоставляет OData-API, который мощный, но очень многословный. Запрос «контакты из Москвы, созданные на этой неделе» на чистом OData выглядит так:
GET /0/odata/Contact?$filter=City/Name eq 'Москва' and CreatedOn ge 2026-04-26T00:00:00Z&$select=Id,Name,Email
Cookie: BPMSESSIONID=...; BPMCSRF=...
BPMCSRF: <csrf>
ForceUseSession: trueLLM-агенту, который пытается его собрать, нужно знать:
где живёт OData (для .NET 8 —
/odata, для .NET Framework —/0/odata, для v3 — отдельный путь);что строки в одинарных кавычках, GUID-ы у v3 в
guid'…', у v4 без обёртки;что лимит ответа 20 000 строк, $batch только в v4 и не больше 100 подзапросов;
что lookup-поля у v4 заканчиваются на
Id, а у v3 — нет;что русские названия полей доступны только через системную таблицу
SysEntitySchemaColumn;и десяток других мелочей.
Этот сервер прячет всё это за человеческим интерфейсом:
Пользователь: Найди контакты из Москвы за последние 30 дней
Агент → tool: bpm_search_records
collection: "Contact"
criteria: [
{ field: "Город", op: "равно", value: "Москва" },
{ field: "Дата создания", op: "за последние N дней", value: 30 }
]
Сервер → Скомпилирует $filter, разрешит «Москва» в UUID города,
применит лимит max_records (от переполнения контекста),
вернёт сводку + первые 5 записей + cursor для следующих.Быстрый старт за 5 минут
Требуется: Node.js 18+, инстанс BPMSoft 1.8 с включённым OData (по умолчанию — да).
# 1. Склонировать репозиторий
git clone https://github.com/Catter58/mcpBPMSoft.git
cd mcpBPMSoft
# 2. Установить зависимости
npm install
# 3. Собрать
npm run build
# 4. Прописать URL целевого стенда в .env
cp .env.example .env
# открыть .env, заполнить BPMSOFT_URL
# 5. Запустить сервер
npm startПо умолчанию сервер поднимает Streamable HTTP транспорт на порту 8007. MCP-клиент обращается к нему по HTTP с авторизационными заголовками своего пользователя — секреты на сервере не хранятся.
Для локальной отладки через stdio установите MCP_TRANSPORT=stdio в .env.
Подключение к Claude Desktop
Сервер использует Streamable HTTP транспорт по умолчанию. Для Claude Desktop, который запускает процесс локально, удобен режим stdio. В файле ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) или %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"bpmsoft": {
"command": "node",
"args": ["/абсолютный/путь/к/mcpBPMSoft/build/index.js"],
"env": {
"BPMSOFT_URL": "https://mycompany.bpmsoft.com",
"MCP_TRANSPORT": "stdio",
"BPMSOFT_ODATA_VERSION": "4",
"BPMSOFT_PLATFORM": "net8"
}
}
}
}Перезапустить Claude Desktop. В чате появится бейдж bpmsoft, и инструменты будут доступны модели.
Авторизация в stdio-режиме. При запуске через Claude Desktop аутентификация выполняется per-request: каждый вызов инструмента должен нести заголовок
BPMCSRFи cookie.ASPXAUTH,BPMSESSIONID,CsrfToken— Claude Desktop передаёт их автоматически из сессии браузера пользователя. Секреты на сервере не хранятся.
Полный пример — в examples/claude_desktop_config.json.
Примеры диалогов
Пример 1 — поиск с человеческим языком
Пользователь: покажи активные сделки на сумму больше 500 тысяч,
где менеджер — Иванова
Claude → bpm_search_records
collection: "Opportunity"
criteria: [
{ field: "Сумма", op: "больше", value: 500000 },
{ field: "Owner", op: "равно", value: "Иванова" },
{ field: "Stage", op: "не равно", value: "Закрыта (выиграна)" }
]
format: "markdown"
Сервер вернёт:
Скомпилированный $filter:
Amount gt 500000 and OwnerId eq <UUID Ивановой>
and StageId ne <UUID этапа закрыта>
Получено записей: 7
| Id | Title | Amount | Stage | Owner |
|-----|--------------------|---------|------------|----------|
| ... | Поставка софта | 1200000 | В работе | Иванова |
...Пример 2 — регистрация нового контакта
Пользователь: создай контакт Петров Пётр, телефон +7-999-1234567,
работает в ООО Орбита
Claude → bpm_register_contact
name: "Петров Пётр"
phone: "+7-999-1234567"
account_name: "ООО Орбита"
Сервер:
1. Ищет Account по Name='ООО Орбита' → не нашёл → создаёт.
2. Получает accountId.
3. Создаёт Contact с подставленным AccountId.
4. Возвращает оба UUID.Пример 3 — массовое обновление со страховкой
Пользователь: закрой все мои задачи старше года
Claude → bpm_search_records (узнать сколько таких)
collection: "Activity"
criteria: [
{ field: "Owner", op: "равно", value: "<текущий пользователь>" },
{ field: "CreatedOn", op: "меньше", value: "2025-05-02T00:00:00Z" },
{ field: "Status", op: "не равно", value: "Завершено" }
]
[ответ: 12 записей]
Пользователь: ага, закрывай
Claude → bpm_update_by_filter
collection: "Activity"
filter: "OwnerId eq <UUID> and CreatedOn lt 2025-05-02T00:00:00Z and StatusId ne <UUID Завершено>"
data: { Status: "Завершено" }
expected_count: 12 # страховка: если найдено иное число — операция отменитсяПример 4 — запуск бизнес-процесса
Пользователь: запусти процесс «UsrCalculatePipeline» и покажи результат
Claude → bpm_run_process
process_name: "UsrCalculatePipeline"
parameters: { period_days: "30" }
result_parameter_name: "UsrPipelineSummary"
Сервер:
GET /ServiceModel/ProcessEngineService.svc/UsrCalculatePipeline/Execute
?period_days=30&ResultParameterName=UsrPipelineSummary
Парсит XML-обёртку <string>...</string>, JSON.parse содержимого.
Возвращает структуру в structuredContent.Пример 5 — комментарий в ленте записи
Пользователь: оставь в ленте этой сделки заметку «звонил, обещали вернуться в среду»
Claude → bpm_post_feed
collection: "Opportunity"
id: "<UUID сделки>"
message: "звонил, обещали вернуться в среду"
Сервер:
POST /odata/SocialMessage
body: { Message: "...", EntitySchemaName: "Opportunity", EntityId: "..." }Все инструменты — кратко
Подключение (env-creds opt-in)
Инструмент | Зачем |
| Подключиться к BPMSoft через логин/пароль (доступен только при |
Чтение
Инструмент | Зачем |
| Получить записи коллекции с фильтром/select/expand/order/top/skip; safe-pagination + token-aware форматы (compact/full/markdown); поддерживает opaque cursor |
| Одна запись по UUID |
| Количество записей по фильтру |
| Поиск с критериями на русском — массив |
Запись
Инструмент | Зачем |
| Создать запись; lookup-поля резолвятся по тексту, ключи можно на русском |
| Обновить по UUID |
| Удалить по UUID |
| Массовое обновление с обязательным |
| Массовое удаление с обязательным |
Схема и справочники
Инструмент | Зачем |
| Список доступных EntitySet |
| Поля коллекции с русскими подписями, типами, lookup-связями |
| Найти UUID справочного значения; |
| Все значения справочника, к которому привязано lookup-поле (например, все ActivityCategory) |
| Карта типичных сценариев + связи между сущностями + ограничения BPMSoft 1.8. Хорошо вызывать в начале сессии. |
| Найти поле по фрагменту русского/английского названия в уже загруженных схемах |
| Сводка по инстансу за один вызов: главные сущности, их счётчики, кастомные коллекции/поля ( |
Пакетные операции (только OData v4)
Инструмент | Зачем |
| Создать N записей одним $batch |
| Обновить N записей одним $batch |
| Удалить N записей одним $batch |
Все три поддерживают continue_on_error.
Файлы
Инструмент | Зачем |
| Загрузить локальный файл в |
| Скачать файл из |
| PUT бинарных данных в произвольное поле сущности ( |
| GET бинарных данных из поля сущности |
| Очистить бинарное поле |
Готовые workflow-инструменты
Инструмент | Зачем |
| Создать Account (или найти) + создать Contact + привязать |
| Создать Activity с резолвом типа/владельца по тексту, опц. привязка к Contact/Account/Opportunity |
| Сменить статус по человеческому имени; сервер сам найдёт правильное status-поле и его справочник |
| Сквозной поиск по подстроке в Contact/Account/Lead/Opportunity (плоский список) |
Бизнес-процессы и лента
Инструмент | Зачем |
| Запустить БП через |
| Возобновить элемент уже выполняющегося процесса по UID |
| Опубликовать сообщение в ленту записи (через коллекцию |
Готовые сценарии (MCP prompts)
LLM-клиенты с поддержкой prompts (Claude Desktop, Cursor) могут вызвать готовый сценарий за одну команду — модель получит сразу шаблон с инструкциями и нужными tool-ами:
Prompt | Аргументы | Что делает |
| — | Обзор сервера, главные сущности, типичные сценарии |
|
| Сквозной поиск + детали при необходимости |
|
| Регистрация контакта в один заход |
|
| Отчёт: новые контакты, активные сделки, завершённые задачи |
|
| Поиск потенциальных дубликатов (без удаления) |
|
| Анализ воронки Opportunity: распределение по стадиям, средняя сумма |
Ресурсы (MCP resources)
Браузабельные URI, которые модель может «прочитать» вместо tool-вызова — дешевле по токенам, удобно для карточек:
bpmsoft://collections — список всех EntitySet
bpmsoft://collection/{name} — карточка коллекции (поля + record_count)
bpmsoft://entity/{collection}/{id} — карточка одной записи
bpmsoft://schema/{name} — только схема коллекции (быстрее, без count)Конфигурация
Все параметры — через переменные окружения. Единственная обязательная переменная — BPMSOFT_URL; остальные имеют разумные defaults.
Основные параметры
Переменная | По умолчанию | Описание |
| — (обязательно) | URL приложения, например |
|
| Транспорт: |
|
| Порт HTTP-сервера (при |
|
|
|
|
|
|
|
| Размер страницы при автопагинации |
|
| Лимит подзапросов в |
|
| TTL кеша lookup в секундах |
|
| Таймаут одного HTTP-запроса (мс) |
|
| Лимит размера файла (10 МБ) |
|
|
|
Авторизация
По умолчанию — per-request. Сервер не хранит учётных данных. Каждый входящий MCP HTTP-запрос должен нести:
заголовок
BPMCSRF— CSRF-токен пользователя;заголовок
Cookieс полями.ASPXAUTH,BPMSESSIONID,CsrfToken.
Сервер извлекает эти значения через AsyncLocalStorage и пробрасывает их в каждый OData-запрос к BPMSoft. Запрос без авторизационных данных завершается ошибкой AuthRequiredError (HTTP 401). Эта модель аналогична mcp-proxy-server.
Env-creds (скрытый opt-in)
Не рекомендуется для on-prem без явного согласия службы ИБ.
Если выставить BPMSOFT_ALLOW_ENV_CREDS=true, сервер дополнительно:
включает путь аутентификации через
BPMSOFT_USERNAME/BPMSOFT_PASSWORD(login черезAuthService.svc);регистрирует инструмент
bpm_init, позволяющий передать логин/пароль через MCP-вызов.
По умолчанию (BPMSOFT_ALLOW_ENV_CREDS не задана или false) bpm_init не регистрируется, а env-creds путь не используется. В стандартной документации и подсказках этот режим не рекламируется.
Deployment hardening (on-prem)
Default bind is loopback (
MCP_HTTP_HOST=127.0.0.1). Set explicitly only if the reverse proxy lives on a different interface; never bind to0.0.0.0in production.Plain HTTP only — the server must sit behind an HTTPS-terminating reverse proxy (nginx, Caddy, etc.). Never expose port 8007 directly to untrusted networks.
Firewall the host so only the reverse proxy can reach port 8007, and so the only permitted outbound destination is the BPMSoft stand.
Keep
BPMSOFT_ALLOW_ENV_CREDSunset (default per-request auth); keepBPMSOFT_DEBUGunset in production.Run
npm auditregularly to catch transitive dependency vulnerabilities.Note: upstream OData error messages are surfaced verbatim to callers and may echo request data (field names, filter values). Account for this when configuring aggregated log storage and retention.
Скрипты
npm run build # компиляция TS -> JS в build/
npm start # запустить собранный сервер
npm run dev # tsc --watch на время разработки
npm test # vitest run (95 тестов: unit + интеграция через MSW)
npm run test:watch # тесты в watch-режиме
npm run lint # eslint (typescript-eslint, рекомендованный preset)
npm run lint:fix # автоисправление
npm run format # prettier --write
npm run format:check # prettier --check (для CI)Отладка
Самый быстрый способ увидеть, что именно уходит в BPMSoft — включить BPMSOFT_DEBUG:
BPMSOFT_DEBUG=1 npm start
# -> [HttpClient][req] GET https://.../odata/Contact?$top=10
# -> [HttpClient][res] GET .../odata/Contact -> 200 (143ms)
BPMSOFT_DEBUG=trace npm start
# -> также выводит headers и тела запросов/ответов;
# BPMCSRF/Cookie/UserPassword автоматически маскируются.Для проверки подключения без MCP-клиента можно запустить сервер напрямую — он выводит в stderr:
[Server] Configuration loaded from environment variables
Target: https://mycompany.bpmsoft.com
OData: v4, Platform: net8
MCP BPMSoft OData Server running on http (port 8007)
Registered 31 operational tools
Registered 6 prompts, 4 resource templatesПри MCP_TRANSPORT=stdio строка транспорта будет running on stdio.
Ограничения BPMSoft 1.8
Ограничение | Значение |
Максимум строк в OData-ответе | 20 000 |
Максимум подзапросов в | 100 |
Максимальный размер файла | 10 МБ (настраивается) |
Длина query string в OData v3 | 4 000 символов |
| не поддерживается (используйте v4) |
Создание системных пользователей | не поддерживается |
Прямой HTTP-API для EntitySchemaQuery | не предусмотрен — используйте обёртку через бизнес-процесс (см. сценарий |
Часто задаваемые вопросы
LLM путается в OData-синтаксисе. Что делать?
Используйте bpm_search_records с criteria-массивом. Он принимает поля по русской подписи, операторы по-русски, сам экранирует значения и ставит правильный синтаксис. Сырые $filter нужны только для очень специфичных случаев.
Сервер вернул 20 000 строк в одном ответе и контекст модели «лопнул».
По умолчанию bpm_get_records ограничивает выдачу max_records=1000 и пагинация выключена. Если хотите всё — передайте auto_paginate: true и увеличьте max_records. Для пошагового перебора возвращается cursor — передайте его в следующий вызов и получите следующую страницу без перенабора параметров.
Как назвать поле — «Город» или «City»?
Любым. Сервер хранит двусторонний словарь caption ↔ name (по SysSchema/SysEntitySchemaColumn) и переводит сам. Если не угадал — в ошибке будут «Похоже на: …».
Lookup-значения — UUID или текст?
Текст. Сервер сам резолвит «Москва» → <UUID> через bpm_lookup_value. Если найдено несколько кандидатов — вернёт список и попросит уточнить.
OData v3 на .NET Framework — будет работать?
Да, кроме $batch (его в v3 BPMSoft нет). При попытке bpm_batch_* на v3 получите явную ошибку, а не молчаливое 404.
Как запустить кастомный бизнес-процесс?
bpm_run_process с process_name (имя схемы процесса) и parameters. Если процесс возвращает результат — добавьте result_parameter_name. Сервер заберёт XML-обёртку и распакует JSON-payload в structuredContent.
Что если на инстансе нет коллекции SocialMessage?
bpm_post_feed вернёт ошибку 404 с понятным сообщением «На этом инстансе нет коллекции SocialMessage; функция ленты не настроена». Лента в BPMSoft может быть выключена настройками безопасности.
Архитектура (для разработчиков)
src/
client/ HttpClient (binary-aware, contentKind, SSRF, 429+Retry-After)
ODataClient (v3/v4, $batch, nextLink, бинарные поля)
process/ ProcessEngineClient (XML envelope parsing)
metadata/ MetadataManager (fast-xml-parser, caption maps, suggestions)
lookup/ LookupResolver (caption-aware, LRU, fuzzy fallback)
utils/ errors, odata, suggest, filter-compiler, render, cursor
prompts/ registry + register
resources/ 4 resource templates
tools/ init, read, write, schema, describe-instance, enum,
workflow-catalog, batch, stream, process
workflows/ register-contact, log-activity, set-status, search-unified
tests/ 95 тестов (vitest + MSW): юнит + интеграция HTTPПодробнее — в CLAUDE.md (для разработчиков, добавляющих новые tool-ы)
Лицензия
MIT — максимально свободные условия из стандартных OSS-лицензий. Использовать, изменять, распространять и встраивать в коммерческие продукты можно без ограничений; единственное требование — сохранить уведомление об авторских правах в копиях.
Дополнительно (не юридически обязательно): если планируете существенное переиспользование, интеграцию в коммерческий продукт или редистрибуцию под собственным брендом — автор будет признателен за короткое сообщение в GitHub: @Catter58. Это не требование лицензии, а просьба «дайте знать, чтобы я мог помочь и был в курсе».
Полный текст — в LICENSE.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/Catter58/mcpBPMSoft'
If you have feedback or need assistance with the MCP directory API, please join our Discord server