SAP B1 ServiceLayer MCP Server
SAP B1 ServiceLayer MCP Server
用于将 AI 助手(opencode、Claude 等)连接到本地网络中的 SAP Business One 10.0 ServiceLayer 的 MCP(Model Context Protocol)服务器。可通过 npx 直接从此 GitHub 仓库运行,无需在 PC 上安装任何东西。
功能特性
默认只读:设置
SAP_B1_READONLY=true(默认)时,仅注册查询类工具(GET)。写入类工具(POST/PATCH/DELETE)在服务器上不存在,也无法被调用。完全发现:
sap_list_entities、sap_get_entity_schema和sap_list_actions查询GET /$metadata(每个进程仅下载一次并缓存),并公开 ServiceLayer 的约 140 个 CRUD 实体(包括用户表@和 UDO)以及数百个服务方法。可选写入模式:设置
SAP_B1_READONLY=false时,将为 ServiceLayer 实体启用sap_create、sap_update、sap_delete,并为服务方法启用sap_call_action(这些操作可能产生副作用)。通过
npx github:运行:无需手动安装。会话管理:使用
CompanyDB/用户名/密码隐式登录,B1SESSION+ROUTEIDcookie 保存在内存中(支持多节点 ServiceLayer),遇到401自动重新登录,并在进程关闭时保证注销(另有sap_logout工具)。自签名 TLS:通过
SAP_B1_VERIFY_TLS=false支持 ServiceLayer 的自签名证书(在本地环境中很常见)。无遥测、无外部调用:HTTP 客户端仅指向配置的 URL(
SAP_B1_SERVER_URL)。安全限制:每次查询的
top限制为 200 条记录。
Related MCP server: BTP MCP Server
工具
读取(始终可用)
工具 | 说明 |
| 对任意 OData 实体的通用 GET,支持 |
| 列出 ServiceLayer 暴露的所有 OData 实体(来自 |
| 实体的架构:属性(类型/键)以及 navigationProperties(可用于 |
| 列出服务方法(function imports,例如 |
| 通过 |
| 业务伙伴(客户/供应商),可按 |
| 目录中的物料 |
| 销售订单;在 v1 中行( |
| 按 |
| 当前会话的状态 |
| 显式关闭会话 |
写入(仅当 SAP_B1_READONLY=false 时)
工具 | 说明 |
| 在实体中创建记录( |
| 按键更新记录( |
| 按键删除记录( |
| 调用服务方法( |
要求
Node.js 18+
SAP Business One 10.0,并启用 ServiceLayer(典型路径
https://<host>:50000/b1s/v1)opencode(或任何 MCP 客户端)
配置(环境变量)
变量 | 必填 | 默认值 | 说明 |
| 是 | - | ServiceLayer 的基础 URL(例如: |
| 是 | - | CompanyDB 名称(例如: |
| 是 | - | ServiceLayer 用户 |
| 是 | - | 用户密码 |
| 否 |
| 设为 |
| 否 |
| 设为 |
| 否 |
| 每次查询 |
与 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)上验证的事实:
实体集共享 EntityType:
Orders/Invoices/DeliveryNotes→SAPB1.Document。sap_get_entity_schema会自动解析真实类型。文档行:在 v1 中是 复杂集合(
DocumentLines、DocumentInstallments),会内联在响应中;$expand仅适用于 navigationProperties(架构会列出这些属性,例如BusinessPartner、Currency)。财务字段:在 v1 中
BusinessPartners没有Balance;请使用CurrentAccountBalance、OpenOrdersBalance、OpenDeliveryNotesBalance。发票没有BalanceDue:未结余额为DocTotal − PaidToDate。旧版 v1 中没有
ItemStock或/sql_query:sap_get_stock会以发现的真实库存实体发出提示;sap_sql_query返回明确错误。v3 function imports 带有
IsBindable="true"的会被列为bound(不能独立调用),以免污染sap_list_actions。
配方:余额账龄报告(30/60/90)
无需 SQL,仅使用 sap_query(适用于任何 v1/v2):
未结发票(如果很多,使用
skip按 ≤200 条分批翻页):sap_query('Invoices', filter='PaidToDate lt DocTotal', select='CardCode,CardName,DocNum,DocDate,DocDueDate,DocTotal,PaidToDate,DocumentStatus,ControlAccount')对每张发票:
saldo = DocTotal − PaidToDate;días = hoy − DocDueDate。按 0-30 / 31-60 / 61-90 / 90+ 区间和客户分组(或按
ControlAccount查看总账科目视图)。按客户/科目的合计:
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 代码均通过 JSDoc 使用严格 TypeScript 检查(checkJs + strict + noUncheckedIndexedAccess):tsconfig.json 无需构建步骤,服务器直接用 node 运行。
手动验证(通过 stdio 的 JSON-RPC)
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-mcpThis server cannot be installed
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
- FlicenseAqualityDmaintenanceEnables 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.1112
- AlicenseAqualityCmaintenanceConnects AI agents to SAP BTP platform APIs for service discovery, instance management, and destination queries via natural language.51MIT
- FlicenseAqualityCmaintenanceEnables interaction with SAP S/4HANA systems via OData, allowing service discovery, metadata exploration, field value retrieval, and CRUD operations through natural language.45
- FlicenseNot gradedqualityDmaintenanceEnables 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
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, ...
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/leonardows1/sap-b1-servicelayer-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server