ABAP MCP Server
# ABAP MCP Server
独立的 MCP Server,用于 agent 化的 ABAP 开发 — 通过 ADT REST API 提供 82 个工具。
> **最后校对**: 2026-07-19(70 Tools / 28 categories / 15 core 对齐 src/;删 SAPTest facade;Intent Facade 覆盖 132 个 granular operation)→ 2026-08-07 新增 12 WDY 工具(82 / 29 categories / 15 core)→ 2026-08-16 BSP 传输修复(`create_appl_folder` 传 `CORR_NUMBER` + `get_transport_objects` 合并 S 任务行,工具数不变)
---
## 核心特性 — 本 MCP 的差异化优势
ABAP MCP 生态从纯只读 ADT wrapper 到大型工具集合都有。本服务器走不同路线:不追求工具数量,而是**高质量、agent 驱动、面向真实可达系统的开发**。以下三点组合在其他 ABAP MCP 服务器上没有:
### 🧹 Clean ABAP 作为强制工作流 — 而非事后 linter
其他服务器最多提供可选的 lint 调用。本服务器把 Clean Code **内建**到开发流程:`abap_develop` Prompt 强制 **6 步工作流**(上下文分析 → 参考研究 → Clean ABAP 检查 → 代码放置 → 实现 → 质量检查)。此外附带 Claude Code Skill `clean-abap`,在代码编写或评审时自动应用 [Clean ABAP Styleguide](https://github.com/SAP/styleguides),外加 `review_clean_abap` 和 `search_clean_abap` 工具。结果:agent 产出符合 styleguide 的代码 — 无需你反复提醒。
### 🔍 编码前 DDIC 校验 — 从根源杜绝幻觉
用 `validate_ddic_references`,agent 在代码中使用表、结构、字段名之前,**先对照真实 Data Dictionary 校验**。这消除了 ABAP 生成最常见的幻觉源 — 编造的字段名,否则要到激活时才暴露。其他服务器只在事后用语法检查或 ATC 校验;本服务器在源头就切断错误。
### 🌐 四种网络路由模式 — 能连上其他工具连不上的系统
大多数 ADT 桥只支持直接 HTTPS。本服务器按固定顺序尝试四种模式,取第一个已配置的:**BTP Connectivity Proxy → SAProuter NI 隧道 → HTTP-CONNECT 代理 → 直接 HTTPS**。这样在经典 B2B VPN(只开 3299 端口)和混合 CAP / Cloud Connector 场景下也能连上 ABAP 系统 — 这些是纯 HTTPS wrapper 失败的场景。
### 其他强项
- **🚀 本地 `.abap` 文件 + 批量推送 — 15 分钟变秒级** — 其他 AI 方案逐字符把 ABAP 代码写进 ADT 系统;大程序每次写入可达 **15 分钟**。本服务器改用本地 `.abap` 文件:agent 本地编辑,`write_abap_source` 一次 ADT API 调用推送完整内容 — **秒级**完成。10 次迭代修正可省 **150 分钟**/会话。
- **🔁 递归编码直至激活成功** — Write 工作流走 `lock → write → 语法检查 → 激活 → unlock`,**仅在语法检查干净时激活**。失败时 agent 拿到具体错误列表,迭代修正直至对象无错激活。你拿到的是激活的、可运行的代码,而非带红标记的草稿。
- **📝 选择屏幕自动文本元素** — 成功写入+激活 **程序(PROG/P)** 或 **程序 include(PROG/I)** 后,`write_abap_source` 自动为 `PARAMETERS`/`SELECT-OPTIONS` 字段创建文本元素,让选择屏幕显示标签而非裸字段名。ABAP handler 做**全量替换**(`DELETE TEXTPOOL` + `INSERT TEXTPOOL`),所以服务器先读现有文本元素再合并(auto < existing < 调用方 `textElements`),以保留现有报表标题(R)、信息文本(I)、标题(T)、头部注释(H)。可选的 `textElements` 参数优先;省略时 `S` 条目以 `entry`=字段名作占位符自动解析。传 `[]` 禁用。非阻塞 — 失败只追加警告。类/函数组/DDIC 跳过。
- **🎯 延迟加载工具 — 节省 ~75–80% token** — 不把全部 70 个工具加载进上下文,服务器只启动 **15 个核心工具**。其余按需通过 meta 工具 `find_tools` 激活(`find_tools(category=…)` 或 `find_tools(query=…)`)。
- **✂️ 方法级手术** — `read_abap_method` / `edit_abap_method` 读取或替换单个 `METHOD…ENDMETHOD` 块。agent 不再为改一个方法输出整个类 — 服务器在服务端把新方法体拼接进源码并走标准 write 工作流。迭代编码时最大的 token 杠杆。
- **🗜️ 依赖契约** — `get_abap_contract`(和 `analyze_abap_context(mode=contract)`)把类/接口压缩到公共签名表面,不含方法体 — 通常 5–10% 源码大小。agent 在编码前低成本拿到依赖的 API。
- **⚡ 源码缓存** — `getObjectSource` 的 TTL 缓存(`SOURCE_CACHE_TTL_MS`,默认 30s);重复读命中缓存,写入/删除自动失效 — 变更后不会读到过期源码。
- **🧰 Intent Facade** — 四个整合动词 `SAPRead`/`SAPWrite`/`SAPSearch`/`SAPDiagnose`,面向想要小工具表面而非 132 个 granular operation 的客户端。纯路由层 — 所有安全检查保持激活。新操作(Text Elements、GUI Status、Transaction Code via `RPY_TRANSACTION_INSERT`、Transport Append、SMW0 Web Objects、Data Query、Screen/Dynpro CRUD、Message Class/T100 CRUD、RFC→SOAP Webservice via SRT API、Auth Object)只能通过 Intent Facade 访问。Transaction Code 支持 `screenNumber` 指定自定义 dynpro 号。Screen 操作(`list_screens`、`read_screen`、`create_screen`、`copy_screen`)支持 subscreen、table control、tabstrip 及所有 dynpro 元素。Message 操作(`read_messages`、`save_messages`)通过自定义 ICF 端点读写 T100 消息。Webservice 操作(`create_webservice`、`create_sdef`、`create_icf_node`、`delete_webservice`、`check_ws_status`、`list_sdefs`、`get_wsdl_url`、`enable_sdef`、`create_ws_config`)通过 SAP SRT API 自动化 RFC→SOAP webservice 创建 — 替代手动 SOAMANAGER 配置。`enable_sdef` 写 SRT_ST_ACT_P(deployed=true);`create_ws_config` 创建 SOAMANAGER Web Service Configuration(SRT_CFG_DIR RT config + binding)并返回 `bindingUrl`(altPath)— 即 hicode 注册为 apiUrl 的 URL 路径(不含 host,仅路径)。RT config 是 client 相关 → SIT 需 `targetClient='300'`。BSP 操作(`create_bsp_application`、`create_bsp_page`、`read_bsp_page`、`activate_bsp_page`、`delete_bsp_page`)通过 CL_O2_API_APPLICATION/CL_O2_API_PAGES 创建和管理 BSP 应用及页面(自定义 ICF 端点 `/sap/bc/zbsp_tools`,7.31 兼容)。`create_bsp_page` 完整支持 Flow Logic 页面(pageType=flowlogic):`eventHandlers`(OnInitialization/OnInputProcessing/OnRequest)通过 `set_event_handler`,带类型的页面属性(`parameters` 含 `type`,typtype=1),激活时自动重生成 class pool(`call_o2_compiler(P)` + `delete_loadinfo_of_page`)。`delete_bsp_page` 直接调 `save`(`load_for_deletion` 已预设 deleted 状态,`delete` 会触发 error_occured)。Auth Object 操作(`create_auth_object`、`ensure_auth_class`)创建权限对象(TOBJ/TOBJT)或在 TOBC 注册 auth class。测试操作(`test_alv_report`、`test_dyn_function`、`test_hicode_api`、`run_snippet`)挂在 `SAPDiagnose` 下(不是单独的 `SAPTest` 动词)。WebDynpro 操作(`list_wdy_components`、`read_wdy_source`、`read_wdy_method`、`get_wdy_mapping`、`write_wdy_source`、`activate_wdy_object`、`generate_wdy`、`create_wdy_component`、`create_wdy_view`、`create_wdy_action`、`create_wdy_method`、`create_wdy_appl`)通过自定义 ICF 端点 `/sap/bc/zwdy_tools`(ZCL_ADT_WDY_HANDLER)提供 WebDynpro ABAP 对象的完整 CRUD,底层调用 SAP 标准 `WDY_WB_*` 函数组(WDY_WB_GET_CONTROLLER_INCLUDE + READ REPORT 读取源码,WDY_WB_SET_SOURCE_INFO + WDY_WB_GENERATE 写入,WDY_WB_ACTIVATE_OBJECT 激活,WDY_WB_POPUP_CREATE_* 创建组件/视图/方法/应用)。`create_wdy_action` 采用直接 WDY_CTLR_COMPO 表 INSERT(I+A 双版本)+ RS_WORKING_OBJECT_ACTIVATE,因为 WDY_WB_POPUP_CREATE_ACTION 硬编码 CALL SCREEN 0300 向导弹框、MD API save_to_database 触发 SEO_INTERFACE_CREATE_COMPLETE(suppress_dialog=abap_false) 弹框,两条路径均无法无头化。
- **📊 Data Tools(NW 7.31 兼容)** — `query_table` / `query_join` / `insert_table` / `update_table` / `delete_table` 操作通过自定义 ICF 端点 `/sap/bc/zdata_tools/{query|execute}/*`(ZCL_ADT_DATA_HANDLER)提供表数据查询与写入,无需 ADT Data Preview(需要 NW 7.40+)。单表查询用动态 Open SQL(自动 MANDT 过滤),2 表 JOIN 用 ADBC 原生 SQL(自动 DB 方言适配)。INSERT/UPDATE/DELETE 走 `/execute/{insert|update|delete}`,ZADT_TOOLS 权限校验(ACTION=40 SELECT / 30 INSERT / 20 UPDATE / 10 DELETE)+ CSRF + 单 LUW 事务边界,MANDT 自动填,Z/Y 客户命名空间强制。在 NW 7.31 系统上也能查询与写入表数据。
- **🗂️ DDIC 二级索引自动补 MANDT** — `ddic_create`/`ddic_update` 建表带二级索引(`indexes[]`)时,对 client-dependent 表(delivery class A/C/L/G)自动把 `MANDT` 插到索引字段列表第一位(SAP 标准:跨 client 查询才能走索引)。client-independent 表(S/T/W/E/M/LX)不动;索引已含 MANDT 则不重复。TS 端(`buildCreateBody`/`buildUpdateBody`)+ ABAP 端(`ZCL_ADT_DDIC_HANDLER` 索引循环)双端对称补全,ABAP 端检测已存在则跳过,无重复。
- **🛂 治理(角色 + 审计)** — 角色 `viewer`/`developer`/`admin`(`SAP_ROLE`)在 ALLOW_* 标志之上进一步限制;每次变更操作以 JSON 审计行写入 STDERR(及可选 `AUDIT_LOG_FILE`)。
- **🕸️ 影响分析** — `get_call_graph` 把递归 where-used 图渲染为 Mermaid 图;`find_dead_code` 标记无入站使用的对象为删除候选。
- **🧠 写入前的完整上下文** — `analyze_abap_context`、`where_used` 和 `read_abap_source(includeRelated=true)` 递归读取所有关联对象(include、函数模块、类),让 agent 在动手前理解整个程序。
- **⚡ 安全的临时执行** — `execute_abap_snippet` 在临时 `$TMP` 程序中执行代码并**总是删除**(即使运行时出错)。静态禁用列表(`COMMIT WORK`、DB `INSERT/UPDATE/DELETE` 等)预先拦截数据变更操作。
**⛔ 硬规则:本工具仅用于读操作(SELECT、计算)。** 绝不能用于创建、修改或激活永久 ABAP 对象 — 那是 `create_abap_*`、`write_abap_source`、`activate_abap_object` 等的职责。
- **🛡️ 默认安全的安全检查** — 写、删、执行默认**禁用**,需显式开启。客户命名空间强制(Z/Y)和 `BLOCKED_PACKAGES` 保护 SAP 自有对象。PROD 完全锁定。
- **🤖 Agent 框架韧性** — `abap-*`/`mcp-*` 子 agent(`.claude/agents/`)有**硬 wall-clock deadline**(每阶段 4–8 分钟,orchestrator 30 分钟),通过 PreToolUse hook(`agent-deadline-check.ps1`)在 `maxTurns` 之前 `exit 2` 中断并强制结构化 `STATUS: blocked`。`call-tracker` 把振荡/预算耗尽变成**终端阻塞**(`BLOCKED:` 消息,5 分钟冷却)而非软警告 — agent 无法通过切换 facade 逃脱。心跳文件(`_scratch/heartbeat_<agent>.json`)和状态板(`_scratch/agents-status.json`)提供实时进度;主会话可用 `Monitor` tail。**漂移守护测试**(`agent-tools-drift.test.ts`)检测 agent frontmatter 中的拼写错误/退役工具名(fail)和未被任何 agent 列出的新框架工具(warn)。
- **🚦 主会话委派(硬规则)** — 主会话把完整 ABAP 开发任务委派给 `abap-orchestrator`、框架任务委派给 `mcp-framework-orchestrator`,而非直接执行 SAP 写操作 — 以免绕过 7 阶段工作流、Gate Check、deadline/振荡保护、质量评审和交付流程。只读查询和本地编辑主会话可直接做;边界不确定时用 `AskUserQuestion` 问用户。
- **🔒 并发安全** — 串行 write lock 和 stateful session 配合自动锁恢复,防止并行写操作冲突。
- **📚 集成 SAP 文档搜索** — `search_sap_web`、`fetch_url`(读任意 URL,含 SPA 如 SAP Help Portal)和版本相关的 help.sap.com 引用(`SAP_ABAP_VERSION`)给 agent 提供最新、正确的参考,而非过时的训练知识。
### Token 高效用法 — 示例
```jsonc
// 只取依赖的 API 表面(而非整个类):
get_abap_contract({ objectUrl: "/sap/bc/adt/oo/classes/zcl_billing" })
// 读取或替换单个方法(而非全类读/写):
read_abap_method({ objectUrl: "/sap/bc/adt/oo/classes/zcl_billing", methodName: "calculate" })
edit_abap_method({ objectUrl: "/sap/bc/adt/oo/classes/zcl_billing",
methodName: "calculate", source: " rv_total = iv_net * ( 1 + iv_tax )." })
// 上下文用压缩契约而非全文:
analyze_abap_context({ objectUrl: "...", mode: "contract" })
// 变更前的影响分析:
get_call_graph({ objectUrl: "/sap/bc/adt/oo/classes/zcl_billing", depth: 2 })
// 通过 Intent 动词用小工具表面(委托到 granular 工具):
SAPRead({ operation: "method", args: { objectUrl: "...", methodName: "calculate" } })
// 通过 SAPDiagnose 做 SIT 测试(ALV 报表、FM/BAPI 或 ABAP snippet):
SAPDiagnose({ operation: "test_alv_report", args: '{"reportName":"ZMMR068","targetSystem":"sit"}' })
SAPDiagnose({ operation: "test_dyn_function", args: '{"functionName":"BAPI_COMPANYCODE_GETDETAIL","targetClient":"300"}' })
SAPDiagnose({ operation: "run_snippet", args: '{"source":"REPORT z.\\nWRITE: / sy-sysid."}' })
```
---
## 快速开始
**1. 安装依赖并构建**
```bash
npm install
npm run build
```
**2. 配置**
```bash
cp .env.example .env
# 打开 .env 填入 SAP_URL, SAP_USER, SAP_PASSWORD
```
**3. 启动**
```bash
npm start
# 或直接:
node dist/index.js
```
一切正常时你会看到:
```
╔══════════════════════════════════════════╗
║ ABAP MCP Server v2.0 — Extended ║
╚══════════════════════════════════════════╝
System : https://<SAP_SYSTEM>:<PORT>
User : <USERNAME> Client: <CLIENT> Lang: EN
Write : ❌ 已禁用
Delete : ❌ 已禁用
Tools : 15 初始(共 70,延迟加载)
Doku : help.sap.com vlatest
Prompts : 1 (abap_develop)
ADT : ✅ 已连接
✅ MCP Server 运行于 stdio — 等待连接
```
---
## 对比:本 MCP vs SAP ADT for VS Code(官方 MCP)
SAP 的 ADT for VS Code MCP Server(2026 Q2 GA)是类似概念 — 基于 ADT REST API 的 MCP Server。对比如下:
| 特性 | 本 MCP | SAP ADT for VS Code |
|---|---|---|
| **工具数** | **70 个工具** | ~10 个能力类别 |
| **IDE 绑定** | 无 — 任意 MCP 客户端 | VS Code + Eclipse(共享 ADT Core) |
| **系统支持** | ECC 6.0+、S/4HANA on-prem、BTP | BTP + on-prem(RFC);首发聚焦 ABAP Cloud |
| **经典 ABAP**(程序、函数组、BAPI、消息) | ✅ 完整 | ❌ 暂无(函数组/程序计划后续版本) |
| **SAP Business Workflow(SWDD)** | ✅ `analyze_workflow`(definitions/instances/steps/agents) | ❌ |
| **CDS Views(DDLS)** | ✅ | ✅ |
| **CDS Metadata Extensions(DDLX)** | ✅ | ✅ |
| **Service Definitions(SRVD)** | ✅ | ✅ |
| **Service Bindings(SRVB)+ Publish** | ✅ | ✅ |
| **Data Control Language(DCLS)** | ✅ | ✅ |
| **Behavior Definitions(BDEF)** | ✅ `create_behavior_definition` | ✅ |
| **Behavior Implementations(ABP)** | ✅ 通过类工具 | ✅ |
| **方法级手术** | ✅ `read/edit_abap_method` | ❌ |
| **上下文压缩(契约)** | ✅ `get_abap_contract` | ❌ |
| **调用图 / 死代码检测** | ✅ | ❌ |
| **并行批量读** | ✅ `batch_read` | ❌ |
| **ABAP snippet 执行** | ✅ 临时 + 清理 | ❌ |
| **延迟工具加载** | ✅ 节省 75–80% token | N/A |
| **审计日志** | ✅ 结构化 JSON | ❌ |
| **RBAC 治理** | ✅ viewer/developer/admin | ❌ |
| **包守护 + 命名空间强制** | ✅ | ❌ |
| **SAProuter / BTP Proxy / HTTP Proxy** | ✅ 全部 4 种路由模式 | BTP + 直接 |
| **Web 搜索** | ✅ `search_sap_web` + `fetch_url`(Tavily) | ❌ |
| **Clean ABAP Lint** | ✅ `review_clean_abap` + Skill | ✅ ATC clean-core |
| **Unit 测试** | ✅ 执行 + 创建 include | ✅ 生成 + 执行 |
| **DDIC 字段校验(写前)** | ✅ 写前静态分析 | ❌ |
| **RAP BDEF 知识** | ✅ `rap-bdef` Skill | ✅ SAP 自有模型 |
| **专用 ABAP LLM** | ❌(用客户端模型) | ✅ SAP-ABAP-1 |
| **原生 VS Code UX** | ❌(刻意 IDE 无关) | ✅ |
| **企业 SLA** | ❌ 开源 | ✅ |
| **许可成本** | **免费** | AI Units(BTP 订阅) |
**结论:** SAP 提供更窄的首发(聚焦 BTP,VS Code + Eclipse,~10 类别)配自有 ABAP 模型。本服务器更广(所有 SAP 系统、所有 ABAP 制品、任意 MCP 客户端)、更深(70 工具、治理、审计、上下文压缩)且免费。唯一真实缺口是专用的 SAP-ABAP-1 语言模型。
---
## MCP 客户端配置
**重要:** 你通常**不手动**调用服务器 — 它由 MCP 客户端(Claude Desktop、Claude Code 等)自动启动。你只需在配置里登记一次:
### Claude Desktop
`%APPDATA%\Claude\claude_desktop_config.json`(Windows):
```json
{
"mcpServers": {
"abap": {
"command": "node",
"args": ["/path/to/abap-mcp-server/dist/index.js"],
"env": {
"SAP_URL": "https://<SAP_SYSTEM>:<PORT>",
"SAP_USER": "<USERNAME>",
"SAP_PASSWORD": "<PASSWORD>",
"SAP_CLIENT": "<CLIENT>",
"ALLOW_WRITE": "true"
}
}
}
}
```
然后重启 Claude Desktop — 打开会话时服务器在后台运行。
### Claude Code
项目目录下 `.claude/mcp.json`:
```json
{
"mcpServers": {
"abap": {
"command": "node",
"args": ["/path/to/abap-mcp-server/dist/index.js"]
}
}
}
```
#### Clean ABAP Skill(可选,Claude Code)
本仓库含 Claude Code Skill `clean-abap`(`.claude/skills/clean-abap/SKILL.md`),在编写或评审 ABAP 代码时自动应用 Clean ABAP Styleguide。已签入 — 克隆后在项目目录重启 Claude Code 即自动生效。详见 `DOCUMENTATION.md` → "Claude Skills" 章节。
### Cline(VS Code 扩展)
在 VS Code 打开 Cline 设置(Cline 图标 → Settings),进入 "MCP Server Configuration",添加:
```json
{
"mcpServers": {
"ABAP Server": {
"autoApprove": [
"search_abap_objects",
"read_abap_source",
"where_used",
"write_abap_source",
"analyze_abap_context",
"abap_develop"
],
"disabled": false,
"timeout": 60,
"type": "stdio",
"command": "node",
"args": [
"/path/to/abap-mcp-server/dist/index.js"
],
"env": {
"SAP_URL": "https://<SAP_SYSTEM>:<PORT>",
"SAP_USER": "<USERNAME>",
"SAP_PASSWORD": "<PASSWORD>",
"SAP_CLIENT": "<CLIENT>",
"SAP_LANGUAGE": "EN",
"ALLOW_WRITE": "true",
"ALLOW_DELETE": "false",
"ALLOW_EXECUTE": "true",
"BLOCKED_PACKAGES": "SAP,SHD,SMOD",
"SYNTAX_CHECK_BEFORE_ACTIVATE": "true",
"SAP_ALLOW_UNAUTHORIZED": "true",
"MAX_DUMPS": "20",
"DEFER_TOOLS": "true",
"SAP_ABAP_VERSION": "latest",
"NODE_TLS_REJECT_UNAUTHORIZED": "0",
"TAVILY_API_KEY": "<TAVILY_KEY>"
}
}
}
}
```
**说明:**
- `autoApprove` 列出无需用户确认即可执行的工具。按需扩充(如 `search_abap_syntax`、`validate_ddic_references`、`get_object_info`、`find_tools`)。
- `timeout`:单次工具调用最大运行秒数(ATC 检查等建议 60)。
- `SAP_ALLOW_UNAUTHORIZED=true` / `NODE_TLS_REJECT_UNAUTHORIZED=0`:仅自签名证书时(DEV 系统)设置!
- `TAVILY_API_KEY`:可选 — `fetch_url` 和 `search_sap_web` 需要。从 [tavily.com](https://tavily.com) 获取 API key。
- 所有 `env` 变量也可在服务器目录的 `.env` 文件配置。
保存后:重启 Cline 或重载 MCP 连接。
---
## 凭据配置
服务器从项目 `.env` 文件加载凭据:
```bash
# 必填
SAP_URL=https://<SAP_SYSTEM>:<PORT>
SAP_USER=<USERNAME>
SAP_PASSWORD=<PASSWORD>
SAP_CLIENT=<CLIENT>
SAP_LANGUAGE=EN
# 安全(全部默认安全)
ALLOW_WRITE=false
ALLOW_DELETE=false
ALLOW_EXECUTE=false
BLOCKED_PACKAGES=SAP,SHD,SMOD
# 治理(角色与审计)
# SAP_ROLE 在 ALLOW_* 标志之上进一步限制(只能更严,不能放开):
# viewer = 只读,developer = write+execute(无 delete),admin = 全部(默认 = 旧行为)。
SAP_ROLE=admin
# 可选:变更操作的 JSON 审计日志(同时总是写 STDERR)。
AUDIT_LOG_FILE=
# 选项
SYNTAX_CHECK_BEFORE_ACTIVATE=true
DEFER_TOOLS=true
SAP_ABAP_VERSION=latest
MAX_DUMPS=20
# getObjectSource 的源码缓存 TTL(ms,默认 30000;0 = 关闭)。
# 写入/删除自动失效。
SOURCE_CACHE_TTL_MS=30000
# Web 搜索(可选 — 用于 fetch_url 和 search_sap_web 工具)
TAVILY_API_KEY=
# 每次 Tavily 调用超时(ms);Web 响应缓存 TTL(ms)。0 = 关闭。
# TAVILY_TIMEOUT_MS=30000
# WEB_CACHE_TTL_MS=300000
```
你**无需**在 MCP 配置里重复凭据 — 服务器启动时自动加载。
**各环境推荐设置:**
| 变量 | DEV | QAS/TEST | PROD |
|---|---|---|---|
| `ALLOW_WRITE` | `true` | `false` | `false` |
| `ALLOW_DELETE` | `false` | `false` | `false` |
| `ALLOW_EXECUTE` | `true` | `false` | `false` |
| `SAP_ROLE` | `admin`/`developer` | `viewer` | `viewer` |
---
## 为什么服务器不需要端口?
ABAP MCP Server 运行在 **stdio 模式**(标准输入/输出),不是 HTTP 模式:
- **stdio 模式**(本服务器) ✅
- 服务器通过 stdin/stdout 直接与客户端通信
- 无 HTTP 服务器,无需 TCP 端口
- 这是 MCP(Model Context Protocol)的标准
- 按需由客户端自动启动
- 适合:Claude Desktop、Claude Code、Cline
- **HTTP 模式**(可选,用于外部客户端)
- 服务器监听 TCP 端口(如 4847)
- 客户端通过 HTTP 连接
- 多客户端进程或外部集成时需要
**简言之:** 不需要端口,因为你的客户端(Claude、Cline)直接启动服务器并通过 stdio 通信。更快更安全。
---
## 网络路由
运行 MCP 服务器的机器必须能访问 ABAP 系统。服务器支持四种路由模式 — 按以下顺序尝试,取**第一个已配置的**:
| 优先级 | 模式 | 适用场景 |
|---|---|---|
| 1 | **BTP Connectivity Proxy** | 混合 CAP 开发;ABAP 系统仅通过 Cloud Connector 可达 |
| 2 | **SAProuter NI 隧道** | 经典 B2B VPN,仅 3299 端口对外开放 |
| 3 | **HTTP-CONNECT 代理** | 公司代理或本地 SSH/socat 隧道 |
| 4 | **直接 HTTPS** | DNS 和防火墙允许直连 |
### 模式 1 — BTP Connectivity Proxy(CAP 开发推荐)
通过 BTP 子账户信任的 Cloud Connector 路由 HTTPS。MCP Server 搭载在绑定了 `connectivity` 服务的 Cloud Foundry 应用的本地转发 Connectivity Proxy 上。
**一次性准备:**
```bash
# 在单独终端 — MCP 运行期间保持
cf ssh <app> -N -L 20003:connectivityproxy.internal.cf.<region>.hana.ondemand.com:20003
# 在 CAP 项目:绑定 connectivity 服务(一次性)
cds bind --to <connectivity-instance> --credentials '{"onpremise_proxy_host":"localhost"}' --for hybrid
```
**MCP 配置(`.env` 或 MCP 客户端 `env`):**
```env
SAP_URL=http://mdadneap1.example.com:44300 # 端口 20003 用 http://!
SAP_BTP_CONNECTIVITY_PROXY=http://localhost:20003
SAP_BTP_CONNECTIVITY_LOCATION_ID= # 空 = 默认 CC;可用诊断工具确定
SAP_BTP_CONNECTIVITY_CDS_BIND_FILE=/abs/path/<project>/.cdsrc-private.json
SAP_BTP_CONNECTIVITY_CDS_BIND_NAME=connectivity
SAP_BTP_CF_HOME=/abs/path/<project> # 可选,项目专属 cf 会话
```
三种 JWT 来源按顺序尝试:`*_CREDS_FILE` → `*_CDS_BIND_FILE` + `*_CDS_BIND_NAME` → 直接 `*_CLIENT_ID/_SECRET/_TOKEN_URL`。详见 [`.env.example`](.env.example)。
**协议说明:**
- 端口 **20003** 的 Connectivity Proxy 是 HTTP 转发代理 → `SAP_URL` 须为 `http://...`。Cloud Connector 处理后端 TLS。
- 端口 **20004** 的代理走 CONNECT 隧道 → `SAP_URL=https://...`。
- Cloud Connector 须将 `/sap/bc/adt/*` 放行。
**诊断:**
```bash
npm run diag:btp-proxy # 对 SAP_URL/sap/bc/adt/discovery 的端到端探测
npm run diag:btp-token # 显示 XSUAA JWT claims(subaccount、audience、scope)
npm run diag:btp-destination -- --list # 列出所有 destinations
npm run diag:btp-destination -- <DESTINATION_NAME> # 确定 Location-ID + virtual host
npm run diag:adt # 通过 getClient() 端到端测试
```
### 模式 2 — SAProuter NI 隧道
```env
SAP_URL=https://<target-host>:<port>
SAP_ROUTER=/H/saproutprd.example.com/S/3299 # 或简写:host:port
# SAP_ROUTER_PASSWORD= # saprouttab 要求密码时
# SAP_ROUTER_DEBUG=true # stderr 输出 NI 帧
```
前提:`saprouttab` 须含(你的来源 → target host:port)的 Permit 规则。否则 SAProuter 返回 `NI_RTERR`。后端主机还须在指定端口真正接受 HTTPS(Web Dispatcher 或 ICM `icm/server_port`)。
### 模式 3 — HTTP-CONNECT 代理
```env
SAP_PROXY_URL=http://proxy.corp.example.com:8080 # 或 http://localhost:8443(SSH 隧道)
```
标准环境变量 `HTTPS_PROXY` / `HTTP_PROXY` 也被识别。
### 模式 4 — 直接 HTTPS
无需额外变量。后端用自签名证书时加 `SAP_ALLOW_UNAUTHORIZED=true`(仅 DEV 系统)。
### 不应放在 `SAP_URL` 里的内容
- **SAProuter 路由**(`/H/.../S/...`):SAProuter 说 SAP NI 二进制协议,不是 HTTP。应放 `SAP_ROUTER`。
- **Cloud Connector virtual-host-only 路径**:那是 `SAP_URL`。路径前缀映射由 Cloud Connector 做。
---
## 故障排查
**"ADT 错误:User is currently editing..."**
- 服务器试图锁定一个已被锁定的文件(如前次错误残留)。
- 解决:打开 SAP Studio 结束锁会话,或重启服务器。
**Include 激活错误**
- Include 不能独立激活。服务器自动识别并在主程序上下文中激活 include。需要时写入时指定 `mainProgram` 参数。
**"SAP_URL, SAP_USER and SAP_PASSWORD must be set"**
- 缺 `.env` 文件或服务器从错误目录启动。Cline 下检查 MCP 配置的 `cwd` 字段。
**Connection refused / `ENOTFOUND <host>`**
- VPN 开了吗?SAP 系统可达吗?URL 对吗?`nslookup <host>` 须在本机通过 — 否则不是代码问题,是 DNS/VPN。
**BTP Connectivity Proxy:HTTP 503 "no SAP Cloud Connector matching the requested tunnel"**
- JWT 中 subaccount audience 错误(如用了别的子账户的 service-key)或缺/错的 `SAP_BTP_CONNECTIVITY_LOCATION_ID`。
- `npm run diag:btp-token` 显示 token 的 `zid`(子账户 ID)和 `aud`。
- `npm run diag:btp-destination -- --list` 显示你子账户配置的所有 Location-ID。
**BTP Connectivity Proxy:HTTP 405 "HTTPS proxying is not supported"**
- `SAP_URL` 是 `https://...`,但代理跑在 HTTP 转发端口(20003)。把 `SAP_URL` 改成 `http://`,或把 SSH 转发改到端口 20004。
**`cf service-key` 失败(login expired / no org targeted)**
- 服务器给出含 `cf` 命令建议的精确错误。通常 `CF_HOME=<project> cf login --sso` 即可。
**自签名证书(仅 DEV)**
- 设置 `SAP_ALLOW_UNAUTHORIZED=true`。生产环境绝不要!
TDQS
Scored across 13 tools
Each of the 13 tools has a clearly distinct purpose: analyze_abap_context provides structured context, batch_read parallelizes reads, fetch_url fetches web content, find_tools enables deferred tools, get_abap_contract returns compressed interfaces, list_tools lists all tools, the four SAP verbs (Diagnose, Read, Search, Write) consolidate granular operations, search_abap_syntax queries syntax docs, search_sap_web searches SAP resources, and validate_ddic_references checks DDIC references. No two tools overlap in functionality.
Most tools follow a verb_noun pattern (e.g., fetch_url, find_tools, search_abap_syntax), but there are stylistic inconsistencies: three tools use a capitalized 'SAP' prefix (SAPDiagnose, SAPRead, SAPSearch, SAPWrite) which mixes with lowercase verb-first names, and 'batch_read' uses an adjective-noun structure. While still readable, the convention is not uniform.
With 13 tools, the set is well-scoped. It provides a reasonable number of high-level abstractions that cover the main workflows (read, write, search, diagnostics, utilities) without overwhelming the user. The count is appropriate for a specialized ABAP development server.
The tool set covers all major aspects of ABAP development: reading source code and context, writing and activating code, searching code and documentation, performing diagnostics, validating DDIC references, and enabling/disabling tools. The consolidated SAP verbs (Read, Write, Search, Diagnose) ensure that granular operations are accessible, and utilities like batch_read and fetch_url address additional needs. No obvious gaps are present.