Skip to main content
Glama
abap0917

abap-adt-mcp

ABAP ADT MCP Server 设计文档

基于 ABAP ADT(ABAP Development Tools)REST API 构建的 Model Context Protocol (MCP) 服务器。 让 AI Agent(Claude Desktop / Cline / VS Code Copilot Agent / 任意 MCP 客户端)无需 SAP GUI 即可 读取、检查、编写、激活、传输 ABAP 代码,覆盖完整开发生命周期。


1. 设计定位与决策

社区已有成熟实现,本项目的定位不是重复造轮子,而是采用"AI 友好"的高层工具设计

现有项目

定位

本项目的取舍

mario-andreschak/mcp-abap-abap-adt-api

abap-adt-api 的薄封装,暴露 lock/unlock 等底层步骤

✅ 复用其底层库 abap-adt-api 作为传输层

mario-andreschak/mcp-abap-adt

偏向只读的高层工具(GetProgram/GetClass…)

✅ 借鉴其"高层工具"思路

abap-adt-mcp(himcp.ai)

AI 友好工作流、安全优先、审计日志

主要设计蓝本:把 lock 编排、错误翻译、只读/白名单封装进工具内部

结论:底层通信直接建立在业界验证的 abap-adt-api(v3.1.2)之上, 避免自己重写脆弱的 ADT REST 协议(CSRF、XML 解析、对象元数据)。 在其之上构建一层安全优先、面向 Agent 的高层工具,使 Agent 通过工具名即可理解能力,且不会留下悬空锁、不会误改 SAP 标准对象。


2. 架构分层

┌─────────────────────────────────────────────────────────────┐
│  MCP Client (Claude / Cline / VS Code Agent / FLUJO)         │
└───────────────────────────┬─────────────────────────────────┘
                            │  JSON-RPC over stdio
┌───────────────────────────▼─────────────────────────────────┐
│  MCP Server (this project, TypeScript)                        │
│                                                               │
│  ├─ tools/read.ts     只读/检查工具 (11)                       │
│  ├─ tools/write.ts    写入编排工具 (4) — 仅非只读模式注册       │
│  ├─ tools/ddic.ts     DDIC 创建工具 (2) — 域 / 数据元素        │
│  ├─ tools/table.ts    DDIC 创建工具 (1) — 透明表               │
│  ├─ tools/package.ts  DDIC 创建工具 (1) — 包 DEVC/K            │
│  ├─ tools/textelements.ts 文本元素读写 (1读+1写)               │
│  ├─ tools/functions.ts 函数模块读写 (2读+3写, SE37)             │
│  ├─ tools/edit.ts     surgical edit 工具 (1) — token 优化      │
│  ├─ tools/decisions.ts 统一 包/请求 决策(澄清 vs 直接绑定)    │
│  ├─ resources/        可浏览资源 (system info / package)       │
│  ├─ adt/security.ts   安全层:只读、Z*/Y* 白名单、审计日志      │
│  ├─ adt/errors.ts     错误翻译(可行动的错误信息)              │
│  └─ adt/client.ts     连接生命周期 + 每个 ADT 操作的薄封装      │
└───────────────────────────┬─────────────────────────────────┘
                            │  HTTPS + CSRF (abap-adt-api)
┌───────────────────────────▼─────────────────────────────────┐
│  SAP ABAP System  (SICF: /sap/bc/adt 已激活, 用户具 S_DEVELOP) │
└─────────────────────────────────────────────────────────────┘

关键原则(对应 MCP Builder 准则)

  1. 描述性工具名adt_write_source 而非 tool1;Agent 靠名字选工具。

  2. Zod 类型化参数 — 每个输入都校验,可选参数有默认值。

  3. 结构化输出 — 数据返回 JSON,源码类内容返回带行号的文本。

  4. 优雅失败 — 所有工具经 safe() 包裹,错误转为 isError 文本,服务器永不崩溃。

  5. 无状态工具 — 每次调用独立;SAP 会话由单例 ADTClient 维护。

  6. 安全优先 — 见第 4 节。


3. 工具清单(24 个:11 只读 + 13 写入)

只读 / 检查(始终注册,含只读模式)

工具

说明

关键参数

adt_ping

连通性 + 会话/角色信息诊断

adt_search_objects

按名称模式搜索对象(支持 */+ 通配)

query, objectType?, maxResults?

adt_browse_package

列出包(DEVCLASS)内对象

package

adt_read_source

读取源码,支持行范围切片、行号前缀、截断保护;attachContext=true 附加 DDIC 引用压缩 prologue(token 优化)

objectUri, startLine?, endLine?, attachContext?

adt_get_object_structure

对象结构大纲;类返回每个 include 的 sourceUri + 方法/属性清单(方法级定位)

objectUri

adt_syntax_check

语法检查(不锁、不写)

objectUri, source

adt_list_transports

列出用户传输请求

user

adt_get_table_data

读 DDIC 表 / CDS 视图数据(WHERE + 行数限制)

entity, where?, maxRows?

adt_read_textelements

读程序文本元素(文本符号 / 选择文本 / 列表标题三类),支持语言覆盖

programName, language?

adt_read_function_module

读函数模块(SE37):完整源码 + 解析出的参数接口(IMPORTING/EXPORTING/CHANGING/TABLES/EXCEPTIONS)。不传 functionGroup 时经仓库搜索自动解析所属函数组

functionModule, functionGroup?

adt_list_function_group

列函数组的函数模块/包含程序:返回每个模块名、URI、描述,便于调用/读取前先发现组里有什么

functionGroup

写入(仅非只读模式注册)

工具

说明

关键参数

adt_write_source

AI 安全编辑编排:冲突检查 → 语法检查 → 锁 → 写 → 解锁(finally) → 可选激活

objectUri, source, transport?, syntaxCheck?, activate?, expectedCurrentSource?

adt_activate_object

激活对象(含未激活部分)

objectUri

adt_create_object

创建对象壳(无源码),返回 URI 供后续写入

objectType, name, description?, package?, transport?

adt_manage_transport

传输请求:create / release / list

action, objectUri?, description?, transport?, user?

adt_create_package

创建开发包(DEVC/K):包必须嵌套在真实父包下并继承其父包的软件组件+传输层,故必传 superPackage(真实客户包,如 ZRAP_TEST_192637,非 $TMP);softwareComponent/transportLayer 缺省从父包自动派生。abap-adt-apicreateObject 不支持包(且 createBodyPackage 硬编码 YMU_RAP),本工具改用 createObject 完整 options 实现。这是"统一包/请求决策流"的"创建包"分支——当某写入工具因未给包而返回澄清时,用本工具建包后回填。必填项确认name / superPackage / description 任一缺失时,本工具不报错、不猜测,而是返回 topic:"package_creation" 的结构化澄清(missingFields 列出缺项),Agent 与用户确认后携完整参数重调

name, superPackage, description, packageType?, softwareComponent?, transportLayer?, transport?

adt_create_domain

创建 DDIC 域(DOMA):骨架 → 锁 → PUT 技术属性(类型/长度/小数) → 解锁 → 可选激活。abap-adt-api 原生不支持域,本工具直接驱动 ADT REST 实现。传输绑定细节(已真机验证)$TMP(本地) 域全程不需 corrNr;非 $TMP必须绑定传输,且 POST 创建 / LOCK / PUT 三步都要带 corrNr=tr(因 AdtClient.lock 会丢弃第 3 个 corrNr 参数,故 LOCK/UNLOCK 走原始 h.requestcorrNr)。域的 XML 根类型须用 DOMA/DD(非 DOMA

name, description, datatype, length, decimals?, package?($TMP), transport?, activate?

adt_create_dataelement

创建 DDIC 数据元素(DTEL):引用已有域,技术类型(CHAR/长度/小数)自动从域派生;骨架 → 锁 → setObjectSource(XML) → 解锁 → 可选激活。字段标签长度默认 短10/中20/长40/标题55;传入文本更长时按实际长度(不截断),均不超过 SAP 物理上限

name, domain, description, package?($TMP), shortLabel?, mediumLabel?, longLabel?, headingLabel?, activate?

adt_create_table

创建 DDIC 透明表(TABL):ABAP 字典 DDL 源(define table { key 字段 : 类型; });骨架 → 锁 → setObjectSource(DDL, 端点 <uri>/source/main) → 解锁 → 可选激活。字段支持数据元素引用(推荐)、基本类型(CHAR/NUMC→char<len>、INT4/DATS…)、.INCLUDE 结构包含(include:true + type=结构名如 EMARA)、以及外键(foreignKey:{checkTable,...} 生成 with foreign key 子句)。默认自动补客户端字段 MANDT(数据元素 MANDT、外键检查表 T000、首个主键;autoClient:false 可关)。含基本类型 include 时增强类别自动升级为 EXTENSIBLE_ANY;全数据元素时默认 NOT_EXTENSIBLE。至少一个主键字段

name, description, package?($TMP), deliveryClass?, enhancementCategory?, dataMaintenance?, fields[](name,type,length?,decimals?,key?,notNull?,label?,include?,foreignKey?), autoClient?, activate?

adt_write_textelements

写程序文本元素:锁 textelements 资源 → PUT 三类(symbols/selections/headings) → 解锁 → 激活文本池。symbols 用 @MaxLength:N + key=value 格式;selections/headings 用纯 key=value。完整替换指定类别的文本池。⚠️ 文本池是 SAP 子对象 PROG/PX必须激活 textelements URI 自身(激活程序主对象 URI 激活不到它),否则运行时读不到文本——本工具默认已处理(activate 默认 true)

programName, entries[](category,key,text,maxLength?), language?, transport?, description?, activate?(默认 true)

adt_edit_source

surgical edit(token 优化):Agent 只发 {oldString,newString} 改动片段,工具读当前源码 → 逐个唯一性替换 → lock → write → unlock → 可选激活。对标 VSP EditSource,大对象改一处可省 90%+ 请求载荷

objectUri, edits[](oldString,newString), transport?, syntaxCheck?, activate?

adt_create_function_group

创建函数组(FUGR):在包(默认 $TMP)中建组并可选激活。函数模块必须属于某个函数组,故先建组。名需匹配 Z*/Y* 前缀

name, package?($TMP), description, transport?, activate?

adt_create_function_module

创建函数模块(FUGR/FF):在已存在函数组中建模块、写源码、可选激活。源码接受经典 FUNCTION z_fm. ... ENDFUNCTION. 形式(含可含 "* Local Interface 注释块)或归一化形式,自动归一化为 ADT 接受格式。建前守卫:组须存在

name, functionGroup, description, source, transport?, activate?

adt_write_function_module_source

编辑已有函数模块源码(lock → write → unlock → 可选激活)。接受经典或归一化源码,自动归一化。只读模式禁用,名需匹配 Z*/Y* 前缀。首次创建请用 adt_create_function_module

functionModule, source, functionGroup?, transport?, activate?

资源(Resources)

  • adt://system/info — 连接与角色信息

  • adt://packages/{pkg} — 包内容清单(JSON)


4. 安全模型(最重要)

ABAP 系统里误改 SAP 标准对象或留下悬空锁是真实风险。本设计内建四道防线:

  1. 只读模式ABAP_MCP_READONLY=true 时,13 个写入工具根本不注册(Agent 看不到),其余工具拒绝变更。

  2. 生产系统强制只读ABAP_MCP_SYSTEM_ROLE=prod 时,无论 READONLY 如何,一律只读。

  3. Z/Y 前缀白名单**:assertPrefixAllowed() 校验对象名,默认仅允许 Z,Y 前缀,杜绝误改 SAP 交付对象。

  4. 审计日志:每次写入追加 JSON 行到 ABAP_MCP_AUDIT_LOG,含时间、工具、对象、传输号、状态。

adt_write_source 的锁编排保证 try/finally 释放锁;即使写入失败也不会留下悬空锁。

4.1 统一「包 / 请求」决策流(所有写入工具共用)

每个写入工具在创建对象前,都要先决定目标开发包传输请求。逻辑统一由 tools/decisions.tsresolvePackageInput() / resolveTransportInput() 实现,规则如下:

包(package)决策

  1. 调用方显式给了 package → 直接绑定到该包(已大写上送)。

  2. 调用方没给 package → 工具返回一条结构化澄清needsClarification:truetopic:"package"),列出两个动作让 Agent 转问用户:

    • create_package — 调用 adt_create_package 新建一个真实包(需指定 superPackage 父包);该选项额外携带 requiredInputs:[name, superPackage, description],提示 Agent 必须先从用户处确认这三项必填信息再调建包工具。

    • keep_local — 落到本地包 $TMP(无需传输)。

传输请求(transport)决策(同样逻辑)

  1. 调用方显式给了 transport → 直接绑定。

  2. 包是 $TMP → 本地对象,不需要传输(resolveTransportInput 返回空串,后续调用不传 corrNr)。

  3. 包是非 $TMP 且没给 transport → 返回结构化澄清(topic:"transport"action:create_transport),由 Agent 经 adt_manage_transport(create) 建请求后回填。

设计要点:工具绝不静默默认到 $TMP 或自动建包——缺参数时一律返回 needsClarification,把选择权交还给用户,避免 Agent 在用户不知情的情况下把对象塞进本地包或误建包。澄清对象结构为 { needsClarification, topic, message, options:[{action,label,description,requiredInputs?}], missingFields?, tool, object }

  • topic:"package" / "transport" 的澄清:options 列出可行动作,Agent 转述给用户、回收选择后重新调用同一工具并补上 package / transport

  • topic:"package_creation" 的澄清(由 adt_create_package 自身返回):当 name / superPackage / description 任一缺失时返回,missingFields 列出缺哪些包必填项,Agent 与用户确认后用完整参数重新调用 adt_create_package。这一层保证「创建包前必与用户确认必填信息」,缺项时绝不猜测或崩溃。

  • 通用 topic:"missing_inputs" 澄清(仅「重型创建」类工具保留)adt_create_function_group(需 name/description)、adt_create_domain(需 name/description/datatype/length)、adt_create_dataelement(需 name/domain/description)、adt_create_table(需 name/description/fields)——这类工具自身有多个必填项、且参数结构较复杂,缺项时返回 missing_inputs 澄清missingFields 列出缺什么 + 中文 label + hint),由 decisions.tsinputClarification() 工厂统一生成,缺项检查在 handler 顶部、任何 SAP 调用之前完成。

  • 其余 8 个写入工具已还原为 Zod 必填校验(不再返回 missing_inputs 澄清):adt_write_sourceadt_activate_objectadt_create_objectadt_manage_transportadt_create_function_moduleadt_write_function_module_sourceadt_write_textelementsadt_edit_source。它们的必填字段(如 objectUri/source/edits/name/action 等)在 Zod schema 中声明为必填,缺项时由 MCP SDK 返回标准校验错误,而非结构化澄清。其中 adt_manage_transportaction=createobjectUriaction=releasetransport 仍由 handler 内显式 throw 校验(create/release 的条件性必填)。

真机验证结论verify_packages.mjsVERDICT: PASS):

  • 缺包 → 返回 topic=package 澄清;缺传输(非 $TMP)→ 返回 topic=transport 澄清;$TMP 路径无需传输。

  • adt_create_packageZRAP_TEST_192637 下建包,自动继承 softwareComponent=HOMEtransportLayer=ZS4C

  • adt_create_dataelement / adt_create_domain / adt_create_table 在显式 transport 下创建时,对象均正确绑定到该传输请求(域通过 POST/LOCK/PUT 全程带 corrNr 实现)。

  • ⚠️ 已知 SAP 限制:通过 ADT 创建的包(DEVC/K)因携带 SAP 自动生成的子对象,ADT 删除端点会报「仍然包含开发对象或其它包」而拒绝删除——这是 SAP 行为,非本 server 缺陷;验证脚本对包做尽力删除(不计入功能结论),残留测试包可在 SE21/SE80 手动清理。


5. 错误处理哲学

底层错误(ADT 业务异常 / 网络 / TLS / 锁冲突)被 translateError() 翻译成可让 Agent 自我纠正的中文信息,例如:

  • 证书错误 → 提示设置 SAP_SSL_REJECT_UNAUTHORIZED=false

  • 401/403 → 提示检查账号/客户端/是否被锁

  • 锁冲突 → 提示去 SM12 释放或重试

  • 语法错误 → 在 adt_write_source写前拦截并返回行号,不真正写入


6. 安装与配置

前置条件

  • Node.js ≥ 20(本项目用 22 验证)

  • 一个启用了 ADT 的 SAP ABAP 系统(SICF/sap/bc/adt 已激活,用户具 S_DEVELOP

步骤

git clone <this-repo> abap-adt-mcp && cd abap-adt-mcp
npm install
cp .env.example .env        # 填入 SAP_URL / SAP_USER / SAP_PASSWORD / SAP_CLIENT
npm run build               # 产出 dist/

配置文件名:服务器按以下优先级加载(后者不覆盖前者已设的值):

  1. MCP 客户端 env 块中直接传入的变量(最高优先级)

  2. 项目根目录的 .env

  3. 项目根目录的 MCP.env(本项目的约定文件名,便于与客户端配置共存)

所以把配置放在项目根的 MCP.env 即可被自动加载,无需改名。

.env / MCP.env 关键项:

SAP_URL=https://s4h.example.com:44300
SAP_USER=DEVELOPER
SAP_PASSWORD=*****
SAP_CLIENT=100
SAP_SSL_REJECT_UNAUTHORIZED=true     # 自签名证书开发环境设为 false
ABAP_MCP_SYSTEM_ROLE=dev             # prod 会强制只读
ABAP_MCP_READONLY=false
ABAP_MCP_ALLOWED_PREFIXES=Z,Y
ABAP_MCP_AUDIT_LOG=./abap-mcp-audit.log

接入 MCP 客户端(任选其一)

a) 任意客户端(npx,无需构建)

{
  "mcpServers": {
    "abap-adt-mcp": {
      "command": "npx",
      "args": ["-y", "abap-adt-mcp"],
      "env": {
        "SAP_URL": "https://...:44300",
        "SAP_USER": "DEVELOPER",
        "SAP_PASSWORD": "*****",
        "SAP_CLIENT": "100"
      }
    }
  }
}

b) 本地构建后(stdio)

{
  "mcpServers": {
    "abap-adt-mcp": {
      "command": "node",
      "args": ["/绝对路径/abap-adt-mcp/dist/index.js"],
      "env": { "SAP_URL": "...", "SAP_USER": "...", "SAP_PASSWORD": "...", "SAP_CLIENT": "100" }
    }
  }
}

调试可用:npm run inspect 启动官方 MCP Inspector。


7. 端到端使用示例

你: 读取 ZCL_INVOICE 的源码并加一个方法,然后激活。

Agent 内部流程:
1. adt_search_objects  query="ZCL_INVOICE"        → 拿到 objectUri
2. adt_read_source     objectUri=...              → 当前源码
3. adt_syntax_check    source=<新源码>             → 预校验(写前拦截错误)
4. adt_write_source    objectUri=... source=<新> activate=true
      内部: 解析传输 → 语法检查 → lock → setObjectSource → unlock(finally) → activate
5. 返回 { written:true, transport:"NPLK900123", activated:true, success:true }

8. AI Token 优化

三类策略降低 Agent 与 SAP 交互时的 token 开销(对标 VSP 的方法级手术 + 上下文压缩):

8.1 Surgical edit(写入侧,adt_edit_source

Agent 只发 {oldString, newString} 改动片段,不发整个对象源码。工具内部读当前源码 → 逐个替换(要求 oldString 唯一匹配,否则报错并提示加上下文消歧)→ 走 lock/write/unlock/activate 编排。对 2000 行类改一个 5 行方法,请求载荷省 90%+。

8.2 方法级读取定位(读取侧,adt_get_object_structure 增强)

对类返回每个 include(definitions/implementations/main/testclasses)的 sourceUri + 方法/属性清单(name + visibility)。Agent 拿到 include sourceUri 后用 adt_read_source 只读单个 include(如只读实现部分),配合行范围切片定位到具体方法,避免读整个类。

8.3 源码压缩 prologue(读取侧,adt_read_sourceattachContext

attachContext=true 时,解析源码中 TYPE/LIKE 引用的 DDIC 对象名(排除 ABAP 内置类型),逐个查 domain/data element 端点取一行摘要(NAME DATATYPE(LENGTH)),附加为 prologue。上限 12 个对象,避免过多调用。Agent 一次读源码即可获得所有引用类型的概要,省去逐个查 DDIC 的往返。


9. 扩展点

  • ATC 质量门禁:调用 abap-adt-api 的 ATC 接口,在 adt_write_source 中加一道 run_atc_check

  • 单元测试runUnitTest(url) 接入 adt_activate_object 之后的 CI 流。

  • BTP OAuth2 + PKCEabap-adt-api 支持传入 BearerFetcher,可替换账号密码登录(参考 @abapify/adt-cli 的 service-key 流程)。

  • Streamable HTTP:用 FLUJO 或 mcp-proxy 把 stdio 服务暴露为 HTTP,供远程 Agent 调用。

  • Git/abapGitabap-adt-api 已支持 gitRepos / stageRepo / pushRepo,可加 adt_git_* 工具。


10. 目录结构

abap-adt-mcp/
├─ package.json
├─ tsconfig.json
├─ .env.example
├─ README.md
└─ src/
   ├─ index.ts              # 入口:建 McpServer、注册、连接 stdio
   ├─ config.ts             # 环境变量 + 安全默认值
   ├─ adt/
   │  ├─ client.ts          # ADTClient 单例 + 每操作封装
   │  ├─ errors.ts          # 错误翻译
   │  └─ security.ts        # 只读/白名单/审计
   ├─ tools/
   │  ├─ index.ts           # 聚合注册(按只读模式决定写入工具)
   │  ├─ read.ts            # 11 个只读工具(含 attachContext prologue + 方法级定位增强)
   │  ├─ write.ts           # 4 个写入工具(含 lock 编排)
   │  ├─ ddic.ts            # 2 个 DDIC 创建工具(域 / 数据元素)
   │  ├─ table.ts           # 1 个 DDIC 创建工具(透明表)
   │  ├─ package.ts         # 1 个 DDIC 创建工具(包 DEVC/K,含父包属性继承)
   │  ├─ textelements.ts    # 文本元素读写(adt_read_textelements + adt_write_textelements)
   │  ├─ edit.ts            # surgical edit 工具(adt_edit_source, token 优化)
   │  ├─ decisions.ts       # 统一 包/请求 决策(resolvePackageInput / resolveTransportInput + 澄清结构)
   │  ├─ util.ts            # safe() / textResult / jsonResult 公共工具
   │  └─ util.ts            # 结果格式化 + safe() 包裹
   └─ resources/
      └─ index.ts           # system info / package 资源

10. 验证状态

  • npm run build 通过(TypeScript 严格模式,零错误)

  • ✅ stdio 冒烟测试通过:MCP initializetools/list 返回 24 个工具(11 只读 + 13 写入);adt_ping 在未配置 SAP 时返回 isError 而非崩溃

  • ✅ 真实 S/4HANA 联调:adt_create_dataelement 创建引用 YTEST_192637 的数据元素成功并激活(datatype=CHAR, length=11);存在性守卫与坏域守卫均优雅报错

  • ✅ 真实 S/4HANA 联调(函数模块):verify_functions.mjs 全绿(VERDICT: PASS)——读 BAPI_USER_GET_DETAIL(44 参数)、列 ZAIRFC_TOOLS(5 模块)、建组 ZFMCPV2_192637 并激活、建模块 ZFMCPV2_FM(经典含 "* 注释块源码被自动归一化并激活)、读回解析出 IV_NAME/EV_GREETING、编辑加 CHANGING CV_COUNTER 并激活、清理删除成功。关键结论:ADT 拒绝经典 FUNCTION z_fm. 尾点形式与 "* Local Interface 注释块,本 server 的 normalizeFmSource() 已将其转换/重写为 ADT 接受的 function name + 小写接口块 + 独立 . + endfunction. 形式

  • ✅ 真实 S/4HANA 联调(统一包/请求决策流):verify_packages.mjs 功能全绿(FUNCTIONAL VERDICT: PASS)——24 工具齐全且含 adt_create_package;缺包→返回 topic=package 澄清、缺传输(非$TMP)→返回 topic=transport 澄清、$TMP 路径无需传输;adt_create_package 缺必填项时返回 topic=package_creation 澄清并列出 missingFields(name/superPackage/description),创建包前必与用户确认必填信息adt_create_packageZRAP_TEST_192637 下建包继承 HOME/ZS4Cadt_create_dataelement / adt_create_domain / adt_create_table 在显式 transport 下均正确绑定该请求。清理阶段子对象可正常删除,包本身因 SAP「自动子对象」限制无法经 ADT 删除(已知限制,不计入功能结论)


11. 部署到其他电脑(便携分发)

本服务器源码可移植config.tsfileURLToPath(import.meta.url) 解析项目根绝对路径读取凭证,不依赖启动时的 cwd,因此放到任意目录、任意电脑都能自定位。跨机器只需处理三件事:依赖、路径、凭证

一键打包脚本 deploy.bat(推荐,零手敲命令)

仓库根目录已提供 deploy.bat,双击或命令行运行即可自动完成「重建 dist → 打包为 abap-adt-mcp-dist.zip」,且自动排除凭证与日志MCP.env / .env / *.log / *.err / *.mjs),保留 node_modules/ + dist/,对方免装免构建。

deploy.bat        :: 在本机项目根目录运行;产物 abap-adt-mcp-dist.zip 自动生成

实现要点:用 %~dp0 自定位项目根(不硬编码路径),robocopy /XF 排除敏感文件后 Compress-Archive 压缩,兼容老版本 PowerShell(不依赖 -Exclude 参数)。对方拿到 zip 后从下方「方式 A 第 2 步」继续即可。

方式 A:零安装便携包(推荐给同事,最直接)

  1. 打包:在本机把整个项目目录压缩,排除 MCP.env*.log(含真实密码,切勿外传)。已带的 node_modules/(≈54M) 和 dist/ 让对方免安装、免构建。

    # Git Bash / PowerShell
    zip -r abap-adt-mcp.zip abap-adt-mcp -x "abap-adt-mcp/MCP.env" -x "*.log"
  2. 对方解压到任意目录,例如 D:/tools/abap-adt-mcp

  3. 填凭证:复制 .env.exampleMCP.env,填入对方自己的 SAP 账号:

    cp .env.example MCP.env   # 编辑 MCP.env,填 SAP_URL/SAP_USER/SAP_PASSWORD/SAP_CLIENT
  4. 加 MCP 配置:在对方机器的 ~/.workbuddy/mcp.json(或其他客户端配置)加:

    {
      "mcpServers": {
        "abap-adt-mcp": {
          "command": "node",
          "args": ["D:/tools/abap-adt-mcp/dist/index.js"],
          "cwd": "D:/tools/abap-adt-mcp",
          "env": { "ABAP_MCP_READONLY": "false" }
        }
      }
    }
    • commandnode(要求对方 node 在 PATH,Node ≥ 20);若想彻底免装 node,把 node.exe 也放进包、command 指向 ./node.exe

    • 必须把路径改成对方机器上的实际位置(本项目 mcp.json 里硬编码的绝对路径在别的电脑不存在)。

    • 凭证不必写进 env——服务器会自动读项目根下的 MCP.env

  5. 启用:在 WorkBuddy 连接器管理页右上角「自定义连接器」点新 server 的 Trust

方式 B:源码分发(目标机自行安装,包体最小)

对方拿到 src/ + package.json + .env.example,然后:

cd abap-adt-mcp
npm install          # 拉取依赖
npm run build        # 产出 dist/
cp .env.example MCP.env   # 填凭证

之后同方式 A 第 4–5 步配置并 Trust。

其他 MCP 客户端

配置结构相同,只是文件位置不同:

  • Claude Desktop%APPDATA%/Claude/claude_desktop_config.json

  • Cursor / VS Code:对应 mcp.json

  • npx 一行版(无需本地构建,但每次拉包):

    { "mcpServers": { "abap-adt-mcp": { "command": "npx", "args": ["-y", "abap-adt-mcp"], "env": { "SAP_URL":"...", "SAP_USER":"...", "SAP_PASSWORD":"...", "SAP_CLIENT":"100" } } } }

安全提醒

  • 永远不要分发 MCP.env:它含明文 SAP 密码。用 .env.example 作模板,让每台机器填自己的凭证。

  • 生产系统把 ABAP_MCP_SYSTEM_ROLE=prod(强制只读)或 ABAP_MCP_READONLY=true,写工具会被隐藏且拒绝变更。

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/abap0917/abap-adt-mcp'

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