Skip to main content

MCP Overview

@abapify/adt-mcp is a stateless Model Context Protocol server that bridges MCP-aware clients — Claude Code, Cursor, VS Code Copilot, and others — to SAP ABAP Development Tools (ADT). It uses the same typed contracts as the adt CLI, so every tool call goes through @abapify/adt-client and the XSD-driven schema pipeline. No manual XML, no ad-hoc HTTP.

The server is a thin MCP adapter. All business logic lives in @abapify/adt-client, @abapify/adt-contracts, and the domain packages.

Why an MCP server?

  • Agentic ABAP workflows. An AI assistant can search objects, read source, run syntax checks, execute ATC, create transports, and commit to gCTS — all inside the same conversation.
  • Type safety end-to-end. Every tool is backed by a typed contract; responses are parsed against the schemas in @abapify/adt-schemas.
  • Same guarantees as the CLI. CSRF sessions, lock protocol, ETag refresh, and security session semantics are handled by @abapify/adt-client — see adt-client architecture.

Installing and running

adt-mcp is published as a binary inside the monorepo. The server speaks MCP over stdio.

# From the monorepo
bunx nx build adt-mcp

# Run directly
node packages/adt-mcp/dist/bin/adt-mcp.js

Claude Code / Claude Desktop

Add the following to your ~/.config/claude/claude_desktop_config.json (or equivalent):

{
"mcpServers": {
"adt": {
"command": "node",
"args": ["/absolute/path/to/packages/adt-mcp/dist/bin/adt-mcp.js"]
}
}
}

Cursor

In Settings → MCP Servers:

{
"adt": {
"command": "node",
"args": ["/absolute/path/to/packages/adt-mcp/dist/bin/adt-mcp.js"]
}
}

VS Code (Copilot / other MCP clients)

Point the client at the same binary using its MCP server configuration UI. The transport is always stdio — no HTTP port, no daemon.

Calling a tool

Tools are invoked through the standard MCP tools/call request. Every tool accepts the connection parameters (baseUrl, username, password, client) as arguments — the server is stateless and creates a fresh AdtClient per call.

Example raw JSON-RPC request:

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_objects",
"arguments": {
"baseUrl": "https://sap.example.com:44300",
"username": "DEVELOPER",
"password": "***",
"client": "100",
"query": "ZCL_MY"
}
}
}

The response is a single text content item whose text field contains a JSON-serialised result:

{
"content": [
{ "type": "text", "text": "[ { \"name\": \"ZCL_MY_CLASS\", ... } ]" }
]
}

Errors are returned with isError: true and a human-readable message.

Tool catalog

All 96 registered tools grouped by category. Each page documents the input schema (Zod), the underlying contract, and an example invocation.

Discovery & system

Search & navigation

Source code

Objects – generic CRUD

Function groups & modules

DDIC

CDS

RAP / services

BAdI

CTS transports

ATC

  • atc_run — run ATC checks on an object / package

gCTS (git-enabled CTS)

abapGit

Import / checkin

STRUST (SSL certificates)

Fiori Launchpad

RFC

  • call_rfc — invoke a classic RFC via SOAP-over-HTTP

Architecture notes

  • Stateless. No session, no cached client, no credentials in memory between calls. Every request receives its own AdtClient.
  • Schema-driven. All request bodies and response parsing go through schemas in @abapify/adt-schemas — never a manual XML parser.
  • Contract-backed. Each tool calls exactly one typed contract from @abapify/adt-contracts. If an endpoint has no contract yet, a contract is added before the tool.
  • Mock server for testing. createMockAdtServer() starts an in-process HTTP server backed by fixtures; see packages/adt-mcp/tests/integration.test.ts for examples.

Known limitations

  • Credentials in arguments. MCP tool calls include connection parameters in every invocation. The server never persists them — but clients do need to forward them.
  • Per-call sessions. SAP allows one security session per user. Concurrent tool calls from the same user compete for the same slot.
  • No streaming. Tools return a single JSON blob; long-running operations (package import, ATC runs) do not stream progress.

See also