mcp-bw-adt-api

mcp-bw-adt-api

Exposes SAP BW/4HANA ADT operations as MCP tools for LLM clients, with a local-file buffering layer to handle large XML payloads and table data efficiently.

Category
Visit Server

README

mcp-bw-adt-api

An MCP (Model Context Protocol) server that exposes the bw-adt-api library — SAP BW/4HANA ADT (ABAP Developer Tools) operations — to LLM clients such as ZCode, Claude Desktop, or any MCP-compatible client.

It wraps the ~100 public methods of BWAdtClient (ADSO, Transformation, DTP, DataSource, Process Chain, InfoObject, DDIC tables, search, dataflow lineage, transports, …) as MCP tools, with a local-file buffering layer that keeps large XML payloads and table data out of the LLM context window.


Why a buffering layer?

bw-adt-api payloads are large — measured on real systems:

Payload Typical size
Object XML (PUT request body) 15–80 KB
DDIC table data, 100 rows × 20 cols ~68 KB
DDIC table data, 10 000 rows ~6.7 MB
Process chain logs, 200 entries ~39 KB

Pushing these through the LLM context window is wasteful or fatal. This server solves it two ways:

Mechanism A — large request bodies via local files (POST/PUT)

Every tool that takes a large string body (object XML, SQL statement, ABAP source) accepts two fields:

  • <label>Content — inline string
  • <label>Path — path to a file under the workdir (takes precedence)

So instead of the LLM having to generate or hold a 50 KB XML, it reads the current XML to a file, edits it (or uses an atomic-edit tool), then references the file by path.

Mechanism B — large responses via outputPath

Most read tools accept an optional outputPath. When set, the full result is written to that file and the tool returns only a small summary envelope:

{ "ok": true, "outputPath": "/abs/path/big.json", "bytes": 723908, "summary": "object with key(s): tableName, rows, …" }
  • Objects / arrays are written as JSON.
  • Raw XML strings (from bw_*_get_xml with outputPath) are written as plain text, so the same path can be reused as xmlPath in a later save call.

Without outputPath, the result is returned inline (with table data paginated to a soft cap and truncated/hint flags set when needed).

Workdir sandbox

All file paths resolve under the workdir and are confined to its subtree (.. escapes and out-of-tree absolute paths are rejected). By default the workdir is <cwd>/.mcp-bw-out (a scratch folder under the server process working directory) so buffered files do not land on project source. Override with BW_MCP_WORKDIR if you need a different root (e.g. the workspace root).


Quick start

# 1. Install + build
npm install
npm run build

# 2. Configure connection (copy & edit)
cp .env.example .env
#   multi-env: BW_PROFILES + BW_<NAME>_*  (or legacy BW_BASE_URL / …)

# 3. Inspect the tool catalog (no BW connection needed)
npm run list-tools

Environment variables — multi-profile (recommended)

Variable Required Description
BW_PROFILES yes* Comma-separated profile names, e.g. test,prod
BW_DEFAULT no Startup profile (default = first in BW_PROFILES)
BW_<NAME>_BASE_URL yes* BW server URL for that profile
BW_<NAME>_USERNAME yes* SAP logon user
BW_<NAME>_PASSWORD yes* Password (never exposed to the LLM)
BW_<NAME>_CLIENT no SAP logon client, e.g. 100
BW_<NAME>_LANGUAGE no Language key, e.g. ZH
BW_<NAME>_READONLY no true → reject mutating tools on this profile
BW_<NAME>_ALLOW_UNAUTHORIZED no true to accept self-signed certs
BW_MCP_WORKDIR no Root for file buffering (default = <cwd>/.mcp-bw-out)

* Or use the legacy single-env vars (BW_BASE_URL, BW_USERNAME, BW_PASSWORD, optional BW_CLIENT / BW_LANGUAGE / BW_READONLY / BW_ALLOW_UNAUTHORIZED) when BW_PROFILES is unset — they become a profile named default.

Switch at runtime with bw_env_list / bw_env_switch. The active profile’s client auto-logs-in on its first request; bw_disconnect drops only the current profile’s session.

Read-only profiles: mutating tools are omitted from tools/list, and the server emits notifications/tools/list_changed when readOnly visibility changes. Host support for mid-session refresh is incomplete (Cursor / Claude Code may keep a stale list until MCP reconnect or a new chat) — the server still rejects mutating tools/call as a hard guard.


Registering in an MCP client

Add the server to your client's MCP config. Examples:

ZCode (.zcode/mcp.json in the workspace, or user-level)

{
  "mcpServers": {
    "bw-adt": {
      "command": "node",
      "args": ["E:/04-code/02-personnal/mcp-bw-adt-api/build/index.js"],
      "env": {
        "BW_PROFILES": "test,prod",
        "BW_DEFAULT": "test",
        "BW_TEST_BASE_URL": "http://your-bw-test:8000",
        "BW_TEST_USERNAME": "developer",
        "BW_TEST_PASSWORD": "secret",
        "BW_TEST_CLIENT": "100",
        "BW_TEST_LANGUAGE": "ZH",
        "BW_TEST_READONLY": "false",
        "BW_PROD_BASE_URL": "http://your-bw-prod:8000",
        "BW_PROD_USERNAME": "developer",
        "BW_PROD_PASSWORD": "secret",
        "BW_PROD_CLIENT": "100",
        "BW_PROD_LANGUAGE": "ZH",
        "BW_PROD_READONLY": "true"
        // "BW_MCP_WORKDIR": "C:/path/to/workspace"
      }
    }
  }
}

The server inherits the client process's cwd, so BW_MCP_WORKDIR usually does not need to be set — files are buffered into the workspace that owns the MCP server.

Claude Desktop (claude_desktop_config.json)

Same shape under "mcpServers".


Tool catalog

Tools are named bw_<domain>_<action>. Run npm run list-tools for the full list with input schemas. Domains:

Domain Prefix Example tools
System / env bw_system_*, bw_env_*, bw_disconnect bw_env_list, bw_env_switch, bw_system_status
Search bw_search_*, bw_quick_search bw_search_objects, bw_quick_search
Dataflow / lineage bw_dataflow_* bw_dataflow_get, bw_dataflow_lineage
Generic CRUD bw_object_* bw_object_create/update/delete/activate
ADSO bw_adso_* bw_adso_get_xml, bw_adso_save_and_activate, bw_adso_add_field
Transformation bw_trfn_* bw_trfn_save_and_activate, bw_trfn_add_rules_and_save, bw_trfn_auto_map_and_save
DTP bw_dtp_* bw_dtp_execute, bw_dtp_save_and_activate
DataSource bw_datasource_* bw_datasource_save_and_activate, bw_datasource_merge_proposal
Replication bw_replication_* bw_replication_replicate_full
Process Chain bw_processchain_* bw_processchain_execute, bw_processchain_logs
InfoObject bw_infoobject_* bw_infoobject_get
DDIC tables / data bw_table_* bw_table_get_data, bw_table_query_sql
BICS reporting / preview bw_reporting_* bw_reporting_preview, bw_reporting_initial_view
Transport / CTS bw_transport_* bw_transport_check, bw_transport_create

Note: Transformation creation is unsupported server-side (SAP JCo limitation) and bw_object_create with objectType: "trfn" returns an error. All other TRFN operations work.


Typical workflows

Read-modify-write an ADSO (no large XML held by the LLM)

1. bw_adso_get_xml   { id: "ZL_FID40", format: "summary", outputPath: "adso.xml" }
   → LLM sees a small envelope; the full XML is on disk under the workdir.

2. bw_adso_add_field { id: "ZL_FID40", name: "ZZFLAG", dataType: "CHAR", length: 1 }
   → atomic edit: reads current XML, adds the field, saves+activates.
   (Or the LLM edits adso.xml directly, then:)

3. bw_adso_save_and_activate { id: "ZL_FID40", xmlPath: "adso.xml" }
   → writes the file's XML back, one-stop lock→PUT→activate→unlock.

Query a large table without flooding context

bw_table_get_data { table: "/BIC/AZL_FID402", maxRows: 1000, outputPath: "data.json" }
→ { ok: true, outputPath: "…/data.json", bytes: 680000, summary: "…: 1000 row(s)…" }

The LLM can then run a follow-up script/tool to inspect data.json instead of ingesting it.

Inspect process chain logs safely

bw_processchain_logs { id: "ZPC_FID", limit: 50, offset: 0 }
→ inline, capped. Use outputPath for the full log set.

Architecture

src/
├── index.ts        stdio entry; --list-tools catalog dump
├── server.ts       MCP Server + tools/list + tools/call (outputPath interception)
├── session.ts      singleton BWAdtClient from env (auto-login)
├── errors.ts       AdtException → MCP error result mapping
├── fileio.ts       workdir sandbox, readInput (mechanism A), writeOutput (mechanism B)
├── response.ts     pagination, projection, summaries
├── tool.ts         ToolDef + zod→JSON Schema + largeInput/outputPathField helpers
└── tools/          one file per domain, each exporting ToolDef[]
  • Credentials are read once from env at startup and never surfaced to the LLM.
  • Write operations (delete, activate, execute) are exposed directly, no extra confirmation layer — rely on your MCP client's tool-approval prompt.
  • Pagination: table tools default maxRows to 50 and cap inline returns; logs default to 100 with limit/offset.

Development

npm run build      # tsc → build/
npm run watch      # tsc -w
npm start          # run the server (stdio)
npm run list-tools # dump the tool catalog as JSON

The server depends on bw-adt-api via a local file: link during development. Once published, switch the dependency to "bw-adt-api": "^0.1.0".

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured