Skip to main content
Glama
leonardows1

SAP B1 ServiceLayer MCP Server

by leonardows1

SAP B1 ServiceLayer MCP Server

Сервер MCP (Model Context Protocol) для подключения ИИ-ассистентов (opencode, Claude и т. д.) к ServiceLayer SAP Business One 10.0 в локальной сети. Запускается с помощью npx из этого репозитория GitHub, без установки чего-либо на ПК.

Характеристики

  • Только чтение по умолчанию: с SAP_B1_READONLY=true (по умолчанию) регистрируются только инструменты запросов (GET). Инструменты записи (POST/PATCH/DELETE) не существуют на сервере и не могут быть вызваны.

  • Полное обнаружение: sap_list_entities, sap_get_entity_schema и sap_list_actions запрашивают GET /$metadata (скачивается один раз за процесс и кэшируется) и предоставляют ~140 сущностей CRUD (включая пользовательские таблицы @ и UDO) и сотни сервисных методов ServiceLayer.

  • Опциональный режим записи: с SAP_B1_READONLY=false включаются sap_create, sap_update, sap_delete для сущностей ServiceLayer и sap_call_action для сервисных методов (могут иметь побочные эффекты).

  • Запуск через npx github:: без ручной установки.

  • Управляемая сессия: неявный вход с CompanyDB/пользователем/паролем, файлы cookie B1SESSION + ROUTEID хранятся в памяти (поддержка многоузлового ServiceLayer), автоматический повторный вход при 401 и гарантированный выход при завершении процесса (плюс инструмент sap_logout).

  • Самоподписанный TLS: поддержка самоподписанных сертификатов ServiceLayer (типично для локальных сред) с помощью SAP_B1_VERIFY_TLS=false.

  • Без телеметрии и внешних вызовов: HTTP-клиент обращается исключительно к настроенному URL (SAP_B1_SERVER_URL).

  • Лимиты безопасности: top ограничен 200 записями на запрос.

Related MCP server: BTP MCP Server

Инструменты

Чтение (всегда доступны)

Tool

Описание

sap_query

Общий GET к любой сущности OData с select, filter, top (≤200), skip, orderby, expand

sap_list_entities

Список всех сущностей OData, предоставляемых ServiceLayer (из $metadata, кэшируется); включает пользовательские таблицы (@) и UDO. Необязательный filter для ограничения

sap_get_entity_schema

Схема сущности: свойства (типы/ключи) и navigationProperties (действительны для $expand); разрешает entity sets, разделяющие EntityType

sap_list_actions

Список сервисных методов (function imports, напр.: CompanyService_GetCompanyInfo) с их параметрами

sap_sql_query

SQL только для чтения (SELECT/WITH; INSERT/UPDATE/DELETE/DDL отклоняются) через POST /sql_query — только на новых ServiceLayer v2/FP; на старых v1 возвращает понятную ошибку

sap_get_business_partners

Деловые партнеры (клиенты/поставщики), фильтр по card_type

sap_get_items

Товары каталога

sap_get_sales_orders

Заказы на продажу; в v1 строки (DocumentLines) включаются без expand (expand доступен только в v2)

sap_get_stock

Остатки товара по ItemCode (+ необязательный WarehouseCode); понятная ошибка, если ItemStock отсутствует в ServiceLayer (старые v1)

sap_session_status

Состояние активной сессии

sap_logout

Явное завершение сессии

Запись (только если SAP_B1_READONLY=false)

Tool

Описание

sap_create

Создает запись в сущности (POST)

sap_update

Обновляет запись по её ключу (PATCH)

sap_delete

Удаляет запись по её ключу (DELETE)

sap_call_action

Вызывает сервисный метод (POST); может иметь побочные эффекты (Cancel, UpdateCompanyInfo, Import...)

Требования

  • Node.js 18+

  • SAP Business One 10.0 с включенным ServiceLayer (типичный путь https://<host>:50000/b1s/v1)

  • opencode (или любой MCP-клиент)

Конфигурация (переменные окружения)

Variable

Требуется

По умолчанию

Описание

SAP_B1_SERVER_URL

Да

-

Базовый URL ServiceLayer (напр.: https://<host>:50000/b1s/v1)

SAP_B1_DATABASE

Да

-

Имя CompanyDB (напр.: SBODEMO_XX)

SAP_B1_USERNAME

Да

-

Пользователь ServiceLayer

SAP_B1_PASSWORD

Да

-

Пароль пользователя

SAP_B1_READONLY

Нет

true

false включает инструменты записи

SAP_B1_VERIFY_TLS

Нет

true

false для самоподписанных сертификатов

SAP_B1_MAX_TOP

Нет

200

Максимальный лимит top на запрос

Использование с opencode

В opencode.json проекта:

{
  "mcp": {
    "sap-b1-servicelayer": {
      "type": "local",
      "command": ["npx", "-y", "github:leonardows1/sap-b1-servicelayer-mcp"],
      "environment": {
        "SAP_B1_SERVER_URL": "https://<host>:50000/b1s/v1",
        "SAP_B1_DATABASE": "<CompanyDB>",
        "SAP_B1_USERNAME": "<usuario>",
        "SAP_B1_PASSWORD": "<password>",
        "SAP_B1_SESSION_TIMEOUT": "30",
        "SAP_B1_VERIFY_TLS": "false",
        "SAP_B1_READONLY": "true"
      },
      "enabled": true
    }
  }
}

Перезапустите opencode после сохранения конфигурации.

Безопасность

  • Учетные данные и cookie сессии никогда не записываются в логи.

  • Процесс связывается только с SAP_B1_SERVER_URL.

  • В режиме READONLY=true инструменты записи не регистрируются: создать/обновить/удалить записи невозможно по дизайну.

  • Конфигурация проверяется при запуске: отсутствие SAP_B1_SERVER_URL, SAP_B1_DATABASE, SAP_B1_USERNAME или SAP_B1_PASSWORD → процесс прерывается с понятным сообщением.

  • Имена сущностей проверяются (^[A-Za-z][A-Za-z0-9_]*$): невозможно внедрить пути (напр.: BusinessPartners/...).

  • Значения ключей и фильтры экранируются в OData (дублирование одинарных кавычек): id или ItemCode с ' не ломает URL или $filter.

  • Пароль хранится в открытом виде в конфигурации MCP-клиента. Рекомендуется использовать менеджер секретов, если репозиторий доступен другим.

  • npx github: не имеет semver-версионирования: каждый запуск берёт последнюю версию ветки main. После обновления репозитория выполните npm cache clean --force, чтобы принудительно перезагрузить.

Структура

Прагматичная гексагональная архитектура (ESM, без фреймворка): домен и варианты использования не знают о транспорте MCP или HTTP; инфраструктура реализует порт ServiceLayerPort (DIP), а инструменты MCP являются тонкими контроллерами.

sap-b1-servicelayer-mcp/
├── package.json                  # Definición del paquete npm (bin: server.js)
├── server.js                     # Composition root: cablea dependencias y arranca stdio
├── src/
│   ├── config/
│   │   └── config.js             # Configuración desde env, validada e inmutable
│   ├── domain/
│   │   ├── errors.js             # Excepciones tipadas (Configuration/InvalidArgument/ServiceLayer)
│   │   ├── oData.js              # Helpers puros: query string, filtros, clamp de $top, validación de entidad
│   │   └── edmx.js               # Parseo puro de $metadata: entity sets, esquemas, function imports
│   ├── application/
│   │   ├── ports.js              # Puerto ServiceLayerPort (contrato, DIP)
│   │   ├── helpers.js            # ensureOk / ensureSuccess / unwrapValue
│   │   └── services/
│   │       ├── queryService.js   # Consulta GET genérica a entidades OData
│   │       ├── catalogService.js # Socios de negocio y artículos (compone QueryService)
│   │       ├── salesService.js   # Pedidos de venta y stock
│   │       ├── sessionService.js # Estado y cierre de sesión
│   │       ├── writeService.js   # create / update / delete
│   │       ├── metadataService.js # Descubrimiento: $metadata cacheado, entidades, esquemas y actions
│   │       └── sqlService.js     # SQL de solo lectura (SELECT/WITH) vía POST /sql_query
│   └── infrastructure/
│       ├── http/
│       │   ├── httpClient.js     # Cliente HTTP mínimo (http/https)
│       │   ├── cookies.js        # Manipulación pura de cookies de sesión
│       │   └── serviceLayerClient.js # Adaptador del puerto: login, 401, logout
│       └── mcp/
│           ├── result.js         # ok / err / serialize / handle (controladores delgados)
│           └── tools.js          # Registro de tools MCP
├── test/                         # node:test (sin dependencias externas)
│   ├── config.test.js
│   ├── oData.test.js
│   ├── edmx.test.js              # parseo EDMX v3/v4 (entity sets, esquemas, function imports)
│   ├── cookies.test.js
│   ├── client.test.js
│   ├── fakePort.js               # fake tipado del puerto ServiceLayerPort (compartido)
│   ├── services.test.js          # casos de uso con cliente fake (anti-inyección)
│   ├── metadataService.test.js   # descubrimiento y acciones con fake
│   ├── sqlService.test.js        # SQL solo-lectura (rechazos, Service Not Found)
│   └── tools.test.js             # integración MCP in-memory (registro y llamadas)
├── .gitignore
└── README.md

Адаптация к реальной схеме (проверено на ServiceLayer 10.0 v1)

Сервер динамически адаптируется к $metadata каждого экземпляра, ничего не захардкожено. Проверенные факты на реальном экземпляре (v1, OData v3):

  • Entity sets разделяют EntityType: Orders/Invoices/DeliveryNotesSAPB1.Document. sap_get_entity_schema автоматически разрешает реальный тип.

  • Строки документа: в v1 это complex collections (DocumentLines, DocumentInstallments), которые приходят inline в ответе; $expand применяется только к navigationProperties (схема их перечисляет, напр.: BusinessPartner, Currency).

  • Финансовые поля: в v1 BusinessPartners не имеет Balance; используйте CurrentAccountBalance, OpenOrdersBalance, OpenDeliveryNotesBalance. В счетах нет BalanceDue: открытый баланс — это DocTotal − PaidToDate.

  • Нет ItemStock и /sql_query в старых v1: sap_get_stock уведомляет с реальными обнаруженными сущностями остатков; sap_sql_query возвращает понятную ошибку.

  • Function imports v3 с IsBindable="true" перечисляются как bound (не вызываемые отдельно), чтобы не загрязнять sap_list_actions.

Рецепт: отчет по срокам давности остатков (30/60/90)

Без SQL, только с sap_query (работает на любых v1/v2):

  1. Открытые счета (разбивайте с skip партиями ≤200, если их много):

    sap_query('Invoices',
      filter='PaidToDate lt DocTotal',
      select='CardCode,CardName,DocNum,DocDate,DocDueDate,DocTotal,PaidToDate,DocumentStatus,ControlAccount')
  2. Для каждого счета: остаток = DocTotal − PaidToDate; дней = сегодня − DocDueDate.

  3. Сгруппируйте по диапазонам 0-30 / 31-60 / 61-90 / 90+ и по клиенту (или по ControlAccount для вида по бухгалтерскому счету).

  4. Итоги по клиенту/счету: sap_get_business_partners с CurrentAccountBalance (текущий остаток) и CreditLimit.

С помощью sap_sql_query (v2) этот же отчет выполняется одним запросом по OINV/OINV3/OFRJ/OCRD.

Разработка

npm install     # dependencias
npm test        # tests (node:test)
npm run typecheck  # verificación de tipos estricta (tsc --noEmit sobre JSDoc)
npm start       # arranque local (requiere variables de entorno)

Весь код JS проверяется строгим TypeScript через JSDoc (checkJs + strict + noUncheckedIndexedAccess): tsconfig.json без шага сборки, сервер запускается напрямую с помощью node.

Ручная проверка (JSON-RPC через stdio)

echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | \
  SAP_B1_SERVER_URL=... SAP_B1_DATABASE=... SAP_B1_USERNAME=... SAP_B1_PASSWORD=... \
  npx -y github:leonardows1/sap-b1-servicelayer-mcp
F
license - not found
Not graded
quality - not tested
B
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
    D
    maintenance
    Enables AI assistants to integrate with SAP systems via OData REST APIs for querying entity sets, performing CRUD operations, and executing function imports. It features automatic service discovery, CSRF token management, and smart connection handling without requiring the SAP RFC SDK.
    11
    12
  • F
    license
    A
    quality
    C
    maintenance
    Enables interaction with SAP S/4HANA systems via OData, allowing service discovery, metadata exploration, field value retrieval, and CRUD operations through natural language.
    4
    5
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with SAP Business One via Service Layer REST API to retrieve and create business data such as partners, orders, invoices, items, and stock levels through natural language.
    1

View all related MCP servers

Related MCP Connectors

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

  • Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.

  • Connect your AI assistants to Keboola and expose your data, transformations, SQL queries, ...

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/leonardows1/sap-b1-servicelayer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server