SAP Business One MCP Server Sample
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 开销与全面能力暴露之间取得平衡。
在该架构中,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 工具:
工具 | 描述 | 参数 |
| 第 1 步:按业务类别和可选名称筛选条件搜索 SAP Business One Service Layer 实体。返回最简列表(entityName、categories)。如果没有找到匹配项,则返回全部实体。接下来使用 | - |
| 第 2 步:获取 SAP B1 实体的架构。第 2.1 步:使用 | - |
| 第 3a 步:对 SAP B1 Service Layer 实体执行读操作。请先调用 | - |
| 第 3b 步:对 SAP B1 Service Layer 实体执行写操作:创建、更新和删除。执行前需要征得确认。 | - |
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 parametersToken 效率:第 1 步返回的架构数据比完整 schema 少约 90%
清晰分离:LLM 可以在提交完整架构获取之前先扫描和选择
渐进式细节:可以通过第 2.2 步调用深入查看复杂类型,而无需先获取所有内容
公司选择工具
在 OAuth 模式下,在调用实体工具之前,先选择一家公司:
工具 | 描述 | 参数 |
| OAuth 第 0 步:返回可用的 SAP B1 公司列表。返回:CompanyID、CompanySchemaName、CompanyName、Status。接下来使用 | 无 |
| OAuth 第 1 步:为所有后续请求选择当前活跃的 SAP B1 公司。可选地获取详细公司信息(版本、本地化等)。下一步:使用 | - |
工作流辅助工具
两个可帮助简化常见 B1 业务流程的工作流工具:
工具 | 说明 | 参数 |
| 通过复制现有的源单据来创建新销售单据,自动解析 BaseType、BaseEntry 和 BaseLine 引用。支持标准 B1 流程:订单→发货、发货→发票、订单→发票。 | - |
| 验证并为一个或多个 A/R 发票创建收款。获取未清余额,并自动(最早优先)或手动分配收款,然后过账。 | - |
在运行时运行发现工作流辅助工具:
Show me what workflow tools are available in the B1 MCP serverAI 代理使用 category: 'workflow' 调用 b1_find_entities,并收到 b1_copy_document 和 b1_create_payment 的完整描述。
MCP 资源
两种资源类型无需工具调用即可提供上下文知识:
资源 URI 模式 | 说明 |
| 服务层(Service Layer)的服务和实体元数据。 |
| 参考数据,包括 objectTypes、documentFlows、fieldPatterns、statuses、paymentTypes 以及 all。示例: |
优势: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 |
安装
从联机帮助中心下载此包
b1-mcp-server.zip,解压缩,然后进入解压后的项目文件夹。安装依赖并编译:
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=trueOAuth 模式(生产环境,默认)
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-passphraseHTTP:
如果您出于本地测试、避免浏览器安全警告等其它原因(例如您已经有了现成的 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 端点:
端点 | 说明 |
| 存活检查——返回状态、版本和组件健康 |
| 服务器元数据——协议版本、能力、活动会话 |
| 简要 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) |
| 不支持(v4.0.8) | 内置 PKCE 流程 |
GitHub Copilot(VS Code) |
| 支持 | 内置 PKCE 流程 |
Goose(桌面) |
| 支持 | 内置 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 流程:
从
GET /mcp发现 OAuth 元数据(服务器会公布其授权端点和令牌端点)。发起一个 PKCE 授权请求,并将用户重定向到 Keycloak。
用授权码换取令牌(access token + refresh token)。
使用
b1_list_companies获取可用公司列表。让用户选择公司,然后调用
b1_select_company。在每一次 MCP 请求中都包含访问令牌和公司 ID:
Authorization: Bearer <access_token>x-b1-companyID: <companySchemaName>
在令牌过期前刷新令牌;如果刷新失败,重新发起 PKCE 流程。
带有注释的、完整的可运行示例——包括客户端注册、OAuth 流程、公司选择、以及预期输出——请参阅 docs/SIMPLE_MCP_CLIENT.md。
人工确认(MCP Elicitation)
MCP Elicitation 是一种协议级机制,它允许 MCP 服务器在工具调用执行中暂停,并要求已连接的客户端在继续之前提供额外的输入或确认。与简单的提示不同,Elicitation 内置于 MCP 协议中:服务器发送一个结构化的结构化请求给客户端,客户端以提示(通常是内联对话框或表单)的形式呈现给用户,服务器在决定继续或中止之前等待响应。这样,在关键操作时用户仍能保持知晓,但不必依赖 AI 代理临时充当自己的确认机制。
当 MCP_HUMAN_CONFIRMATION_ENABLED=true(默认)时,服务器在以下操作前暂停:
写入操作(
create、update、delete)——等待用户显式批准敏感读取——当查询选择了被分类为个人数据的字段(电子邮件、电话、身份证号)时,发出提示
支持 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) 在运行时动态选择。
工作原理:
MCP 客户端调用
b1_list_companies来检索 SLD 中注册的所有可用公司及其状态。用户(或由用户指导的 AI 代理)选择目标公司,调用
b1_select组件"。会话期间,所有后续工具调用(
b1_find_entities、b1_read、b1_write等)都会路由到所选公司的 Service Layer 数据库。如需切换公司,可再次使用不同的 schema 名称调用
b1_select_company— 无需服务器重新启动。
关键特性:
会话作用域: 公司选择绑定到 MCP 会话。不同的 AI 客户端会话可以同时针对不同的公司,在同一个服务器实例上。
SLD 驱动: 公司列表直接来自 SLD,反映注册公司的实时状态。无需在配置中维护静态公司列表。
仅 OAuth 模式: 该切换机制需要 OAuth 模式。直接模式仅限于单公司(
B1_COMPANY_DB在.env中固定)。
注意: 如果请求中已存在有效的的
x-b1-companyID标头,MCP 服务器将直接使用它 — 无需调用b1_list_companies和b1_select_company。这些工具的目的只是为了帮助 AI 代理或用户确定正确的公司 schema 名称,并在公司上下文尚未确定时建立上下文。一旦知道了目标公司,就可以将其公司 ID(由CompanySchemaName解析得到)直接传递给后续每个 MCP 请求的x-b1-companyID标头。
使用示例
自然语言查询
自然语言 | 工具调用 | Generated Parameters |
"显示 10 个销售订单" |
|
|
"获取销售订单 DocEntry 12345" |
|
|
"查找订单总额超过 1000 的记录" ( DocTotal > 0) |
|
|
"为供应商 V00001 创建采购订单" |
|
|
"更新业务伙伴 C00001 的电话号码" |
|
|
注意:上一行是原列表的扩展,不应在输出中出现。我们再根据原始表展开:
自然语言 | 工具调用 | 生成的参数 |
"显示 10 个销售订单" |
|
|
"获取 DocEntry 为 12345 的销售订单" |
|
|
"查找超过 1000 美元的销售订单" |
|
|
"为供应商 V00001 创建采购订单" |
|
|
"更新业务伙伴 C00001 的电话号码" |
|
|
工作流示例
要实施其他业务工作流或添加新的 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集成测试的关键变量:
变量 | 描述 |
| 测试运行程序使用的 OAuth 客户端 ID |
| 要请求的作用域(例如 |
| 设置为 |
集成测试位于 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 服务器:检查访问令牌的 scope 和 aud(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— 生产环境中使用introspection或introspection-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_DB、B1_USERNAME和B1_PASSWORD.OAuth 模式:验证
OAUTH_BASE_URL、OAUTH_CLIENT_ID、OAUTH_CLIENT_SECRET和SLD_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。
This 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
- FlicenseNot gradedqualityDmaintenanceEnables interaction with SAP Business One API through Azure Container Apps with VNet connectivity. Provides secure access to SAP data and operations through natural language interface.6
- 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
Related MCP Connectors
Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.
Chile DTE for AI agents - boleta/factura electronica via OpenFactura or LibreDTE. Stateless BYO.
Manage your Savanto store from your AI: catalog, content, prompts, and analytics, by chat.
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/glauberbessa/mcpserverforsapb1'
If you have feedback or need assistance with the MCP directory API, please join our Discord server