关于 abap2UI5
abap2UI5 的 MCP 服务为 AI 编码 Agent 提供本地开发流程,可在无需 SAP 系统的情况下构建、验证、预览和运行 abap2UI5 应用。它结合视图检查与截图、后端构建和浏览器测试。
主要功能
- 01验证并修复视图
- 02生成视图截图
- 03搜索指南、示例和问题目录
- 04部署应用并构建后端
- 05运行应用、交互和单元测试
适用场景
- 01开发应用时检查 ABAP 视图
- 02查看渲染后的视图截图
- 03无需 SAP 系统构建并运行应用
- 04查阅示例和框架指南
MCP 相关
该项目是 MCP 服务,向 MCP 客户端提供 abap2UI5 开发工具,包括视图验证、截图、部署、后端构建和应用运行。它通过 stdio 注册到客户端。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @abap2ui5/mcp-serverAI_VIEW_CHECK_HOMECheckout or install of @abap2ui5/linter (validate_view, fix_view, screenshot_view). Default: the peer npm installs beside the server. A set value is authoritative.A2UI5_HOMEabap2UI5 framework checkout (app_guide, api_reference, pitfalls; backend when present). Default: ../abap2UI5, else the GitHub mirror and the npm runtime.SAMPLES_CONTROLS_HOMEsamples-controls checkout (capabilities, examples, generation_rules, scope_of, UI5 for screenshots). Default: ../samples-controls, else the GitHub mirror.SAMPLES_HOMEabap2UI5/samples checkout, one of the catalogues examples searches. Default: ../samples, else the GitHub mirror.SAMPLES_STACK_HOMEabap2UI5/samples-stack checkout (OData, RAP, APC, launchpad samples). Default: ../samples-stack, else the GitHub mirror.APP_TEMPLATE_HOMEabap2UI5/app-template checkout that scaffold_app serves and add_agent_setup executes. Default: ../app-template, else the GitHub mirror.DOCS_HOMEabap2UI5/docs checkout that docs_search reads. Default: ../docs, else the GitHub mirror.ABAP_CLOUD_GUI_HOMEabap2UI5-addons/abap-cloud-gui checkout (with npm ci done) whose report2cloud converter migrate_report runs. Default: ../abap-cloud-gui; no mirror.POPUPS_HOMEabap2UI5-addons/popups checkout whose popups migrate_report with deploy: true writes into the dev sandbox beside the converted class. Default: .deps/popups of the abap-cloud-gui checkout, ../popups beside it, then its build/popups.OPENUI5_SRCOpenUI5 source checkout scope_of reads the JSDoc from (via samples-controls). Default: ../fork-openui5 next to samples-controls.A2UI5_MCP_WORKSPACEWhere the npm backend installs, the dev sandbox lives and a framework clone lands. Default: ~/.abap2ui5-mcp.A2UI5_MCP_BACKENDWhich backend runs the apps: npm (the @abap2ui5/node-runtime package, even beside a checkout) or clone (clone the framework). Default: decided per call.A2UI5_MCP_RUNTIME_VERSIONPin the @abap2ui5/node-runtime release (X.Y.Z) the npm backend installs. Default: the registry's latest.A2UI5_MCP_PORTPort of the local backend run_app boots against. Default: 3000.A2UI5_MCP_UIWhether app_start/app_describe/app_act declare their MCP Apps screen (ui://abap2ui5/app-screen): auto (default - when the client advertises the io.modelcontextprotocol/ui extension), on, off.A2UI5_MCP_APP_FORMATThe default answer format of the app tools: snapshot (default) or adaptive-card (the snapshot plus an Adaptive Card 1.5 as an embedded resource, for card-rendering hosts).A2UI5_MCP_OFFLINESet to 1 for no network: no UI5 CDN fallback, no GitHub mirror, no registry lookup.A2UI5_MCP_REMOTESet to 0 to switch off the read-only GitHub mirror used when no checkout is found.A2UI5_MCP_REMOTE_DIRCache directory of the GitHub mirror. Default: <tmp>/abap2ui5-mcp-remote.A2UI5_MCP_REMOTE_TTL_MSHow long a mirrored copy is used before it is refreshed, in milliseconds. Default: one day.A2UI5_MCP_UI5_CACHE_MBHow many MB of UI5 answers from the CDN (sdk.openui5.org) run_app and interact_app keep in memory across calls, so a second boot does not download them again. 0 switches the cache off. Default: 64.A2UI5_MCP_RENDER_PAGESPages (Chromium tabs) of validate_view's warm render gate, which concurrent calls queue on. Default: 2 (1 to 8).A2UI5_MCP_CHROMIUMChromium binary for run_app and interact_app. Default: CHROMIUM_BIN, Playwright's managed browser, then a system chromium.A2UI5_MCP_SCREENSHOT_DIRWhere run_app and interact_app write their PNGs (the newest 50 are kept) and build_backend its log. Default: <tmp>/abap2ui5-mcp-screenshots.A2UI5_MCP_PREBUILT_URLWhere build_backend mode prebuilt downloads the backend from. Default: the framework's release asset.A2UI5_MCP_LINT_WORKERSet to 0 to run every lint as a fresh abaplint process. Default: a long-lived worker keeps @abaplint/core with the framework parsed and lints a deploy in milliseconds (the CLI runs whenever the worker cannot stand in for it).A2UI5_MCP_LINT_IDLE_MSHow long the warm lint worker (about 300 MB with the framework parsed) is kept without a request before it exits, in milliseconds; the next lint starts a fresh one. 0 keeps it for the server's life. Default: 10 minutes.A2UI5_MCP_LINT_TIMEOUT_MSHard timeout of the abaplint run, in milliseconds. Default: 5 minutes.A2UI5_MCP_SCOPE_TIMEOUT_MSHard timeout of scope_of, in milliseconds. Default: 5 minutes.A2UI5_MCP_BUILD_TIMEOUT_MSHard timeout of a build, the prebuilt download and the npm install, in milliseconds. Default: 30 minutes.A2UI5_MCP_UNIT_TIMEOUT_MSHard timeout of the ABAP Unit runner, in milliseconds. Default: 10 minutes.A2UI5_MCP_SYSTEM_URLSwitches on the SYSTEM MODE: the app tools against this real SAP system instead of the sandbox loop. The launch URL, e.g. https://host:44300/sap/bc/z2ui5?app_start={class}&sap-client=100.A2UI5_MCP_SYSTEM_USERSystem mode: the SAP user the app tools log on with (Basic authentication).A2UI5_MCP_SYSTEM_PASSWORD密钥System mode: the password of A2UI5_MCP_SYSTEM_USER. Or A2UI5_MCP_SYSTEM_PASSWORD_CMD, to keep it out of the configuration.A2UI5_MCP_SYSTEM_PASSWORD_CMD密钥System mode: a shell command that prints the password (a keychain lookup) - instead of A2UI5_MCP_SYSTEM_PASSWORD.A2UI5_MCP_SYSTEM_INSECURE_TLSSystem mode: set to 1 to accept a certificate that cannot be verified. NODE_EXTRA_CA_CERTS with the CA is the better fix.GITHUB_TOKEN密钥Optional token sent to api.github.com only, to raise the rate limit of the docs tree listing (GH_TOKEN is read too).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
30收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
mcp-server
abap2UI5 的 MCP 服务——让任何 AI 编码 Agent(Claude Code、 Cursor、VS Code Copilot 或任何 MCP 客户端)都能完整使用 abap2UI5 开发 循环,无需 SAP 系统:
examples -> app_guide -> validate_view + screenshot_view -> deploy_app -> build_backend -> run_app -> pitfalls
(has somebody (how an app (SECONDS, no system: (write ABAP, (transpile (boot headless, (what a green
built it is built) is the view legal, lint) to Node) errors + run still
already?) and what does it LOOK like) SCREENSHOT) does not prove)
Agent 编写 ABAP 类,验证视图,并查看视图图片,只需几秒;随后部署视图,在真实浏览器中启动并查看运行中的应用,然后继续迭代。所有操作都在本地运行,使用的基础设施已在 CI 中为 abap2UI5 生态系统提供保障:abaplint 转译器 + open-abap 运行时、框架的 express shim、 samples-controls 构建和启动 检查,以及 linter 验证核心。
文档
→ 完整介绍 MCP 服务 ——此处 MCP 的含义、三个配置级别分别提供什么、如何向客户端注册服务、每个工具能为 Agent 提供什么,以及它们的预期使用流程。
→ 使用 AI 构建 — 按投入从低到高介绍完整的 AI 配置。此服务是最高一级;应先了解成本更低的选项。
快速开始
一键安装
每个按钮都会注册同一个名为 abap2ui5 的 stdio 服务:
{"command":"npx","args":["--yes","-p","@abap2ui5/mcp-server","abap2ui5-mcp"]}
这些徽章通过 Web 重定向跳转,因为 GitHub 不会渲染指向编辑器自有 URL 方案的链接;以下是可粘贴到浏览器中或用于
xdg-open/open 的直接链接:
vscode:mcp/install?%7B%22name%22%3A%22abap2ui5%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22--yes%22%2C%22-p%22%2C%22%40abap2ui5%2Fmcp-server%22%2C%22abap2ui5-mcp%22%5D%7D
cursor://anysphere.cursor-deeplink/mcp/install?name=abap2ui5&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyItLXllcyIsIi1wIiwiQGFiYXAydWk1L21jcC1zZXJ2ZXIiLCJhYmFwMnVpNS1tY3AiXX0%3D
(Insiders 使用 vscode-insiders: 替代 vscode:。)Claude Code:
claude mcp add abap2ui5 -- npx --yes -p @abap2ui5/mcp-server abap2ui5-mcp
Claude Code 插件。 abap2UI5 插件将框架的 Agent 技能(构建应用、ABAP 和 UI5 陷阱目录、视图链布局等)与此服务打包在一起,并按照上文相同的方式注册——一次安装即可获得两者:
/plugin marketplace add abap2UI5/abap2UI5
/plugin install abap2ui5@abap2ui5
从 1.0.0 起发布的版本也列在官方 MCP Registry 中,名称为
io.github.abap2UI5/mcp-server(server.json),供从 Registry 安装的客户端使用。Smithery(smithery.yaml)和
Glama(glama.json)目录也列出相同的命令:一个 npm 包、一个版本,客户端读取哪个目录都可以。
这就是下文的第 1 级:validate_view 和 fix_view 开箱即用,而
setup_status 会告知 Agent 此设备上还有哪些功能可用,以及缺少什么。
每种安装方式包含什么
第 1 级 — validate_view、fix_view 和 screenshot_view,大多数工作都围绕这些工具展开。它们需要 linter,服务器将其声明为对等依赖项(@abap2ui5/linter,>=0.8.0 <0.10.0——这是此服务器构建时所针对的版本范围)。npm 7+ 会自动安装非可选的对等依赖项,因此下面这条命令会一并安装 linter,让 validate_view/fix_view 开箱即用。screenshot_view 背后的渲染关卡还需要 UI5 库和 Playwright(@abap2ui5/linter-render 被声明为可选对等依赖项:会注明兼容版本范围,但不会为你安装该包——请预留 约 150–200 MB 空间,并做好首次安装需要几分钟的准备):
claude mcp add abap2ui5 -- npx --yes -p @abap2ui5/mcp-server abap2ui5-mcp # validate_view, fix_view
claude mcp add abap2ui5 -- npx --yes -p @abap2ui5/mcp-server -p @abap2ui5/linter-render abap2ui5-mcp # + screenshot_view
服务器会按以下顺序查找 linter:AI_VIEW_CHECK_HOME;服务器旁边的 linter 检出目录(npx 运行时,npm 也会将对等依赖项安装在这里:node_modules/@abap2ui5/{mcp-server,linter});启动服务器时所在的项目(node_modules/@abap2ui5/linter——app-template 将其列为 devDependency,因此只需在该目录下运行 npm install);服务器自身的 node_modules;以及 Node 从服务器所在位置解析到的模块。设置了环境变量时,将只按其指定的位置查找。也可以从检出目录运行:
git clone https://github.com/abap2UI5/linter # AI_VIEW_CHECK_HOME
cd linter && npm ci
服务器本身发布在 npm 上,因此无需检出代码;上面的注册命令就是完整的安装步骤。(如果使用 npm 6 或 --legacy-peer-deps,请自行添加 -p @abap2ui5/linter。)
(-p … abap2ui5-mcp 会显式指定 bin,每个已发布版本都支持这种写法。较短的 npx --yes @abap2ui5/mcp-server 需要一个以包名命名的 bin,而 0.2.0 及更早版本都没有,因此 npx 会报错“could not determine executable to run”并停止。)
(安装包约 47 MB:其中 19 MB 是仅供 run_app 使用的 Playwright 驱动,linter 占 2 MB——首次启动时需要下载,之后会缓存。也可以从检出目录开始:git clone https://github.com/abap2UI5/mcp-server && cd mcp-server && npm ci,然后运行 claude mcp add abap2ui5 -- node /path/to/mcp-server/server.mjs。)
Cursor、VS Code 和 Claude Desktop 都采用标准的 stdio 配置格式——文档中提供了 JSON 配置,以及后续两个级别的内容(示例目录和部署,以及无头构建与启动循环)。如果缺少某项工具的前置条件,该工具会回复一条说明所需条件的消息;无论如何,服务器都会启动。
abap2UI5 VS Code 扩展会为你注册此服务器,并额外添加一个自有服务器,用于需要连接真实 SAP 系统的工具。
一条命令完成所有设置——对于专门用于完整构建与启动循环的机器(或 Codespace),setup.sh 会在此仓库旁边检出框架、语料库和 linter,安装它们的依赖项以及无头浏览器(会复用现有检出目录,可安全地重复运行):
git clone https://github.com/abap2UI5/mcp-server && ./mcp-server/setup.sh
setup.sh --no-corpus 只会检出框架和 linter;由于框架沙箱已存在,这就是开发自有应用所需的完整循环。语料库用于 scope_of、完整构建和本地托管的 UI5。
在检出目录中启动的 Claude Code 会通过已提交的 .mcp.json 自动发现服务器;devcontainer 则会在创建时运行同一套设置流程。
级别 0 — 完全无需克隆。 知识工具(app_guide、
api_reference、pitfalls、capabilities、examples、read_example、
docs_search、scaffold_app、generation_rules)读取已提交的文件,因此
当无法解析到克隆目录且未设置环境变量时,它们会改为从 GitHub 读取:文件会放入按用户隔离的缓存(<tmp>/abap2ui5-mcp-remote,按天缓存;仅当该目录由用户本人创建且权限为 0700 时才使用;A2UI5_MCP_REMOTE_DIR 可更改其位置),服务会将其视为只读克隆;add_agent_setup
也会从那里读取模板,但只会写入提供给它的项目中。并且
耗时的部分由 npm 包 @abap2ui5/node-runtime(见下文)运行,因此在全新项目中执行
npx --yes -p @abap2ui5/mcp-server abap2ui5-mcp,也能使用
deploy_app、build_backend、run_app、interact_app、run_unit_tests
和 verify_app,无需克隆任何内容。仍需克隆的是语料库相关功能(scope_of、build_backend 的 full 模式,以及本地托管的 UI5)。A2UI5_MCP_REMOTE=0 或 A2UI5_MCP_OFFLINE=1 可关闭镜像。文档镜像通过 GitHub 的 API 列出页面,每个地址每小时最多可进行 60 次未经身份验证的请求;在环境中设置 GITHUB_TOKEN(或 GH_TOKEN)可提高此限制,并且该令牌只会发送到 api.github.com。
无需框架克隆的后端:@abap2ui5/node-runtime。
框架已在 npm 上发布为转译后的版本,并包含同一发布提交中的 ABAP 源码,可用于转译应用。在没有 abap2UI5 克隆(且未配置克隆路径)时,build_backend 会为每个版本将该包安装一次到 ~/.abap2ui5-mcp/runtime/<version>,其中包含包指定的转译器、express,以及 app-template 的 abaplint(用于 lint),所有依赖均使用锁文件固定到精确版本,并添加 --ignore-scripts;随后会获取构建该版本时使用的 open-abap-core 提交,再基于它仅转译已部署的应用:耗时数秒,而非转译整个框架。deploy_app 会写入 ~/.abap2ui5-mcp/sandbox(并使用 app-template 自带的配置,基于该包的源码执行 lint),run_app 会启动注册了这些应用的包内服务器,run_unit_tests 会运行应用自带的测试。除非通过 A2UI5_MCP_RUNTIME_VERSION 固定版本,否则使用注册表中的最新版本(通过 npm 查询,每天缓存一次)。此处在 npm 缓存为空时测得:首次安装约 10 秒,open-abap-core 约 1 秒,之后每次构建需 7–8 秒,单元测试约需 1 秒。setup_status 会显示版本、工作区以及下次构建将执行的操作。
有框架克隆时(A2UI5_HOME 或同级目录),一切照常运行:build_backend 首次会将预构建后端(backend-<version>.tar.gz)下载到克隆目录,之后会从其中的 node/zz_dev 重新转译已部署的应用。在有克隆目录时,A2UI5_MCP_BACKEND=npm 会使用旁边的 npm 包;build_backend 的 prebuilt 模式(或 A2UI5_MCP_BACKEND=clone)则会将该版本克隆到 ~/.abap2ui5-mcp/abap2UI5 —— 在该包出现之前,此服务在没有克隆目录时使用的路径。对于未发布的提交,仍可使用完整语料库构建,设置 mode: "full" 即可。
工具
每个工具都会从同级克隆目录读取实时内容,且每个工具都需要特定的同级目录——不存在“可选”仓库,只有你会不会用到的工具。需要列说明了某个工具缺少哪种克隆目录就无法运行:只有 linter 提供 validate_view、fix_view 和 screenshot_view(快速迭代环节,也是大多数迭代发生的地方——它也是 npm 安装服务时唯一安装的依赖,作为服务声明的 peer);框架克隆目录提供指南、常见问题和接口(缺少时,这三者都会从 GitHub 镜像);npm 包 @abap2ui5/node-runtime 在没有框架克隆目录时提供后端;语料库则提供几乎所有其他内容。若工具所需的克隆目录缺失,它会给出用于解决问题的克隆命令和环境变量。
| 工具 | 功能 | 依赖 |
|---|---|---|
setup_status | 查看哪些内容可用、已构建、缺失以及如何修复——一次读取,首先调用 | 无 |
capabilities | 根据已验证的能力映射,判断 abap2UI5 是否能实现某项 UI5 功能 | samples-controls |
app_guide | 如何构建应用,内容实时取自框架检出目录 | abap2UI5 |
api_reference | 客户端 API(z2ui5_if_client)及其 ABAP-Doc:方法、参数、默认值、cs_* 常量 | abap2UI5 |
scaffold_app | 新项目的起始文件,实时取自 app-template;通过 { class: … } 全面重命名,并包含旁置文件 CLSNAME | app-template |
add_agent_setup | 为现有项目设置 AI 工作环境——说明 npm create abap2ui5-app -- --agent-setup 的作用:将 AGENTS.md、技能、.mcp.json、允许列表、两道门禁和 CI 作业写入 project_dir;不会覆盖文件,会合并 package.json/.gitignore,并遵循 STARTING_FOLDER | app-template |
examples | 搜索三个示例目录,并提供验证状态等信息——返回可供阅读的类,而不是不可信的代码片段 | samples / samples-controls / samples-stack 中任意一个(或 GitHub 镜像) |
read_example | 从检出目录读取 examples 命中的示例源代码,或从 GitHub 获取 | 示例所在的仓库(或 GitHub 镜像) |
docs_search | 对文档网站页面进行全文搜索:页面、标题、片段和已发布的 URL | docs |
generation_rules | 将 UI5 demo-kit 示例移植到 samples-controls 的规则手册 | samples-controls |
pitfalls | 绿灯运行检测不到的问题:{ area: "abap" } 和 { area: "view" } | abap2UI5 |
scope_of | 判断某个 UI5 控件是否在范围内 | samples-controls + OpenUI5 检出目录 |
validate_view | 几秒内运行 lint 检查门禁,并依据项目自身的 abap2ui5lint.jsonc 进行判定 | linter |
fix_view | 应用 lint 的机械修复并返回修正后的源代码——不会写入任何内容 | linter |
screenshot_view | 几秒内查看视图——无需构建,也无需后端 | linter |
deploy_app | 将类、abapGit 旁置文件(及测试 include)写入开发沙箱,然后运行 abaplint | 无(npm 后端的 ~/.abap2ui5-mcp/sandbox);若存在,则使用 samples-controls 的 src/zz_dev 或 abap2UI5 的 node/zz_dev |
read_app | 读取已部署开发应用的源代码,并检查构建后的后端是否已包含该应用 | 沙箱(同 deploy_app) |
build_backend | 获取转译后的 Node 后端:没有检出目录时,从 npm 获取 @abap2ui5/node-runtime,且只转译开发应用(几秒内完成);有检出目录时,prebuilt 会下载框架已发布的后端,incremental 会在其基础上重新转译开发应用;按需执行 prebuilt/transpile 时会克隆框架;full 会运行语料库的 e2e-build | 无(npm),或 abap2UI5(full 需要 samples-controls) |
build_log | 分页查看上次构建的完整输出——包括结果简短尾部中被截断的错误 | 无(读取上次构建留下的记录) |
run_app | 无头启动应用:查看状态、真实页面错误和截图 | 需要构建(npm 后端或 abap2UI5 检出目录);若存在,samples-controls 会在本地提供 UI5,否则使用 CDN |
interact_app | 启动应用后,通过简短脚本点击、填写、按键并等待——拍下事件分支 | 需要构建(同 run_app) |
app_list | 列出构建后的后端能够启动的应用类——已部署的开发应用和框架自身的应用 | 需要构建(npm 后端或 abap2UI5 检出目录) |
app_start | 启动应用并获取其Agent 快照:字段(路径、标签、类型、值)、操作(事件 + 参数)、表格、消息——通过 abap2UI5 JSON 协议,无需浏览器;在 MCP Apps 宿主中还可显示交互屏幕,使用 format: "adaptive-card" 时还会返回 Adaptive Card | 需要构建(同 run_app) |
app_describe | 从内存中获取会话当前的 Agent 快照——无需往返请求 | 来自 app_start 的会话 |
app_act | 填写字段并按名称触发事件——依据快照验证,以真实模型增量发送——然后获取下一份快照 | 来自 app_start 的会话 |
run_unit_tests | 在 open-abap 运行时中运行已部署应用的测试类(在检出目录上也可运行整个转译树):验证断言,而非查看图片 | 需要构建(npm 后端或 abap2UI5 检出目录) |
verify_app | 一次调用完成整个流程——依次验证、部署、构建、运行单元测试、启动应用,并在首个失败阶段停止 | 各阶段所需的依赖 |
migrate_report | 将经典 ABAP 报表转换为 abap-cloud-gui 应用类(report2cloud):生成类文件、迁移报告(TODO、带替代项的未发布表)和拒绝项(file:row:col);deploy: true 会在此处构建,并返回其选择屏幕的 Agent 快照 | abap-cloud-gui(需运行 npm ci);deploy 还需要弹窗和构建 |
backend | 对本地 express 后端执行 status / start / stop / restart | 需要构建(start/restart;status 和 stop 始终可用) |
remove_app | 从沙箱中删除开发应用,或列出已部署的应用 | 沙箱(同 deploy_app) |
verify_app 是一次调用内的循环:依次进行校验、部署、构建、单元测试和启动,在第一个失败的阶段停止,并报告此前的每个阶段。interact_app 是带操作的 run_app:启动后,它会按一段简短脚本点击、填写并按键,然后拍摄结果;这样无需系统,应用的事件分支也能显现出来;run_unit_tests 会在 open-abap 运行时中运行 deploy_app 写在应用旁边的测试类(本地的 z2ui5_if_client 替身,参见应用指南第 9 章),并用断言作答。 |
scaffold_app 和 add_agent_setup 都会执行 app-template 自带的 template.json,分别用于两种项目。scaffold_app 会返回一个完整的新项目,包括应用类,但不会写入任何内容。add_agent_setup 面向已存在的 abapGit 仓库——其中大多数项目并非从模板开始——它会按照模板的 agentSetup 键,在该仓库中执行 npm create abap2ui5-app -- --agent-setup 的操作:将 Agent 配置和两个门禁写入 project_dir(默认值:服务器的工作目录;如果该目录看起来像项目),绝不覆盖项目中已有的文件(每个文件都会列为已跳过),只补充缺失内容来合并 package.json 和 .gitignore(每个与模板不同且保留的值都会作为警告列出),将配置指向 .abapgit.xml 中命名的源文件夹,并且不会写入该文件。再次运行不会有任何更改;dry_run: true 会返回相同的报告,但不写入任何内容。所有写入路径都来自模板的文件列表,并会预先检查:必须是普通相对路径、属于模板的共享文件且位于源文件夹之外;任何一项不符合都会在写入任何内容之前拒绝整个调用。绝不会通过符号链接或指向项目外部的文件夹进行写入:相应文件会被跳过,答复会说明原因。
每个答复都适配客户端。 客户端不会向 Agent 显示超过上限的工具结果(Claude Code:25,000 个 token),因此任何答复都不会超过约 60,000 个字符。答复会随上游内容增长的工具会分页,而不是截断:matches 统计所有匹配项,returned 表示当前页,more 给出获取剩余内容的准确调用方式(offset 适用于 examples、capabilities、api_reference、app_guide、pitfalls、docs_search;files 适用于 scaffold_app;from_line 适用于 read_app、read_example;build_log 会在 cut 下给出下一页的 offset)。被缩短而非分页的列表会在 ...Cut 字段中说明(findingsCut、rulesCut、errorsCut 等),最后一道保护措施还会裁剪任何仍超过上限的内容,并标记为 __answerGuardCut。资源也遵循同一上限(见下文)。
examples 会按目录逐个降级处理,而不是直接失败:它会搜索找到的检出目录,并列出未能检索的目录,因此较少的结果不会让人误以为“没有人构建过这个”。只要检出目录中存在已提交的 catalogue.json,它就会读取该文件——其中包含控件端口的验证状态(排序相同时,依次优先 checked、reviewed、generated)、学习路径阶段,以及栈样例所需的系统内容;若检出目录来自该文件出现之前,则会回退到解析 SAMPLES.md。如果 samples 和 samples-controls 在旁边提交了 catalogue-derived.json,查询也会匹配每个样例视图所构建的控件类型,因此搜索 sap.m.Dialog 会找到每个构建了该控件的样例,而不仅是归档在该控件名下的样例。screenshot_view 和 run_app 回答的是同一个问题,但耗时相差三个数量级:前者不需要后端,会为重建的视图拍照;后者则会在构建之后为运行中的应用拍照。大多数迭代都应止步于前者。
无浏览器运行应用
app_start、app_act 和 app_describe 让每个 abap2UI5 应用都能由 Agent 操作:它们针对本地后端使用 UI5 前端所用的 JSON 协议——应用启动、附带参数的事件、所输入内容的模型增量——并根据响应中的视图 XML 和模型,返回一个Agent 快照:Agent 可以填写的字段(模型路径、标签、类型、当前值、可选值、是否可编辑)、可以触发的操作(事件名称、静态参数和依赖行的参数)、表格(列、首批行、选择项——SelectDialog/TableSelectDialog 也是表格,且 app_act 可通过 row 从中选择)、消息(toast、消息框、MessageStrip、字段值状态、MessagePopover 和 MessageView 项目)以及一些静态文本。执行任何操作前,都会依据快照进行验证:对于未知事件、不在屏幕上的字段或不可编辑的字段,以及超出可选值范围的选项,系统都会拒绝,并列出允许的内容。以下是针对 abap2UI5/samples 中 z2ui5_cl_smp_app_009 的一个简短会话:
app_start { app: "z2ui5_cl_smp_app_009" }
-> fields f1..f5 (f3 "Input with value", /S_SCREEN/COLOR_02, text, ""),
actions a1 POPUP_TABLE_VALUE (valueHelpRequest of f3), ..., a5 BUTTON_SEND
app_act { session, values: { f4: "Smith" }, event: "POPUP_TABLE_VALUE" }
-> layer "popup", table t1 /T_SUGGESTION_SEL (6 rows, Single, editableCells [SELKZ]),
action a1 POPUP_TABLE_VALUE_CONTINUE
app_act { session, values: { "/T_SUGGESTION_SEL/2/SELKZ": true }, event: "POPUP_TABLE_VALUE_CONTINUE" }
-> layer "main", f3 = "BLACK", f4 = "Smith", message { toast, "value selected" }
VS Code 扩展和 ABAP Agent 插件使用相同的快照结构;docs/agent-snapshot.md 是参考文档,其中说明了推导规则、操作、与原始契约的差异,以及快照目前尚不可见的内容。对于只有浏览器才能显示的内容(渲染后的页面、客户端行为),仍使用 interact_app 工具。
聊天中的屏幕:MCP Apps 和 Adaptive Cards
快照是供 Agent 使用的文本。两个可选界面会在聊天中向用户显示同一屏幕,并通过 app_act 将用户的操作发送回来——使用与 Agent 自身操作相同的验证,因此无法触发快照不允许的操作,且 Agent 能看到该操作:
- MCP Apps(SEP-1865,2026-01-26 起稳定,扩展
io.modelcontextprotocol/ui)。如果客户端在initialize中声明了该扩展,app_start、app_describe和app_act会将 UI 资源命名为ui://abap2ui5/app-screen(_meta.ui.resourceUri,MIME 类型text/html;profile=mcp-app)。支持渲染 MCP Apps 的宿主(该扩展自己的 README 列出了 Claude、ChatGPT、VS Code 和 Goose)会在结果旁以沙盒 iframe 的形式显示它:可填写的字段、按钮、行操作、表格单元格和消息。点击会通过宿主发起app_act的tools/call,其内容根据屏幕上的快照构建;之后,页面会告知模型发生了什么(ui/update-model-context),并渲染新的快照。页面是一个独立的 HTML 文档——没有外部 URL、没有网络请求、没有 eval——因此能在规范严格的默认 CSP 下运行;无需其他内容。对于未声明扩展但支持渲染 MCP Apps 的宿主,A2UI5_MCP_UI=on会声明该屏幕;off则始终不声明;无论哪种情况,工具的文本响应都不会改变。 - 面向 Copilot/Teams 风格宿主的 Adaptive Cards:在
app_start、app_describe和app_act上设置format: "adaptive-card"(或设置A2UI5_MCP_APP_FORMAT=adaptive-card,使其应用于每次调用),会将屏幕作为 Adaptive Card 1.5 添加——它是一个类型为application/vnd.microsoft.card.adaptive的嵌入式资源,位于保持不变的快照之后——并由 abap2UI5/protocol 的渲染器渲染(随项目提供,位于lib/vendor/adaptive-cards)。默认关闭。每个Action.Submit都会携带session(以及行操作对应的row);提交的负载会映射为一次app_act调用:event和row保持原样,每个值发生变化的输入都映射为values["<binding path>"],消息框按钮映射为该消息框的关闭操作,并将按钮作为其$action参数,弹窗/弹出窗的关闭信号分别映射为@CLOSE_POPUP/@CLOSE_POPOVER(cardSubmitToAct位于lib/adaptive-card.mjs;完整映射表见 docs/agent-snapshot.md)。
迁移经典报表
migrate_report 接收经典报表的源代码(REPORT、
PARAMETERS、SELECT-OPTIONS、事件块、WRITE 列表、ALV)以及其
.prog.xml 文本池,并返回
abap-cloud-gui 插件中的类。该插件保留了原有编程模型——selection_screen( )、
start_of_selection( )、write( )、alv( )、message( )——并附带迁移报告(TODO、未在 ABAP
Cloud 上发布的表和 API 及其替代项,以及列表中不会保留的内容),以及它拒绝转换的语句,位置格式为 file:row:col(dynpros、批量输入、SUBMIT、
原生 SQL)。如果报表包含 open-abap 的 @KERNEL 转义(WRITE '@KERNEL ...'.,转译后为 JavaScript),则在转换任何内容之前就会被拒绝;动态
WHERE (cond) 会被转换,但会在 warnings 下标记——运行时会用 eval() 求值(SECURITY.md)。转换器是插件自带的 report2cloud,需从插件的代码仓库检出后运行——它不在 npm 上:
git clone https://github.com/abap2UI5-addons/abap-cloud-gui # ABAP_CLOUD_GUI_HOME
cd abap-cloud-gui && npm ci
设置 deploy: true 后,除了将类写入开发沙箱,还会一并写入插件的运行时(src/01,包括其数据库表——后端会在启动时创建已部署的表)以及它调用的弹出窗口(若 POPUPS_HOME 中有 popups 的代码仓库,则使用该仓库;否则依次尝试插件的 .deps/popups、同级目录下的 ../popups 或插件的 build/popups);随后构建后端,返回结果中包含 app_start 对选择屏幕的快照——通过 app_act 和 CGUI_EXECUTE 运行报表。报表读取的数据库表不在本地后端中:屏幕可以运行,但读取这些表的报表无法运行。
系统模式:在真实 SAP 系统上操作应用
以上所有内容都可在没有系统的情况下运行。设置 A2UI5_MCP_SYSTEM_URL 后,同一个服务就会变成另一种用途:让工具在真实 SAP 系统上操作应用,并以配置的用户身份登录——供非 VS Code 扩展的 MCP 客户端使用(VS Code 扩展自己的系统服务会为其窗口中的客户端完成此操作):Claude Desktop、Claude Code、Cursor 以及任何 stdio 客户端。此模式下不提供沙盒工具;如需同时使用两者,请注册两次服务,一次设置该变量,一次不设置。
| 工具 | 功能 |
|---|---|
system_status | 显示端点和用户(绝不显示密码),并发送一个请求,以检查主机是否响应、证书是否被接受以及登录是否成功——只有 abap2UI5 启动页有响应时才返回 ok,仅返回 200 的登录表单页不算——请先调用此工具 |
app_list | 系统中的类名,来自 ADT 快速搜索(filter:名称开头部分,* 为通配符;最多 50 个) |
app_start | 在系统上启动应用并获取其 Agent 快照——与沙盒的 app_start 使用相同的快照、参数和拒绝规则 |
app_describe | 会话的当前快照,来自内存——不会发送任何内容 |
app_act | 填写字段并触发事件;根据快照进行验证,并作为真实模型增量发送——会实际运行 |
Claude Desktop(claude_desktop_config.json:Settings → Developer → Edit Config),与系统服务并列的沙盒服务:
{
"mcpServers": {
"abap2ui5": {
"command": "npx",
"args": ["--yes", "-p", "@abap2ui5/mcp-server", "abap2ui5-mcp"]
},
"abap2ui5-dev-system": {
"command": "npx",
"args": ["--yes", "-p", "@abap2ui5/mcp-server", "abap2ui5-mcp"],
"env": {
"A2UI5_MCP_SYSTEM_URL": "https://host:44300/sap/bc/z2ui5?app_start={class}&sap-client=100",
"A2UI5_MCP_SYSTEM_USER": "DEVELOPER",
"A2UI5_MCP_SYSTEM_PASSWORD_CMD": "security find-generic-password -s abap2ui5-dev -w"
}
}
}
}
Claude Code,与上述相同,只需一条命令:
claude mcp add abap2ui5-dev-system \
-e A2UI5_MCP_SYSTEM_URL='https://host:44300/sap/bc/z2ui5?app_start={class}&sap-client=100' \
-e A2UI5_MCP_SYSTEM_USER=DEVELOPER \
-e A2UI5_MCP_SYSTEM_PASSWORD_CMD='security find-generic-password -s abap2ui5-dev -w' \
-- npx --yes -p @abap2ui5/mcp-server abap2ui5-mcp
| 变量 | |
|---|---|
A2UI5_MCP_SYSTEM_URL | VS Code 扩展按 F9 时使用的启动 URL,{class} 作为查询参数——也可以使用不带类名的端点。启用系统模式 |
A2UI5_MCP_SYSTEM_USER | SAP 用户(Basic 身份验证) |
A2UI5_MCP_SYSTEM_PASSWORD | 该用户的密码——以纯文本形式保存在客户端的配置文件中 |
A2UI5_MCP_SYSTEM_PASSWORD_CMD | 也可改用会输出密码的 shell 命令,该命令运行一次,密码保存在内存中。macOS 钥匙串:使用 security add-generic-password -s abap2ui5-dev -a DEVELOPER -w 保存密码,并按上述方式读取;Linux:secret-tool lookup service abap2ui5-dev |
A2UI5_MCP_SYSTEM_INSECURE_TLS | 1 表示接受无法验证的证书(例如开发系统的自签名证书)。更好的做法是将 NODE_EXTRA_CA_CERTS 指向系统的 CA 证书(PEM) |
启用前请了解以下事项:
- 操作会实际生效。
app_act事件会以配置的用户身份在系统上运行,并可能保存、过账或删除数据。请使用开发系统,并使用权限范围符合 Agent 可能执行操作的用户;Agent 只能看到该用户有权查看的内容。 - 被拒绝的登录只会发送一次。 SAP 在多次登录失败后会锁定用户,而 Agent 会重试。收到
401后,不会再使用该密码发送任何内容——所有工具都会说明这一点——直到使用更正后的密码重启服务(Claude Desktop:退出后重新打开),或密码命令返回不同的密码。 - 仅支持 Basic 身份验证。 此模式不支持 SAML、X.509 或 SSO 登录;应使用 VS Code 扩展的系统服务(其身份验证代理)。
- 每个注册项对应一个系统。 两个系统需要使用两个名称分别注册。
- 不支持代理。 请求会直接发送到主机;不会读取
HTTPS_PROXY。 - 协议客户端使用沙盒的
lib/appclient.mjs:它会完成 CSRF 令牌握手,并自行维护有状态会话的sap-contextid;此模式会添加登录信息、系统 Cookie 和启动位置(lib/system.mjs)。app_list需要 ADT 服务及用户对这些服务的授权——如果已知类名,即使缺少这些条件,app_start仍可运行。
在 CI 中运行单元测试,无需系统
同一运行时可在 GitHub Actions 中(或终端里)运行应用仓库的 ABAP Unit 测试:使用项目的 abaplint.jsonc 指定的发布版本的 @abap2ui5/node-runtime,只安装一次并缓存;类针对该运行时进行转译,测试通过生成的运行器运行——无需克隆框架,无需框架的 devDependencies,也无需对本包运行 npm ci(运行器不会导入本包的任何依赖)。在一台机器上对 app-template 的入门应用进行测量:冷启动耗时 16 s,使用缓存时耗时 8 s;而克隆 0.2.0 分别耗时 30 s 和 23 s,且工作区大小为 231 MB,而非 67 MB。
- uses: abap2UI5/mcp-server@v1
with:
paths: src
framework: X.Y.Z 指定的版本与项目指定的版本不同时,backend: clone 会采用旧路径(克隆该版本、下载或构建其后端)——单凭一个早于本包版本(1.145.0)的版本指定值,也会触发此路径。
@v1 是浮动的主版本标签:发布工作流会在发布每个 1.x 版本时更新它,因此工作流使用该标签时会获取修复,而不会引入破坏性变更。该标签会随 1.0.0 版本发布而创建;在该版本发布前,请固定到 @v0(0.3.0,标签不会移动)或某个发布标签,例如 @v0.3.0。
npx -p @abap2ui5/mcp-server abap2ui5-unit src # the same, locally
paths 下的每个类和接口都会连同其所有文件一起部署(无论是否属于应用;测试 include 和本地类 include 也包括在内),并运行每个测试 include。在本包中运行时会使用独立的沙箱和独立构建,因此,同一台机器上的 MCP 会话所运行的应用既不会参与其中,也不会受到影响。运行结果包括作业的判定,以及一份步骤摘要,其中列出每个测试方法和首个失败项;无法部署的对象(名称带命名空间)会导致运行失败,而不是将其测试排除在外。app-template 在其 check.yml 中提供了此作业,命令为 npm run test:unit。运行器无法识别的是 open-abap 运行时无法建模的内容(见 pitfalls 的 abap 部分);除这些内容之外,在此处通过的测试在系统上也会通过;而 PARTIALLY IMPLEMENTED 测试替身必须实现被测代码调用的每个方法,因为运行时不会生成空桩。
资源
这些工具背后的知识文档也是 MCP 资源,供展示这些资源的客户端(上下文选择器、附加文档的界面)以及需要获取完整文档而非切片的 Agent 使用。它们从同一组并列检出目录中实时读取:列出资源无需检出;如果缺少检出目录,读取资源时会返回与工具相同的、可采取行动的错误。若文档长度超过客户端一次读取所能展示的范围(约 60,000 个字符——目前包括 abap-check 目录和功能映射),内容会在章节标题处截断,最后一行会给出读取剩余内容的工具调用,从第一个未显示的章节开始(pitfalls { area, offset }、app_guide { offset }、capabilities { status })。
唯一一个非文档资源是 ui://abap2ui5/app-screen,即应用工具的 MCP Apps 屏幕(见上文“聊天中的屏幕”);它属于此服务,无需检出。
| 资源 | 内容 | 需要 |
|---|---|---|
abap2ui5://guide | 应用构建指南,全文(app_guide 会将其切片) | abap2UI5 |
abap2ui5://guide/{chapter} | 指南中的一个章节,按编号或标题关键词指定(资源模板) | abap2UI5 |
abap2ui5://api | 客户端 API 摘要——列出每个 z2ui5_if_client 方法、常量组和类型,每项一行 | abap2UI5 |
abap2ui5://pitfalls/abap | abap-check——绿色 CI 无法发现的 ABAP 缺陷 | abap2UI5 |
abap2ui5://pitfalls/view | ui5-check——绿色 CI 无法发现的视图缺陷 | abap2UI5 |
abap2ui5://capabilities | CAPABILITIES.md——经过验证的功能映射 | samples-controls |
abap2ui5://generation-rules | 移植 UI5 demo-kit 示例的规则手册 | samples-controls |
ui://abap2ui5/app-screen | 应用工具的 MCP Apps 屏幕(text/html;profile=mcp-app)——作为页面快照,供用户在聊天中操作 | - |
提示词
两个提示词——分别对应此服务支持的两项任务——可让 Agent 直接进入工作流程,而不必仅凭工具描述自行推断顺序。每个提示词都会针对上述工具生成编排脚本,不重复其中的任何内容:
build-an-abap2ui5-app(参数:task,描述应用应实现的功能)——先通过examples/capabilities熟悉情况,再通过app_guide了解应用结构,编写类,数秒内通过validate_view/screenshot_view反复迭代,再用deploy_app→build_backend→run_app验证,最后通过pitfalls收尾。port-a-ui5-sample(参数:sample,demo-kit 示例)——语料库任务:将generation_rules作为任务说明,编写前先查看scope_of和capabilities,再从examples中参考相邻的移植示例,最后执行相同的 validate/screenshot/deploy/run 流程。
备注
- **开发沙箱:**部署的应用会放入 samples-controls 检出目录中被 gitignore 忽略的
src/zz_dev/;如果该目录不存在,则放入 abap2UI5 检出目录中被 gitignore 忽略的node/zz_dev/;否则放入~/.abap2ui5-mcp/sandbox(通过A2UI5_MCP_WORKSPACE可更改位置)——Agent 部署的内容不会泄漏到提交中。 - **后端:**没有框架检出目录时,会使用 npm 包
@abap2ui5/node-runtime——A2UI5_MCP_RUNTIME_VERSION用于固定其版本 (默认使用注册表中的最新版本,每天查询一次);即使存在检出目录,A2UI5_MCP_BACKEND=npm也会使用该包;A2UI5_MCP_BACKEND=clone则恢复以框架克隆为默认设置。所有安装内容都位于~/.abap2ui5-mcp,可以安全删除。 - **端口:**后端监听 3000 端口(可通过
A2UI5_MCP_PORT覆盖)。 - Lint:
deploy_app使用 app-template 的 abaplint 配置运行 lint。 在 npm 后端上,长驻 Worker 会保留已安装在@abaplint/cli旁边、版本相同的@abaplint/core,以及已解析的框架,因此部署时的 lint 只需几毫秒,而不是启动全新的 abaplint 进程(需 2–3 秒,耗时主要在解析框架);当 Worker 无法替代 CLI 时——例如检出目录中没有该 core,或配置无法由 Worker 镜像——则仍会像以前一样运行 CLI。A2UI5_MCP_LINT_WORKER=0可关闭 Worker;A2UI5_MCP_LINT_IDLE_MS(默认 10 分钟,0 = 永不退出)用于设置无请求时保留 Worker 的时长——解析框架后它会占用约 300 MB——之后 Worker 退出,下次 lint 时会启动新的 Worker。 - **超时:**超过时限后,所有生成的子进程都会被终止(包括整个进程树)——lint/scope 为 5 分钟,单元测试为 10 分钟,构建(包括预构建下载和 npm 安装)默认 30 分钟;
可通过
A2UI5_MCP_LINT_TIMEOUT_MS、A2UI5_MCP_SCOPE_TIMEOUT_MS、A2UI5_MCP_UNIT_TIMEOUT_MS和A2UI5_MCP_BUILD_TIMEOUT_MS覆盖 (值以毫秒为单位)。 - **下载限制:**从 GitHub 读取的内容既有大小限制,也有时间限制——只读镜像文件、文档树列表和发布列表的上限为 8 MB(目前最大的是 0.34 MB),预构建后端归档的上限为 200 MB(1.146.0 版本为 2.7 MB)。超出上限的响应会被拒绝(如果响应声明了大小)或截断至上限,工具会按 URL 说明原因;缓存的镜像或上一次构建会保留。
- **解包前会验证预构建后端:**框架会在归档旁附带
backend-<version>.tar.gz.sha256校验文件(适用于 1.148.0 之后的版本),build_backend会将下载内容的 sha256 与之比对——不匹配时会丢弃下载内容并保留上一次构建;没有校验文件的发布版本仍会像以前一样解包,构建日志会说明该版本未经验证。归档中的代码会由run_app启动,因此A2UI5_MCP_PREBUILT_URL必须使用https:——除非通过A2UI5_MCP_PREBUILT_INSECURE=1声明网络可信,否则会拒绝来自回环地址之外的普通http:镜像(此时也会查找<url>.sha256校验文件)。 - UI5 源文件会从 samples-controls 检出目录中的
@openui5包提供;如果该检出目录存在,启动时无需联网;否则,run_app和interact_app会从 CDN 加载 UI5(如果无法连接,会立即说明,而不是一直等待启动超时)。这些包中不包含构建好的主题 CSS——有网络连接时会从 CDN 加载(截图会应用样式);无网络连接时,应用会以无样式但结构完整的状态呈现。CDN 的响应会在多次调用间保存在内存中(A2UI5_MCP_UI5_CACHE_MB,默认 64;0 表示关闭),因此第二次启动时不会再次下载 UI5。A2UI5_MCP_OFFLINE=1会强制启用完全隔离的离线模式。 - Chromium:
A2UI5_MCP_CHROMIUM(或 lint 程序也会读取的CHROMIUM_BIN)用于指定可执行文件;否则使用 Playwright 管理的浏览器(npx playwright install chromium);再否则使用系统中的 chromium。setup_status会说明找到的浏览器及其来源。validate_view的预热渲染门会保留该浏览器的 2 个页面,并发调用会排队等待;可通过A2UI5_MCP_RENDER_PAGES(1 到 8)设置页面数。 - 截图:
run_app和interact_app会将 PNG 文件写入<tmp>/abap2ui5-mcp-screenshots/<class>-<stamp>.png(保留最新的 50 张,并删除更早的同类文件),并在返回结果中附上图片路径——有意不将其写入安装目录,因为通过 npm 安装时该目录位于node_modules中。上次构建的日志也会保存在此目录,重启后可由build_log读取。该目录会以 0700 权限创建,且仅在归你所有时使用(Linux 上的/tmp是共享目录);否则会返回图片但不保存,并通过screenshotNotSaved说明原因。A2UI5_MCP_SCREENSHOT_DIR可将图片保存到你指定的位置。 scope_of需要 OpenUI5 检出目录以及语料库:它会从OPENUI5_SRC读取 JSDoc;如果未设置该变量,则从 samples-controls 检出目录旁的../fork-openui5读取。- **如果你之前已完成设置:**语料库仓库曾名为
ai-demokit,之后改为abap2UI5-api,如今名为samples-controls。无需更改任何内容——系统仍会在这三个目录名中的任意一个下找到现有检出目录,也会继续读取AI_DEMOKIT_HOME和SAMPLES_CONTROLS_HOME。 - 真实系统部署仍与现在一样使用 abapGit。此服务用于内部开发循环;真实系统相关功能位于
VS Code 扩展中,其自身的 MCP 服务将其公开为
run_app_on_system。两个服务都会在同一个编辑器窗口中注册,因此该工具不叫run_app。
参与此代码库的开发
npm ci
npm test
AGENTS.md 记录了约定,CONTRIBUTING.md 和 RELEASING.md 记录了其余工作流。
bench/ 是 abap2UI5-bench:用于统计 AI Agent 开发的 abap2UI5 应用通过模板门槛的频率,并比较使用和不使用此服务的情况。它是独立的软件包,不属于已发布的服务。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。