Skip to main content
Glama
glauberbessa

SAP Business One MCP Server Sample

by glauberbessa

SAP Business One MCP Server Sample


简介

作为 SAP Business One 10.0 FP2608 的一部分,我们提供了一个 SAP Business One MCP Server 示例,用于演示如何将 SAP S1 Service Layer OData 服务暴露为支持模型上下文协议(MCP)的 AI 代理的动态工具。

该示例服务器设计得精简且易于理解,同时充分展示了 MCP 服务器的核心模式与能力。与注册数百个独立的 CRUD 工具(每个实体 × 操作各一个)不同,该服务器采用渐进式发现架构,将数百个潜在工具收敛为几个智能、可复用的工具。

这种设计使 AI 助手能够:

  • 通过轻量级的语义搜索发现相关 B1 实体

  • 理解实体的完整架构,包括属性、类型和各类能力

  • 在自动生成 OData 查询的辅助下,执行经过认证的 CRUD 操作

诸如 "显示余额最高的前 10 个客户""为供应商 V00001 创建采购订单" 之类的自然语言请求,会自动转换为适用的 Service Layer API 调用。

本项目仅作参考参考和学习用途的示例提供, 并非生产级产品。我们鼓励 SAP B1 合作伙伴和开发者研究此架构、调整代码、发挥内置能力,并根据自身业务需求和部署环境构建自己的 MCP 服务器实现。

版本要求: 此 MCP 服务器要求 SAP Business One 10.0 FP2608 或更高版本。它依赖 FP2608 中新增的 Service Layer API。在更低版本上运行会出现异常,无法正常工作。

MCP 协议版本: 本示例实现了 2025-11-25 版本的 MCP 协议,这是 SAP Business One 10.0 FP2608 所对应的模型上下文协议规范的最新版本。连接到此服务器的 MCP 客户端也必须支持协议版本 2025-11-25。随着 MCP 协议不断演进,本示例也会持续更新,以跟进新规范版本的发布。


Related MCP server: SAP OData MCP Server

架构总览

MCP 服务器位于 AI 代理(Cline、GitHub Copilot、Cursor 等)与 SAP B1 Service Layer 之间。 SAP Business One MCP Server a 采用现代分层架构,将 OData 服务契约转化为 AI 友好的 MCP 工具。这一架构围绕“渐进式发现模式”展开,力求在 Token 开销与全面能力暴露之间取得平衡。

arch.svg

在该架构中,AI 代理中的 MCP 客户端与 MCP 服务器通过实现 MCP 协议的安全 HTTP 传输层进行交互。在身份认证方面,MCP 服务器依托 Keycloak 使用 OAuth2。MCP 客户端或 AI 代理通过 Extension SSO Manager 注册为 OAuth 客户端,并经标准的 OAuth2 流程获得访问令牌。借助该令牌,客户端可以选择性从 SLD 获取公司列表,从而在请求中携带正确的公司上下文。服务器对每个 Client 请求进行校验:它将 Bearer 令牌与 Keycloak 核对,确保只有通过认证的客户端才能访问 MCP 工具;同时还会检查 audience 声明,确保该令牌是签发指向此服务器发给本服务器的。


可用的 MCP 工具

重要提醒: Tools 供 AI 模型使用,”下令牌使用“,工具名称、参数,行为都可能随版本变化。请勿对任何特定工具签名建立硬编码依赖。

核心发现与执行工具

服务器采用的是 4 个核心发现/执行工具,而不是逐个注册数百个 CRUD 工具:

工具

描述

参数

b1_find_entities

第 1 步:按业务类别和可选名称筛选条件搜索 SAP Business One Service Layer 实体。返回最简列表(entityName、categories)。如果没有找到匹配项,则返回全部实体。接下来使用 b1_get_entity_schema 获取所选实体的完整架构。可使用 category='workflow' 来发现可用的工作流辅助工具及其描述。

- category(可选):业务领域筛选条件。默认值:'all'。- query(可选):实体名称的搜索词- limit(可选):返回的最大结果数(最小:1,最大:50,默认:20)

b1_get_entity_schema

第 2 步:获取 SAP B1 实体的架构。第 2.1 步:使用 entityName 调用——返回所有属性和结构(复杂)类型。第 2.2 步(可选):使用 entityName + structuralTypeName 调用,深入查看复杂类型的子属性。第 2.1 步必须先对同一实体调用。

- entityName(必填):来自 b1_find_entities 结果的 B1 实体名称(区分大小写,如 "BusinessPartners")- structuralTypeName(可选,仅第 2.2 步):使用第 2.1 步结果中 structuralProperties 条目中的 complexTypeName。示例:' DocumentLine'

b1_read

第 3a 步:对 SAP B1 Service Layer 实体执行读操作。请先调用 b1_get_entity_schema 确认字段名称和键属性。支持 read 进行列表查询,也支持 read-single 按键读取单个实体。

- entityName(必填):实体名称- operation(必填):readread-single- parameters(可选):read-single 的键字段(例如 { DocEntry: 1 });列表读取时省略- filterString(可选):OData $filter 查询- selectString(可选):OData $select 选择特定字段- orderbyString(可选):OData $orderby 排序- topNumber(可选):要返回的记录数- skipNumber(可选):要跳过的记录数(分页)

b1_write

第 3b 步:对 SAP B1 Service Layer 实体执行写操作:创建、更新和删除。执行前需要征得确认。

- entityName(必填):实体名称- operation(必填):createupdatedelete- parameters(必填):以扁平对象表示的实体数据。create:仅 body 字段。update:键字段 + 要更改的字段(处理器会自动拆分)。delete:仅键字段

Progressive 3-Step Discovery

服务器通过将所有内容转换为 3 步流程来避免工具数量爆炸:

Step 1: b1_find_entities        → Lightweight semantic search; returns entity names and categories
Step 2: b1_get_entity_schema    → Full schema for a selected entity (properties, types, keys)
Step 3: b1_read / b1_write      → Execute the read or write operation with schema-informed parameters
  • Token 效率:第 1 步返回的架构数据比完整 schema 少约 90%

  • 清晰分离:LLM 可以在提交完整架构获取之前先扫描和选择

  • 渐进式细节:可以通过第 2.2 步调用深入查看复杂类型,而无需先获取所有内容

公司选择工具

在 OAuth 模式下,在调用实体工具之前,先选择一家公司:

工具

描述

参数

b1_list_companies

OAuth 第 0 步:返回可用的 SAP B1 公司列表。返回:CompanyID、CompanySchemaName、CompanyName、Status。接下来使用 b1_select_company,并传入 CompanySchemaName

b1_select_company

OAuth 第 1 步:为所有后续请求选择当前活跃的 SAP B1 公司。可选地获取详细公司信息(版本、本地化等)。下一步:使用 b1_find_entities 搜索可用实体。

- companySchemaName(必填):来自 b1_list_companies 的公司架构名称(例如 'SBODEMOUS')- getDetails(可选):获取详细公司信息。默认值:false

工作流辅助工具

两个可帮助简化常见 B1 业务流程的工作流工具:

工具

说明

参数

b1_copy_document

通过复制现有的源单据来创建新销售单据,自动解析 BaseType、BaseEntry 和 BaseLine 引用。支持标准 B1 流程:订单→发货、发货→发票、订单→发票。

- sourceEntityName(必填):源实体(例如 "Orders"、"DeliveryNotes")- sourceDocEntry(必填):源单据的 DocEntry- targetEntityName(必填):要创建的目标实体(例如 "DeliveryNotes"、"Invoices")- lineSelections(可选):要复制的从零开始的行索引;省略则复制所有行- additionalFields(可选):要添加/覆盖的单据头字段

b1_create_payment

验证并为一个或多个 A/R 发票创建收款。获取未清余额,并自动(最早优先)或手动分配收款,然后过账。

- cardCode(必填):业务伙伴代码- invoiceDocEntries(必填):发票 DocEntry 值数组- paymentAmount(必填):分配的总收款项- allocationType(可选):automanual(默认:auto- manualAllocations(可选):当 allocationType=manual 时必填;按发票分配金额- transferAccount(可选):总/行/G/L 转账科目- transferDate(可选):付款日期(YYYY-MM-DD- transferReference(可选):付款参考/支票号- remarks(可选):付款备注- validateOnly(可选):若为 true,仅验证不计费。默认是:false(验证并过账)

在运行时运行发现工作流辅助工具:

Show me what workflow tools are available in the B1 MCP server

AI 代理使用 category: 'workflow' 调用 b1_find_entities,并收到 b1_copy_documentb1_create_payment 的完整描述。

MCP 资源

两种资源类型无需工具调用即可提供上下文知识:

资源 URI 模式

说明

b1://service-layer/metadata

服务层(Service Layer)的服务和实体元数据。

b1://constants/{type}

参考数据,包括 objectTypes、documentFlows、fieldPatterns、statuses、paymentTypes 以及 all。示例:b1://constants/objectTypes

优势:AI 助手无需调用工具即可即时访问这些资源——对工作流来说更高效!


前置条件

要求

最低版本

Node.js

22.22.3

npm

10.9.8

SAP B1 Service Layer

FP2608

SAP B1 Identity and Authentication Management (IAM-Keycloak)

FP2608

SAP B1 System Landscape Directory (SLD)

FP2608


安装

  1. 从联机帮助中心下载此包 b1-mcp-server.zip,解压缩,然后进入解压后的项目文件夹。

  2. 安装依赖并编译:

npm install
npm run build

配置

所有设置均通过项目根目录下的 .env 文件控制。请复制 .env.example 作为起点:

cp .env.example .env

如需查看每个可用变量的完整参考,请参阅配置参考章节。

直连模式(仅限开发环境)

当 SAP B1 Service Layer 可通过用户名和密码访问时,可使用此模式。仅适用于本地开发环境中的快速原型测试和测试。

注意: 尽管在 .env 文件中使用了用户名和密码,但这不是 HTTP 基本认证。这些凭据是 MCP 服务器通过 SAP B1 Service Layer 的登录 API(/b1s/v2/Login)获取会话令牌所用的,后续的所有请求都使用该会话令牌进行身份验证。

NODE_ENV=development
AUTHENTICATION_MODE=direct

# B1 Service Layer host (server appends /b1s/v2/ internally)
SERVICE_LAYER_ROOT_URL=https://servicelayer.b1.example.com:50000

B1_COMPANY_DB=yourCompanyDB
B1_USERNAME=yourUsernameHere
B1_PASSWORD=yourPasswordHere

# Accept self-signed certs for local development/testing only
AUTH_ALLOW_SELF_SIGNED=true

OAuth 模式(生产环境,默认)

Service Layer 始终由 Keycloak 代理,因此使用此默认模式。在转发任何 B1 请求之前,都会先向 OAuth 提供方验证传入的 bearer 令牌。

# Default mode, validate incoming requests via OAuth 2.0 / OIDC (requires OAUTH_BASE_URL and OAUTH_CLIENT_ID)
AUTHENTICATION_MODE=oauth

SERVICE_LAYER_ROOT_URL=https://servicelayer.b1.example.com:50000
SLD_ROOT_URL=https://sld.b1.example.com:40000

OAUTH_BASE_URL=https://keycloak.b1.example.com/auth/realms/sapb1/
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-client-secret

HTTPS / 传输协议

服务器默认使用 HTTPS,并在本地开发时使用自签名证书。您也可以根据偏好切换为 HTTP。

HTTPS(默认):

HTTPS_ENABLED=true
HTTPS_KEY_PATH=./certs/server.key
HTTPS_CERT_PATH=./certs/server.crt
PORT=3000

# Optional:
# HTTPS_CA_PATH=./certs/ca.crt
# HTTPS_PASSPHRASE=your-cert-passphrase

HTTP:

如果您出于本地测试、避免浏览器安全警告等其它原因(例如您已经有了现成的 HTTPS 网关或反向代理)希望用 HTTP 代替 HTTPS,请设置:

HTTPS_ENABLED=false
PORT=3000

对外公布的公共 URL(MCP_BASE_URL):

默认情况下,服务器根据当前监听设置推导出公布的 URL。如果服务器位于反向代理后面,或者您需要客户端针对 OAuth 元数据和 MCP 端点使用特定的基础 URL,请显式设置:

MCP_BASE_URL=https://mcp.example.com

本地开发时不用设置——服务器会自动推断正确的 URL。


运行服务器

启动服务器:

npm start

验证服务器是否正在运行:

curl http://localhost:3000/health

服务器提供三个内置的 REST 端点:

端点

说明

GET /health

存活检查——返回状态、版本和组件健康

GET /mcp

服务器元数据——协议版本、能力、活动会话

GET /docs

简要 API 参考——端点、MCP MCP 能力、用法提示

OAuth 提示: 在 OAuth 模式下,GET /mcp 需要在 Authorization 请求头中提供有效的 bearer 令牌。

GET /health — 示例响应:

{
  "status": "healthy",
  "timestamp": "2026-06-17T03:50:58.338Z",
  "version": "1.0.0",
  "checks": {
    "auditLogger": { "healthy": true },
    "personalFieldCache": { "healthy": true }
  }
}

GET /mcp — 示例响应:

{
  "name": "b1-mcp-server",
  "version": "1.0.0",
  "protocol": { "version": "2025-11-25", "transport": "streamable-http" },
  "capabilities": { "tools": {}, "resources": {}, "logging": {} },
  "features": [
    "Dynamic SAP Business One Service Layer OData service discovery",
    "CRUD operations for all discovered entities",
    "Natural language query support",
    "Session-based HTTP transport",
    "Real-time service metadata"
  ],
  "endpoints": { "health": "/health", "mcp": "/mcp", "docs": "/docs" },
  "activeSessions": 1
}

连接 AI 客户端

服务器在以下位置暴露了 Streamable HTTP MCP 端点:

http(s)://<host>:<port>/mcp

任何支持 MCP 的 AI 客户端都可以连接到该端点。下表对受支持的客户端的主要功能进行了汇总:

客户端

传输类型

MCP Elicitation

OAuth / PKCE

Cline(VS Code)

streamableHttp

不支持(v4.0.8)

内置 PKCE 流程

GitHub Copilot(VS Code)

http

支持

内置 PKCE 流程

Goose(桌面)

streamable_http

支持

内置 PKCE 流程

MCP Elicitation 用于对写操作和敏感读取进行人工确认。如果您的客户端不支持该功能,请在 .env 中设置 MCP_HUMAN_CONFIRMATION_ENABLED=false,否则这些操作将被拒绝。详情请参阅人工确认 (MCP Elicitation)


Cline(VS Code)

有关安装步骤、LLM 提供方配置、OAuth/Keycloak 设置,以及覆盖所有 CRUD 操作和工作流工具的测试示例,请参阅 docs/B1_CLINE_INTEGRATION_GUIDE.md


GitHub Copilot(VS Code)

有关安装步骤、OAuth / Keycloak 设置、静态客户端 ID 配置、OAuth 公司选择流程和引导性测试示例,请参阅 docs/B1_GITHUB_COPILOT_INTEGRATION_GUIDE.md


Goose(桌面)

有关安装步骤、配置选项、OAuth / Keycloak 设置和使用示例,请参阅 docs/B1_GOOSE_INTEGRATION_GUIDE.md


MCP Inspector(浏览器)

使用 MCP Inspector 可以交互式地浏览工具并检查原始 MCP 消息。完整的使用说明——包括如何在 OAuth 模式下获取 bearer 令牌和设置必要的请求头——请参阅 docs/MCP_INSPECTOR.md


MCP 客户端集成

如果您正在构建一个以 OAuth 模式连接服务器运行自定义 MCP 客户端,其集成流程遵循标准的 PKCE OAuth 2.0 流程:

  1. GET /mcp 发现 OAuth 元数据(服务器会公布其授权端点和令牌端点)。

  2. 发起一个 PKCE 授权请求,并将用户重定向到 Keycloak。

  3. 用授权码换取令牌(access token + refresh token)。

  4. 使用 b1_list_companies 获取可用公司列表。

  5. 让用户选择公司,然后调用 b1_select_company

  6. 在每一次 MCP 请求中都包含访问令牌和公司 ID:

    • Authorization: Bearer <access_token>

    • x-b1-companyID: <companySchemaName>

  7. 在令牌过期前刷新令牌;如果刷新失败,重新发起 PKCE 流程。

带有注释的、完整的可运行示例——包括客户端注册、OAuth 流程、公司选择、以及预期输出——请参阅 docs/SIMPLE_MCP_CLIENT.md


人工确认(MCP Elicitation)

MCP Elicitation 是一种协议级机制,它允许 MCP 服务器在工具调用执行中暂停,并要求已连接的客户端在继续之前提供额外的输入或确认。与简单的提示不同,Elicitation 内置于 MCP 协议中:服务器发送一个结构化的结构化请求给客户端,客户端以提示(通常是内联对话框或表单)的形式呈现给用户,服务器在决定继续或中止之前等待响应。这样,在关键操作时用户仍能保持知晓,但不必依赖 AI 代理临时充当自己的确认机制。

MCP_HUMAN_CONFIRMATION_ENABLED=true(默认)时,服务器在以下操作前暂停:

  • 写入操作createupdatedelete)——等待用户显式批准

  • 敏感读取——当查询选择了被分类为个人数据的字段(电子邮件、电话、身份证号)时,发出提示

支持 Elicitation 的客户端(如 GitHub Copilot)显示一个内联确认对话框。必须用户确认后服务器才继续;拒绝则会取消操作,不修改任何数据。

写入确认提示示例:

CONFIRM WRITE OPERATION | OPERATION: update | ENTITY: BusinessPartners |
TARGET: C00001 | FIELDS: Phone1=+1 555-1234 |
RISK: This action will modify SAP Business One data. |
ACTION: Set confirmed=true only if you intend to continue.

不支持 Elicitation 的客户端(如 Cline v4.0.8):

服务器会直接拒绝敏感读取和写入操作,而不会在没有确认的情况下进行处理。若在自动化流水线或开发环境中绕过,可设置:

MCP_HUMAN_CONFIRMATION_ENABLED=false

个人数据分类

服务器通过 PersonalFieldsSetupsService_GetPersonalFieldsByTable 使用 SAP Business One 的 PersonalFieldsSetups 元数据(按表解析)对敏感字段进行分类,并在读写操作中实施保护。

字段分类方式

  • 分类来源:Service Layer 表作用域内的 personal-field 条目,这些条目由 PersonalFieldsSetupsService_GetPersonalFieldsByTable 返回。

  • 匹配规则:当一个属性的表名 + 字段名与 PersonalFieldsSetups 中的某行匹配时,该属性被标记为 personal。

  • 范围:分类同时适用于实体的顶层属性和嵌套的复杂类型属性。

  • 嵌套解析:对于复杂属性,表上下文将按子表映射切换,并继续递归处理更深层的嵌套。

分类体现在哪里

  • 在通过 b1_get_entity_schema 获取的 schema 输出中,个人属性会以 isPersonalField 标记。

  • 这包括标量字段,以及当表映射将其标记为 personal 时的嵌套结构化类型属性。

运行时保护

MCP_HUMAN_CONFIRMATION_ENABLED=true 时:

  • 写入操作(create、update、delete)需要显式的 MCP Elicitation 确认。

  • 当 selectString 明确包含顶层的个人字段时,敏感读取需要确认。

如果客户端不支持 MCP Elicitation,这些受保护的保护功能操作将被阻止。

读取结果的编修行为

读取结果的编修取决于 selectString 是否有意义:

  • 没有 selectString(或为空白/空格):对顶层和嵌套的复杂数据中的个人字段进行递归的全响应编修。

  • 有意义的 selectString 并且只选择标量子字段:按请求返回所选的标量。

  • 有意义的 selectString 且包含复杂属性:所选的标量保持可见,而对于选定的复杂属性,内部的个人字段仍会被递归编修。

这意味着:经过用户确认后,顶层的个人标量字段可以被看到,而对于所选的复杂属性,其嵌套的个人字段仍然被编除。

关于个人数据配置的更多详情,请参阅此链接:关于个人数据保护


UDO/UDT/UDF 支持

服务器会自动发现并处理 User-Defined Objects (UDO)User-Defined Tables (UDT) 与标准 SAP B1 实体并存的 User-Defined Fields (UDF) 组件,无需额外配置。

  • 在 SAP B1 中注册的 UDO 会以可查询、可写实体出现 b1_find_entities 中,可在其分类业务类型下发现。

  • *UDT 会以自定表(以 @ 开头)作为一级实体出现,并支持与标准实体相同的 CRUD 操作。

  • UDF 会自动包含在由 b1_get_entity_schema 返回的 schema 中,并具有正确的类型和元数据。

这意味着在 SAP B1 中进行的任何定制 — 合作伙伴扩展、本地化加载项或客户自定义字段 —— 都可以通过同一步的 3 步发现流程立即提供给 AI 代理使用,而无需进行任何服务器端更改。

UDO 命名

UDO 代码必须遵循 OData 标识符规则,才能被 Service Layer 识别。只能使用字母、数字和下划线 — 不能包含空格或其他特殊字符(如 MY_CUSTOM_OBJECT,而不能 My Custom Object)。对于命名不符合规则的 UDO,将无法被发现。

Discovery Delay

通过 SAP B1 客户端、Web 客户端或增强包添加或修改的 UDO 和 UDT、不会立即在 MCP 服务器中反映。服务器会缓存从 Service Layer 获取的 OData 元数据,缓存时间可配置(默认值:30 分钟,由 METADATA_CACHE_TTL_MINUTES 控制)。新的或更改的 UDO/UDT 只有在缓存自然过期后,或 MCP 服务器重新启动后才会变为可被发现。在自定义对象开发的过程中,可将 METADATA_CACHE_TTL_MINUTES 降低为较小的值(例如 5),以更快获取更改。


多想/多租户支持

单个 MCP 服务器实例可以无需任何配置更改即可为多个 SAP Business One 公司提供服务。在 OAuth 模式下,活动租户或公司通过 System Landscape Directory (SLD) 在运行时动态选择。

工作原理:

  1. MCP 客户端调用 b1_list_companies 来检索 SLD 中注册的所有可用公司及其状态。

  2. 用户(或由用户指导的 AI 代理)选择目标公司,调用 b1_select 组件"。

  3. 会话期间,所有后续工具调用(b1_find_entitiesb1_readb1_write 等)都会路由到所选公司的 Service Layer 数据库。

  4. 如需切换公司,可再次使用不同的 schema 名称调用 b1_select_company — 无需服务器重新启动。

关键特性:

  • 会话作用域: 公司选择绑定到 MCP 会话。不同的 AI 客户端会话可以同时针对不同的公司,在同一个服务器实例上。

  • SLD 驱动: 公司列表直接来自 SLD,反映注册公司的实时状态。无需在配置中维护静态公司列表。

  • 仅 OAuth 模式: 该切换机制需要 OAuth 模式。直接模式仅限于单公司(B1_COMPANY_DB.env 中固定)。

注意: 如果请求中已存在有效的的 x-b1-companyID 标头,MCP 服务器将直接使用它 — 无需调用 b1_list_companiesb1_select_company。这些工具的目的只是为了帮助 AI 代理或用户确定正确的公司 schema 名称,并在公司上下文尚未确定时建立上下文。一旦知道了目标公司,就可以将其公司 ID(由 CompanySchemaName 解析得到)直接传递给后续每个 MCP 请求的 x-b1-companyID 标头。


使用示例

自然语言查询

自然语言

工具调用

Generated Parameters

"显示 10 个销售订单"

b1_read

{ entityName: "Orders", operation: "read", topNumber: 10 }

"获取销售订单 DocEntry 12345"

b1_read

{ entityName: "Orders", operation: "read-single", parameters: { DocEntry: 12345 } }

"查找订单总额超过 1000 的记录" ( DocTotal > 0)

b1_read

{ entityName: "Orders", operation: "read", filterString: "DocTotal gt 1000" }

"为供应商 V00001 创建采购订单"

b1_write

{ entityName: "PurchaseOrders", operation: "create", parameters: { CardCode: "V00001" } }

"更新业务伙伴 C00001 的电话号码"

b1_write

{ entityName: "BusinessPartners", operation: "update", parameters: { CardCode: "C00001", Phone1: "123-456-7890" } }

注意:上一行是原列表的扩展,不应在输出中出现。我们再根据原始表展开:

自然语言

工具调用

生成的参数

"显示 10 个销售订单"

b1_read

{ entityName: "Orders", operation: "read", topNumber: 10 }

"获取 DocEntry 为 12345 的销售订单"

b1_read

{ entityName: "Orders", operation: "read-single", parameters: { DocEntry: 12345 } }

"查找超过 1000 美元的销售订单"

b1_read

{ entityName: "Orders", operation: "read", filterString: "DocTotal gt 1000" }

"为供应商 V00001 创建采购订单"

b1_write

{ entityName: "PurchaseOrders", operation: "create", parameters: { CardCode: "V00001" } }

"更新业务伙伴 C00001 的电话号码"

b1_write

{ entityName: "BusinessPartners", operation: "update", parameters: { CardCode: "C00001", Phone1: "123-456-7890" } }


工作流示例

要实施其他业务工作流或添加新的 MCP 工具,请参阅 docs/DEVELOPER_GUIDE.md

基本 CRUD 工作流

1. b1_find_entities → "BusinessPartners"
  ↓ Returns: List of matching entities

2. b1_get_entity_schema → "BusinessPartners"
  ↓ Returns: scalar properties plus structuralProperties[]

3. b1_get_entity_schema → "BusinessPartners", structuralPropertyName="ContactEmployees"
  ↓ Returns: sub-properties for that structural property when needed

4. b1_read or b1_write → execute the selected operation
   ✓ Executes operation with proper parameters

订单到收款工作流(分步)

1. b1_write → Create Sales Order
   ↓ Returns: DocEntry 123

2. b1_copy_document → Order → Delivery
   ↓ Returns: DocEntry 456 (automatic BaseType handling)

3. b1_copy_document → Delivery → Invoice
   ↓ Returns: DocEntry 789 (automatic BaseType handling)

4. b1_create_payment → Create Payment
   ✓ Validates and creates payment (automatic balance checking)

商业智能查询

User: "Show me top 10 customers by balance"
→ Tool: b1_read
→ Parameters:
  {
    "entityName": "BusinessPartners",
    "operation": "read",
    "filterString": "CardType eq 'cCustomer'",
    "orderbyString": "CurrentAccountBalance desc",
    "topNumber": 10
  }
User: "How many open sales orders are there?"
→ Tool: b1_read
→ Parameters:
  {
    "entityName": "Orders",
    "operation": "read",
    "filterString": "DocumentStatus eq 'bost_Open'",
    "selectString": "DocEntry"
  }

数据操作

User: "Update supplier V10000 to have phone number 123-456-7890"
→ Tool: b1_write
→ Parameters:
  {
    "entityName": "BusinessPartners",
    "operation": "update",
    "parameters": {
      "CardCode": "V10000",
      "Phone1": "123-456-7890"
    }
  }

测试服务器

单元测试

npm test

这是 npm run test:unit 的别名。单元测试位于 src/tests/unit/ 下。

集成测试

集成测试要求 MCP 服务器正在运行,并且可以访问 Service Layer 和 OAuth 提供方。它们还要求在 Keycloak 中配置 b1_mcp:access scope — 请参阅 KEYCLOAK_SETUP.md 以获取设置说明。在 .env 中配置测试客户端的凭据,然后运行:

npm run test:integration

集成测试的关键变量:

变量

描述

TEST_MCP_CLIENT_ID

测试运行程序使用的 OAuth 客户端 ID

TEST_OAUTH_SCOPES

要请求的作用域(例如 email b1_mcp:access profile)(例如 email b1_mcp:access profile

TEST_OAUTH_INTERACTIVE

设置为 true 以在测试期间触发基于浏览器的登录

集成测试位于 src/tests/integration/ 下。

注意: 如果更新依赖后测试失败,请先运行 npm run build — 编译时错误通常会先于测试运行器出现。

完整质量检查

按顺序运行 lint、build 和单元测试:

npm run lint
npm run build
npm test
npm run test:integration

日志

服务器产生两个独立的日志流,每个日志流都可单独配置。

应用程序日志

应用程序日志涵盖请求处理、工具分配、会话生命周期以及 Service Layer 调用。默认级别为 info。开发时启用详细日志以跟踪服务器的操作:

APP_LOG_LEVEL=debug
APP_LOG_CONSOLE_ENABLED=true

日志默认以旋转文件形式写入(APP_LOG_FILE_ENABLED=true).文件大小和保留时间分别由 APP_LOG_MAX_SIZE_BYTES(默认 10 MB)和 APP_LOG_RETENTION_DAYS(默认 90 天)控制。

审计日志

审计日志记录与安全相关的事件:写入确认、会话开始和过期,以及身份验证失败。默认情况下写入滚动文件,并应在生产环境中保持启用。

要在开发过程中将审计事件同时输出到控制台:

AUDIT_LOG_CONSOLE_ENABLED=true

文件 size 和保留时间由 AUDIT_LOG_MAX_SIZE_BYTES(默认 10 MB)和 AUDIT_LOG_RETENTION_DAYS(默认为 365 天)控制。

有关日志变量的完整列表,请参阅 docs/CONFIGURATION_REFERENCE.md

有关 OAuth 模式所需的分步 Keycloak 配置 — 包括 MCP 服务器客户端注册、客户端作用域、audience mapper 和受信任主机 — 请参阅 docs/KEYCLOAK_SETUP.md


安全注意事项

注意: 这是一个示例项目。在部署到生产环境之前,请根据您所在机构的安全标准和合规要求,审查并强化所有安全设置。

认证

该 MCP 服务器扮演 OAuth 2.0 框架中的 Resource Server (RS),并采用标准的 MCP 认证机制。AI 代理的每个请求都必须携带有效的 Bearer 访问令牌;服务器在处理任何请求之前都会验证该令牌。

访问令牌通过向 SAP Business One Identity and Authentication Management 服务提供有效用户凭据来获取。该服务基于 Keycloak 构建,并可配置为连接 SAP USB(身份验证服务)或其他身份提供方以进行用户身份认证。

授权

授权在两个层级强制执行:

第一层 — MCP 服务器:检查访问令牌的 scopeaud(audience)声明,以确定 AI 代理是否被允许调用所请求的 MCP 工具。只有携带必需的 b1_mcp:access 作用域且目标为当前服务器的令牌才会被接受。

第二层 — SAP B1 Service Layer:将数据访问决策委托给 Service Layer,它根据令牌关联的用户角色和权限,结合标准 SAP Business One 访问控制模型进行评估。管理员可以为每个用户和组定义细粒度的访问策略。如果 Service Layer 返回 HTTP 403(禁止),MCP 服务器将向 AI 代理返回错误,指出权限不足,不返回任何数据。

生产环境配置

在部署到生产环境前审查以下设置。

传输安全

  • HTTPS_ENABLED — 默认为 true. 生产环境务必使用 HTTPS。只有在 TLS 终止反向代理之后才可关闭。

  • AUTH_ALLOW_SELF_SIGNED — 默认为 false. 生产环境中切勿开启;请使用有效 CA 或 NODE_EXTRA_CERTS.

令牌验证

  • TOKEN_VALIDATION_MODE — 生产环境中使用 introspectionintrospection-with-jwt-fallback(默认),避免 jwt 模式,除非令牌是安全的(<5 分钟),因为已撤销的令牌在过期之前仍然有效。

  • VALIDATE_AUDIENCE — 默认为 true。禁用后,令牌接受用于其他软件的服务;只有当 OAuth 提供方无法限制 aud 声明时才禁用。

  • OAUTH_VERIFY_SCOPES / OAUTH_REQUIRED_SCOPES — 维护 scope 验证,并限制为最小需求作用域 (b1_mcp:access).

网络与访问控制

  • MCP_ALLOWED_HOSTS — 列出服务器可访问的所有域名地址。Host 头不匹配的请求将被拒绝(DNS 重绑定保护)。

  • REQUEST_BODY_LIMIT — 保持较小(默认 1mb)以限制内存和减少 DoS 风险。

  • CORS_ALLOWED_ORIGINS — 除非基于浏览器的客户端需要,否则留空(CORS 已关闭)浏览器环境下。

  • MCP_RATE_LIMIT_WINDOW_MINUTES / MCP_RATE_LIMIT_MAX — 根据预期的客户端带宽进行调优。

会话与写入安全性

  • SESSION_TIMEOUT_MINUTES — 空闲会话将过期并记录审计日志。生产环境内采购较短超时(默认::30 分钟)。

  • MCP_HUMAN_CONFIRMATION_ENABLED — 默认为 true。任何写入前都必须要求用户。除非出于自动化、非交互式流水线,否则请勿关闭。

审计日志

  • AUDIT_LOG_FILE_ENABLED — 默认为 true。审计日志记录所有写入确认和会话事件。生产环境应保持启用,并通过 AUDIT_LOG_RETENTION_DAYS 满足合规要求。


故障排查

服务器或连接问题

  • 验证 Node.js 版本 >= 22.22.3(node --version),以及 npm run build 能否无错误结束。

  • 检查 SERVICE_LAYER_ROOT_URL 仅是主机,不能包含 /b1s/v2/ 路径(例如显示 https://servicelayer.b1.example.com:50000)。

  • 确认服务器正在运行服务器:curl 到运行 curl http://localhost:3000/health.

  • 检查客户端配置中的 MCP 端点 URL 是否与服务器地址一致,如果工具没有出现,请重启 VS Code.

认证与公司上下文

  • 直接模式:验证 B1_COMPANY_DBB1_USERNAMEB1_PASSWORD.

  • OAuth 模式:验证 OAUTH_BASE_URLOAUTH_CLIENT_IDOAUTH_CLIENT_SECRETSLD_ROOT_URL。如果 Service Layer 使用自签名证书,可在 AUTH_ALLOW_SELF_SIGNED=true 设置(仅限开发)。

  • 如果 VS Code 客户端报 Failed to verify remote host,或检查 Keycloak 的可信主机 — 参见 docs/KEYCLOAK_SETUP.md.

  • 在 OAuth 模式下,始终在调用任何实体工具之前调用 b1_list_companies,然后调用 b1_select_company。如果没有选择,公司将不会返回 SAP B1 数据。

实体、字段或写入问题

  • 使用 b1_find_entities 确认正确的实体名称(区分大小写),并使用 b1_get_entity_schema 在构建 filter 或 select 字符串之前验证属性名。

  • 如果写操作被拒绝且 MCP_HUMAN_CONFIRMATION_ENABLED=true,客户端必须支持 MCP Elicitation。可以使用 GitHub Copilot,或在自动化流水线中设置 MCP_HUMAN_CONFIRMATION_ENABLED=false

启用调试选项

启用详细日志记录以追踪请求处理和 Service Layer 调用:

APP_LOG_LEVEL=debug
APP_LOG_CONSOLE_ENABLED=true
AUDIT_LOG_CONSOLE_ENABLED=true

配置参考

有关按类别(身份验证、HTTPS、OAuth、会话、缓存、日志记录)分组的环境变量完整列表,请参阅 docs/CONFIGURATION_REFERENCE.md


局限

  • 不支持 stdio 传输。仅支持 streamable HTTP。

  • 当前 MCP server 示例不支持 OData actions/functions。仅提供对实体的标准 CRUD 操作。

  • 当前 MCP server 示例不支持附件/图片上传/下载。

  • 当前 MCP server 示例不支持 OData batch 操作。每个实体操作必须单独执行。

  • 高级 OData 查询未完全支持。MCP tools 中仅实现了基本的 $filter$select$top$orderby

A
license - permissive license
Not graded
quality - not tested
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
    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

View all related MCP servers

Related MCP Connectors

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/glauberbessa/mcpserverforsapb1'

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