Skip to main content
Glama

main License sap-abap-mcp MCP server M8ven Score Listed on mcpservers.org

SAP ABAP MCP Server (ADT and JSON RPC)

Сервер MCP, который даёт ИИ-агенту полный доступ на чтение и запись к системе SAP ABAP через ADT (ABAP Development Tools). Аутентификация выполняется через SPNEGO/Kerberos single sign-on, X.509 client certificate или OAuth 2.0 bearer token — нигде в конфигурации нет пароля. Пользователь и пароль всё ещё доступны как запасной вариант, но не рекомендуются.

Он является обёрткой над abap-adt-api и добавляет то, чего сам ADT не умеет: вызов RFC-совместимых функциональных модулей через сервис SAP Gateway JSON-RPC 2.0.

128 инструментов — CRUD объектов, редактирование исходного кода, блокировки, транспорты, активация, проверка синтаксиса, автодополнение кода, ABAP Unit, ATC, DDIC, abapGit, рефакторинг, трассировки, отладчик и вызовы RFC.

Сколько из них на самом деле видит клиент, меньше — по двум причинам. Профили (ABAP_MCP_PROFILE) меняют ширину охвата на контекст: core содержит 9 инструментов, тогда как all — 129, то есть ~2,700 токенов против ~17,800 в каждом ходе для клиента, который не умеет загружать схемы инструментов по требованию. Кроме того, сервер спрашивает систему, что она поддерживает, прежде чем вывести какой-либо список, поэтому версии без abapGit-плагина никогда не предлагаются те 10 инструментов, которые отвечали бы ошибкой 400. На DEV остаётся 116.

Это SSO-форк mcp-abap-abab-adt-api от mario-andreschak. Основные отличия: Kerberos SSO вместо Basic Auth, инструменты JSON-RPC/RFC, маршрутизатор, построенный из определений инструментов, и документированный справочник инструментов.


Документация

Документ

Что покрывается

AGENTS.md

Работа над этим репозиторием: структура, соглашения, способ тестирования. Прочтите это перед изменением кода.

docs/Tool-Router.md

Что вы хотите сделать → инструмент, который это делает. Написано вручную, теми словами, которыми говорит люди. Начните здесь, если знаете задачу, но не знаете инструмент.

docs/Tool-Reference.md

Все 128 инструментов с их аргументами, сгруппированные по семействам. Генерируется из определений инструментов, поэтому не может разойтись с кодом.

docs/MCP-Tools.md

Как ведёт себя сервер. Профили, циклы стандартных workflow, семантика ADT URI и блокировок, модель ответов и ошибок, а также матрица поиска неполадок. Написано для людей и для агентов, работающих с сервером.

docs/ABAP-Skills.md

20 SAP/ABAP-навыков и их соответствие этим инструментам.

docs/Development-Skills.md

35 встроенных общих инженерных навыков.

docs/JSON-RPC.md

Дизайн и заметки о протоколе для инструментов JSON-RPC / RFC, прочитанные из ABAP-исходников /IWBEP/CL_JSRPC_*: сетевой протокол, гарантия LUW за пакетными вызовами и тезаками.

docs/Authentication.md

Два беспарольных режима входа: Kerberos SSO и сертификаты X.509 для сервисных и технических пользователей. Что нужно настроить в SAP и почему это взаимный TLS, а не SNC.


Related MCP server: ABAP-ADT-API MCP-Server

Возможности

  • Два беспарольных режима входа — SPHTTP/ Kerberos с тикетом вошедшего пользователя Windows или сертификат клиента X.509 для сервисного или технического пользователя без Kerberos-идентичности. Ни пароль SAP не хранится, ни по какому-либо из каналов не передаётся, и оба режима самовосстанавливаются при истечении сессии.

  • Потоковый HTTP-транспорт для команды, обслуживающей один контейнер — установите ABAP_MCP_TRANSPORT=http, и каждый подключающийся MCP-клиент аутентифицируется своим собственным SAP OAuth 2.0 bearer-токеном: каждая сессия получает свой SAP-вход, а не все делят одного технического пользователя. stdio по-прежнему остаётся значением по умолчанию для одиночного, локально запускаемого клиента. См. §12 и раздел Работа по HTTP ниже.

  • Чтение любого объекта по имени — readAbapObject за один вызов находит исходный код объекта по его имени; никакого ADT URL не нужно обнаруживать или писать вручную.

  • Описание таблицы — describeAbapTable возвращает поля, типы DDIC, признаки ключевых полей и таблицы проверки.

  • Управление объектами — поиск, чтение, создание, изменение, удаление и активация ABAP-объектов.

  • Обзор соглашения о наименовании — searchPackages находит пакеты по шаблону (["ZPP_*","Z_PP*"]) и разворачивает каждый из них в его объекты, сгруппированные по типам, одним вызовом.

  • Работа с исходным кодом — блокировка → изменение → проверка синтаксиса → активация → снятие блокировки, с обработкой транспортов.

  • Интеллектуальная работа с кодом — автодополнение, определения, ссылки на использование, ABAP Doc, pretty printer, ATC, ABAPP Unit, рефакторинг (переименование, извлечение метода).

  • Вызов RFC-модулей — callFunctionViaJsonRpc выполняет RFC-функциональный модуль и проверяет запрос на соответствие его реальной сигнатуре, полученной из системы.

  • Пакетные вызовы RFC в одной LUW — callFunctionsViaJsonRpc отправляет несколько функциональных модулей в одном запросе — именно это позволяет обновляющему BAPI и его BAPI_TRANSACTION_COMMIT работать в одной LUW.

  • Доступ к данным — tableContents и ad-hoc SELECT-запросы через runQuery.

  • Видимость работающей системы — listLoggedOnUsers отвечает на вопрос «кто выполнил вход» по данным из TH_USER_LIST, той же таблицы, что за SM04; readProfileParameters читает параметры RZ11 за один обмен; а checkLogonConfiguration показывает, какую аутентификацию система фактически принимает.

  • Встроенные навыки агента — 55 навыков в каталоге skills/ для ABAP (Clean ABAP, RAP, CDS, ATB, ABAP Unit…) и общего инженерного дела (TDD, ревью кода, диагностика ошибок), которые предоставляются как ресурсы и через readSkill.

  • Самодокументирование — приведённые ниже руководства предоставляются самим сервером как ресурсы MCP (abap-adt://guides/…) и через инструмент readServerGuide, так что агент может уточнить workflow или аргумент в середине задачи, не выходя из сессии.

Предварительные требования

  • SAP ABAP-система, доступная по ADT. В SICF должен быть активен /sap/bc/adt. Для инструментов RFC дополнительно должен быть активен /sap/gw/jsonrpc (SAP_GWFND), а вашему пользователю нужна полномочия S_RFC на вызываемые функциональные группы.

  • Беспарольный вход — один из вариантов:

    • Рабочий Kerberos-вход — SAP-система должна принимать SPNEGO, и у вас должен быть действующий билет (klist). Это вариант по умолчанию, и в поставленном виде он требует Windows: скрипты запуска вызывают C:\Windows\System32\curl.exe --negotiate, которому нужен Schannel/SSPI-бэкенд curl. На других платформах укажите SSO_CURL_PATH на сборку curl с поддержкой GSS-API.

    • Сертификат клиента X.509 — для сервисного или технического пользователя без Kerberos-идентичности. Ему не нужны ни curl, ни Windows. SAP должен быть настроен соответствующим образом: порт ICM должен запрашивать сертификат (VCLIENT в icm/server_port_<n>, что перекручивает icm/HTTPS/verify_client), выпустивший CA — доверенным в STRUST, и для пользователя должно быть правило CERTRULE. Полная настройка — включая проверку этих параметров с самого этого сервера — в docli/Authentication.md.

    • OAuth 2.0-клиент — для SAP BTP под ABAP, где нет ни Kerberos-области, ни какого настраиваемого ICM, либо для on-premise-системы, которая публикует ADT через SOAUTH2. Сервисный ключ BTP уже является таким клиентом. См. §11.

  • Node.js (LTS) и npm — проверьте командами node -v и npm -v.

Установка

git clone --recurse-submodules https://github.com/Ciltress/sap-abap-mcp.git
cd sap-abap-mcp
npm install
npm run build

Значение параметра --recurse-submodules важно: общие инженерные навыки находятся в подмодуле, и без него этот каталог будет пуст, и сервер предложит на 35 навыков меньше. Уже клонировано? Выполните git submodule update --init --recursive.

Пакет npx mcp-abap-abab-adt-api в npm — это upstream-сервер и не включает SSO-загрузку и инструменты RFC. Вместо этого собирайте этот репозиторий из исходного кода.

Конфигурация

Скопируйте .env.example в .env и заполните вашу систему:

SAP_URL=https://your-sap-server.example.com:44301
SAP_USER=YOUR_SAP_USER
SAP_CLIENT=100
SAP_LANGUAGE=EN

SAP_URL и SAP_USER обязательны; SAP_CLIENT и SAP_LANGUAGE необязательны, но рекомендуются. Три из четырёх режимов входа вообще не требуют SAP_PASSWORD.

Никогда не коммитьте .env; он уже находится в .gitignore.

Необязательная переменная

Эффект

SAP_SYSTEM_ID

Идентификатор системы, как sy-sysid (например, DEV). Объявляется при подключении, чтобы клиент мог выбрать между несколькими серверами по имени. См. Более одной системы.

NODE_TLS_REJECT_UNAUTHORIZED=0

Принимать сертификат от внутреннего/неизвестного центра сертификации. Только для разработки.

SSO_CURL_PATH

Путь к исполняемому файлу curl с поддержкой SPNEGO, если это не системный Windows.

SAP_JSONRPC_PATH

Переопределяет путь ICF JSON-RPC, когда узел опубликован под псевдонимом.

ABAP_MCP_PROFILE

Какие инструменты перечисляет этот сервер — и какие, соответственно, обслуживает. См. ниже.

ABAP_MCP_MAX_RESPONSE_BYTES

Потолок одного ответа в байтах. 0 отключает его.

ABAP_MCP_GATE

off пропускает проверку возможностей при сзапу, которая скрывает инструменты, недоступные этому репиз.

ABAP_MCP_RFC_FALLBACK

Запускайтесь даже когда SAP отказывает этому пользователю в узле ADT, сохраняя инструменты RFC. См. docs/Authentication.md.

SAP_FALLBACK_BOOTSTRAP_PATH

Какой узел ICF этой fallback-лог используется. Ему нужно лишь выдать сеансовом cookie и CSRF-токен.

ABAP_MCP_TRANSPORT

stdio (по умолчанию) или http. См. Работа по HTTP.

ABAP_MCP_HTTP_PORT

Порт для конечной точки Streamable HTTP. По умолчанию 3000. Читается только в режиме http.

ABAP_MCP_HTTP_HOST

Адрес связывания в режиме http. По умолчанию 0.0.0.0.

ABAP_MCP_HTTP_ALLOWED_ORIGINS

Истории (origin) браузера, которым разрешено вызывать /mcp, через запятую; * разрешает любые. Пусто (по умолчанию) не обслуживается ни один. Клиенты с не отправленным Origin не затрагиваются.

ABAP_MCP_HTTP_ALLOWED_HOSTS

Значения Host, на которые этот сервер отвечает в режиме http, через запятую. Пустое принимает любые.

ABAP_MCP_HTTP_RATE_LIMIT

Запросов в минуту сессии MCP в режиме http. 0 (по умолчанию) — отключено.

Масштабирование сервера под клиента

Три переменные ABAP_MCP_* существуют по одной причине: клиент, который не может получать схемы инструментов по запросу, платит за весь список инструментов на каждом ходу. Claude Code откладывает загрузку схем и должен оставаться без настроек по умолчанию; модель на 8B параметров с окном 128k тратит шестую часть контекста, ещё до начала диалога, а именно отсюда будет «одинаковый промпт срабатывает в половине случаев».

ABAP_MCP_PROFILE — без значения означает all, поэтому существующая конфигурация не меняется.

profile

tools/list

стоимость за ход

для

core

9

~2 737 токенов

чтение системы и выполнение одного изменения

analyst

18

~3 982 токенов

только чтение: словарь, данные таблиц, вызовы RFC

rfc

10

~2 900 токенов

пользователь с правами подпис-BufferHTTP: ADT-инструменты не могут работать

dev

49

~8 034 токенов

цикл правок плюс тесты, ATC, транспорты, рефакторинг

all

129

~17 759 токенов

умолчаний; подходит клиентам, которые загружают схемы по запросу

Количество включает healthcheck, который вне любого профиля, потому что именно этот инструмент отвечает на вопрос «какой профиль у меня запущен?».

Профиль — не просто удобный фильтр. Инструмент вне активного профиля не числится и не маршрутизируется, так что его нельзя вызвать — именно поэтому analyst гарантирует, что ничто не редактирует исходник, а не просто уменьшенное меню. Внеprofileовые вызовы получают явную ошибку — вместо „unknown tool", поэтому повторять попытки бессмысленно. Не распознанный имени профиля останавливает сервер при старте, а не погружается на all — незаметно раздавать 129 инструментов тому, кто попросил 9, это та самая ошибка, для предотвращения которой профили и существуют.

core мал потому, что один инструмент, editAbapSource, является весь цикл записи: блокировка, запись, активация, освобождение блокировки, и блокировка снимается даже при сбое любого из шагов. Отдельные четыре шага остались в dev и all.

ABAP_MCP_MAX_RESPONSE_BYTES — список инструментов — это фиксированная цена, которую профиль может сжимать; ответ безлимитный. На core весь список — ~11 КБ, тогда как один adtDiscovery — ~42 КБ. Без значений следуют профилю (core 24 000 байт, analyst 32 000, dev 48 000, all без потолка); 0 отменяет.

Ответ сверх бюджета скрывается и заменяется корректным JSON — status:"truncated", исходный bytes, budget, набор preview на 2000 байт и nextStep — но никогда не обрезанным фрагментом: он он объед не был бы распарсен и спровё бы идентичный очередной повтор.

ABAP_MCP_GATE — перед перечислением чего-либо сервер проверяет у системы, что она поддерживает, и скрывает инструменты, чьи коллекции ADT отсутствуют. На DEV это десять инструментов abapGit и три инструмента привязку к сервисам, иначе они ответили бы HTTP 400. Это стоит одного цикла option per process, и список может только сократиться; сбой при этом не приводит к удалению ни одного. ABAP_MCP_GATE=off пропускает проверку.

healthcheck сообщает все три из них: активный профиль, responseBudgetBytes и все, что скрыто.

Сертификат вместо Kerberos

Для сервисного или технического пользователя добавьте сертификат — этого одного достаточно для переключения режима:

SAP_USER=CLAUDEAGENT                                 # the user CERTRULE maps the certificate to
SAP_CERT_FILE=C:\Users\svc_agent\SNC\sec\claudeagent.p12
SAP_CERT_PASSPHRASE=<PKCS#12 password / PSE PIN>

Необязательная переменная

Эффект

SAP_AUTH_MODE

kerberos, certificate, oauth или password. Нужна только для того, чтобы принудительно выбрать один режим, пока настроен другой.

SAP_CERT_KEY_FILE

Приватний ключ, когда он не находится в SAP_CERT_FILE.

SAP_CA_FILE

Набор CA для проверки собственного сертификата SAP вместо отключения проверки TLS.

Это взаимный TLS, не SNC — ADT работает по HTTPS. Сертификат, который уже работает для RFC/SNC, можно переиспользовать, и его маппинг CERTRULE будет перенесён, но при этом нет пищи SNC0 имеет роли, и ICM требуется icm/HTTPS/verify_client. docs/Authentication.md рассказывает о различиях, ловушкой sapgenpse export_p12 / OpenSSL 3 и читать по отклонённом сертификате.

OAuth 2.0 клиент для BTP и SOAUTH2

Для ABAP BMP или локальной системы, которая публикует ADT за сервером авторизации. Установка идентификатора клиента переключает режим:

SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token
SAP_OAUTH_CLIENT_ID=sb-abap-agent!t1234              # 'clientid' in a BTP service key
SAP_OAUTH_CLIENT_SECRET=<'clientsecret'>

А в локальной система точка доступа находится на самом хосте SAP — https://<host>:<port>/sap/bc/sec/oauth2/token — а клиент тот, что зарегистрирован в SOAUTH2.

Необязательная переменная

Эффект

SAP_OAUTH_GRANT

client_credentials (по умолчанию), refresh_token, password или `static**.

SAP_OAUTH_SCOPE

Запрашиваемые области (scopes). Без значения запрашивает настройки клиента по умолчанию — обычно это правильно.

SAP_OAUTH_REFRESH_TOKEN

Для гранта refresh_token; выбирает его автоматически.

SAP_OAUTH_TOKEN

Токен, выпущенный вне здесь, используется как есть. Ничто не может его обновить.

SAP_OAUTH_CLIENT_AUTH

basic (по умолчанию) или post, когда сервер отклоняет правильный секрет.

Токен входит один раз. После этого cookie каждый запрос переносится, как и в run factorization — поэтому токен, который исходит через пять минут, не проблем. Обратите внимание: клиент OAuth 2.0 на AS ABP'? это пользователь в SU01: неверный SAP_OAUTH_CLIENT_SECRET считаается против login /wrong password как пароль, и отклонённый запрос токена никогда не повторяется. Поток authorization code не реализован — ему нужен браузер, которого у сервера, запущенного через stdio, нет способа открыть; пройдите один раз вручную и передайте refresh-token. В docs/Authentication.md §11 есть детали, включая какие сбои закрепляются и почему.

Пароль, когда больше ничего нет

Для систем, где нет ни Kerberos, ни сертификатов — песочница, тестовый стенд, всё вне домена:

SAP_USER=CLAUDEAGENT
SAP_PASSWORD=<the password>

Последнее средство, и нельзя смешивать с двумя pasteren. Неверный билет или непривязанный сертификат просто отклоняются; неверный пароль считается против login/fails_to_user_lock и блокирует этого пользователя для всех потребителей, не только для этого сервера. При реализации повторные попытки принять отказанный пароль не делается по этой причине — одна неудачная входная, фиксатор, даже для вызова множества инструментов. Для автономной работы предпочтительнее сертификат. docs/Authentication.md §10 содержит подробности.

Регистрация в MCP-клиенте

Укажите клиенту на собранную точку пуска с абсолютными путями:

{
  "mcpServers": {
    "sap-abap-dev-100": {
      "command": "node",
      "args": ["C:/path/to/sap-abap-mcp/dist/index.js"],
      "env": {
        "SAP_URL": "https://your-sap-server.example.com:44301",
        "SAP_USER": "YOUR_SAP_USER",
        "SAP_SYSTEM_ID": "DEV",
        "SAP_CLIENT": "100",
        "SAP_LANGUAGE": "EN"
      }
    }
  }
}

Блок env клиента приоритетнее .env. Запустите npm run start, чтобы запустить сервер вручную, или npm run dev для работы через MCP Inspector.

Для клиента, который несёт все схемы инструментов в каждый обращение, добавьте профиль в этот же блок:

"env": { "…": "…", "ABAP_MCP_PROFILE": "core" }

В Docker

По умолчанию сервер разговаривает по MCP через stdio, поэтому портов не публикует — клиент запускает контейнер и общается с ним через stdin/stdout. Этот раздел описывает этот вариант; если контейнер используется по сети командой, выбирайте см. Работа по HTTP ниже.

docker build -t abap-adt-mcp .
{
  "mcpServers": {
    "sap-abap-dev-100": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--env-file",
        "C:/path/to/.env",
        "abap-adt-mcp"
      ]
    }
  }
}

Все четыре способа входа работают здесь, но учётные данные должны быть переданы контейнеру, а --env-file нет является dotenv — Docker не срезает кавычки, не читает export, не отбрасывает концевой # comment, поэтому значение, которое dotenv бы вычистило, приходит как есть. Windows-пути в .env придётся заменить на смонтированные. Kerberos — режим, требующий от контейнера более всего, а OAuth — минимум: токен отправщивается по сети, и монтировать ничего не нужно.

Режим сертификата — монтирует материал ключа только на чтение, вместе с CA, подписывающим SAP-сертификат:

docker run -i --rm --env-file .env \
  -v /host/certs:/certs:ro \
  -e SAP_CERT_FILE=/certs/agent.p12 \
  -e SAP_CA_FILE=/certs/corporate-root.pem \
  abap-adt-mcp

Режим Kerberos — образ включает curl, собранный с поддержкой GSS-API и kinit, поэтому остаются только область (realm) и учётные данные:

docker run -i --rm --env-file .env \
  -v /etc/krb5.conf:/etc/krb5.conf:ro \
  -v /host/agent.keytab:/krb5/agent.keytab:ro \
  -e SAP_KRB_KEYTAB=/krb5/agent.keytab \
  -e SAP_KRB_PRINCIPAL=SVC_AGENT@CORP.EXAMPLE.COM \
  abap-adt-mcp

Режим OAuth 2.0 — подключать ничего не нужно; учётные данные загружаются автоматически:

docker run -i --rm --env-file .env \
  -e SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token \
  -e SAP_OAUTH_CLIENT_ID='sb-abap-agent!t1234' \
  -e SAP_OAUTH_CLIENT_SECRET=<clientsecret> \
  abap-adt-mcp

Режим пароля — крайняя мера!

docker run -i --rm --env-file .env \
  -e SAP_USER=YourUser \
  -e SAP_PASSWORD=YourPassword \
  abap-adt-mcp

Три вещи, которые стоит знать, прежде чем к нему обращаться:

  • Keytab, а не ваш собственный билет. Контейнер не может заимствовать учётные данные сессии так, как это делает интерактивный вход. На Linux-хосте можно смонтировать уже имеющийся кэш билетов (-v /tmp/krb5cc_1000:/krb5/ccache:ro -e KRB5CCNAME=FILE:/krb5/ccache), но он истекает вместе с билетом хоста. Из-под Windows не работает ни один вариант: TGT живёт в кэше LSA и не может быть записан в файл — используйте сертификатный режим, которому ничего из этого не нужно. Keytab — единственные учётные данные, которые работают без участия человека, и единственные, которые переживают время жизни билета.

  • Проверяйте сертификат SAP или знайте, что вы этого не делаете. Образ доверяет только публичному набору корневых CA, поэтому внутренний CA, которому доверяет хост, здесь неизвестен, и рукопожатие завершается с ошибкой UNABLE_TO_GET_ISSUER_CERT_LOCALLY. Подмонтируйте корневой CA и укажите на него SAP_CA_FILE. Перенос настольного .env скопом лишь скрывает это: NODE_TLS_REJECT_UNAUTHORIZED=0 — это настройка для разработки, и ей не место в развёрнутом образе.

  • Собирайте из клона с --recurse-submodules. skills/Development — это подмодуль; без него в образ попадает на 35 навыков меньше.

Образ — Debian, а не Alpine, по одной причине: в Alpine curl собран без GSS-API, и такой curl не вызывает ошибку — он просто никогда не отправляет токен, а SAP отвечает тем же 401, что и при истёкшем билете. Что именно отсутствует, сообщается на stderr при запуске, до попытки создать сеанс. Чтобы спросить контейнер, какими учётными данными он воспользовался, передайте ему команду вместо сервера:

docker run --rm --env-file .env -v /host/agent.keytab:/krb5/agent.keytab:ro \
  -e SAP_KRB_KEYTAB=/krb5/agent.keytab abap-adt-mcp klist

docs/, skills/ и AGENTS.md намеренно копируются в образ — сервер читает их во время работы, чтобы обслуживать readServerGuide, readSkill и ресурсы abap-adt://. Полная настройка контейнера, режим за режимом, приведена в docs/Authentication.md §7.

Запуск по HTTP

Всё описанное выше запускает один сервер для одного клиента через stdio. Установите вместо этого ABAP_MCP_TRANSPORT=http, чтобы запустить долгоживущий контейнер, к которому по сети подключается целая команда, используя Streamable HTTP транспорт SDK на точке /mcp.

HTTP-режим меняет кто выполняет вход, а не то, что сеанс может делать после входа: ни один из четырёх режимов выше — SAP_AUTH_MODE, SAP_CERT_FILE, SAP_OAUTH_CLIENT_ID, SAP_PASSWORD — здесь не применяется, потому что настраивать общий вход не требуется. Вместо этого каждый MCP-клиент аутентифицируется своим собственным токеном OAuth 2.0 SAP: он отправляет Authorization: Bearer <token> в initialize, и этот токен становится учётной записью SAP этого сеанса — собственным входом в ADT, собственными блокировками, собственным журналом аудита. Два члена группы, подключённые одновременно, получают два независимых сеанса, но никогда одного общего технического пользователя.

docker build -t abap-adt-mcp .
docker run --rm -p 3000:3000 \
  -e SAP_URL=https://your-sap-server.example.com:44301 \
  -e SAP_USER=CLAUDEAGENT \
  -e SAP_CLIENT=100 \
  -e ABAP_MCP_TRANSPORT=http \
  abap-adt-mcp

SAP_USER по-прежнему требуется (в любом режиме, кроме пароля, нужно имя пользователя-запуска для создания ADT-клиента), но он никогда не передаётся и не влияет на то, кем на самом деле является сеанс — SAP определяет это по собственному токену каждого сеанса, как и в §11.

Переменная

Действие

ABAP_MCP_TRANSPORT=http

Переключает с stdio на Streamable HTTP.

ABAP_MCP_HTTP_PORT

Порт для прослушивания. По умолчанию 3000.

ABAP_MCP_HTTP_HOST

Адрес для привязки. По умолчанию 0.0.0.0.

ABAP_MCP_HTTP_ALLOWED_ORIGINS

Origin браузера, которым разрешено вызывать /mcp, через запятую; * разрешает любые. Пусто (по умолчанию) — ничего.

ABAP_MCP_HTTP_ALLOWED_HOSTS

Значения Host, на которые отвечают, разделённые запятой. Пусто — принимать любые.

ABAP_MCP_HTTP_RATE_LIMIT

Запросов в минуту на один сеанс. 0 (по умолчанию) — отключено.

Регистрируйте клиент так же, как любой удалённый сервер MCP со Streamable HTTP, указывая на /mcp и передавая собственный токен OAuth SAP этого пользователя:

{
  "mcpServers": {
    "sap-abap-dev-100": {
      "url": "http://your-host:3000/mcp",
      "headers": { "Authorization": "Bearer <your SAP OAuth access token>" }
    }
  }
}

Запрос без учётных данных отклоняется с 401 ещё до какого-либо обращения к SAP; токен, который отклоняет сам SAP, тоже возвращает 401 и сообщение от SAP. Отдельного общего секрета для транспорта настраивать не нужно — токен SAP и есть контроль доступа.

Клиент, не желающий разрывать соединение при каждом истечении срока действия access-токена, может вместо этого отправлять собственный refresh-токен в заголовке X-SAP-Refresh-Token, и тогда сеанс сам переиобретёт себя по grand refresh_token. Для этого требуются переменные SAP_OAUTH_TOKEN_URL и SAP_OAUTH_CLIENT_ID на контейнере, — регистрация клиента, при которой погашается refresh-токен, принадлежит развёртыванию, а сам refresh-токен и, следовательно, учётная идентичность SAP остается у вызывающей стороны.

Браузерные origin отклоняются, если они не перечислены в ABAP_MCP_HTTP_ALLOWED_ORIGINS: это защита от DNS-rebinding, которую MCP-сервер должен применять сам, поскольку rebinding-запрос никогда не проходит через прокси перед ним. Origin из списка исключений получают соответствующие заголовки CORS. Клиенты, которые не отправляют Origin — то есть все MCP-клиенты, не являющиеся веб-страницами, — не затрагиваются.

docker-entrypoint.sh контейнера автоматически пропускает свою настройку Kerberos, если задано ABAP_MCP_TRANSPORT=http, поскольку выбор resolveAuthMode() больше ничему (ничему реальному) не соответствует, когда каждый сеанс выполняет вход по своему токену. Завершение TLS остаётся на том, что стоит перед контейнером (reverse proxy или ingress), как и для любого другого внутреннего HTTP-сервиса. Полные детали, включая механику грантов OAuth, к которому это сводится, — в docs/Authentication.md §12.

Работа с несколькими системами

Сервер привязан к одной системе и одному клиентскому GET на протяжении всей своей жизни — ни то, ни другое нельзя переключить во время выполнения. Поэтому регистрируйте одну запись на каждую систему/клиента и задавайте им SAP_SYSTEM_ID:

"sap-abap-dev-100": { "env": { "SAP_SYSTEM_ID": "DEV", "SAP_CLIENT": "100", "…": "…" } },
"sap-abap-dev-200": { "env": { "SAP_SYSTEM_ID": "DEV", "SAP_CLIENT": "200", "…": "…" } },
"sap-abap-q01-100": { "env": { "SAP_SYSTEM_ID": "Q01", "SAP_CLIENT": "100", "…": "…" } }

Каждый сервер затем сообщает о себе в MCP instructions, которые возвращает при подключении:

Этот сервер привязан к системе SAP DEV, клиент 100 (https://…:44301). Он не может переключить систему или клиент во время работы — обе фиксированы окружением, в котором он был запущен. Если запрос ссылается двига систему или клиент, используйте MCP-сервер из этих; если не один не зарегистрирован, этот факт, а недейте здесь.

Именно это позволяет агенту обращаться «нужно проверить в DEV клиент 200» к нужному серверу, не вызывая ничего больше. healthcheck сообщает ту же идентичность для сервера, которому нужно спросить напрямую.

Проверка декларации. SAP имя системы и клиента в cookie сеанса, которую появляется при входе (SAP_SESSIONID_DEV_100), так что сервер знает, к чему он действительно подключён. Если это расходной с SAP_SYSTEM_ID — например, скопированная запись указывает не на тот хост — healthcheck содержит WARNING, и это громко логируется при запуске. Н этот интерфейс стоит внимания, потому что все инструменты работают отлично, просто на чужой системе.


Быстрый обзор

Читайте любой объект по имени — поиск URL не нужен:

{"tool":"readAbapObject","args":{"objectName":"ZCL_MY_CLASS"}}
{"tool":"describeAbapTable","args":{"tableName":"T000"}}

Обзор целой системы именования — паттерны нормализуются за вас, так что zpp_lab становится ZPP_LAB*:

{ "tool": "searchPackages", "args": { "patterns": ["ZPP_*", "Z_PP*"] } }
// -> each package with its objects grouped by type, sub-packages, and a `truncated` flag

Вызов функционального модуля — сначала читается сигнатура, и запрос проверяется против неё:

{"tool":"readAbapFunctionModule","args":{"functionModuleName":"STFC_CONNECTION"}}
{"tool":"callFunctionViaJsonRpc","args":{"functionModuleName":"STFC_CONNECTION",
                                         "inputParameters":{"REQUTEXT":"hello"}}}

BAPI и его commit должны идти в ** одном** батче, иначе commit попадает в собственную LUW и изменения BAPI теряются:

{
  "tool": "callFunctionsViaJsonRpc",
  "args": {
    "calls": [
      {
        "functionModuleName": "BAPI_USER_LOCK",
        "inputParameters": { "USERNAME": "DEVUSER" },
      },
      {
        "functionModuleName": "BAPI_TRANSACTION_COMMIT",
        "inputParameters": { "WAIT": "X" },
      },
    ],
  },
}

Полный цикл записи (lock → modify → check → activate → unlock), отладчик, ATC и все остальные сценарии — в docs/MCP-Tools.md §4.


Работа с объектами ABAP

Три инструменты закрывают большинство задач, и каждый принимает имя, а не ADT-URL:

Что вас интересует

Инструмент

Исходный код класса, программы, include, группы функций или модуля

readAbapObject

Как же выглядит таблица, структура или представление (view)

describeAbapTable

Всё, что за всеми часами в соглашении об именовании

searchPackages

{"tool":"readAbapObject",   "args":{"objectName":"ZCL_MY_CLASS"}}
{"tool":"describeAbapTable","args":{"tableName":"T000"}}
{"tool":"searchPackages",   "args":{"patterns":["ZPP_*","Z_PP*"]}}

readAbapObject возвращает метаданные и исходный код за один вызов. Когда имя принадлежит нескольким объектам — например, ZPP_EXT_LABEL_DATA — это и группа функций, и функциональный модуль, — он выбирает более конкретный и сообщает об этом (ambiguous:true и alternatives); передайте objectType, чтобы принудительно выбрать объект. Объекты, у которых нет исходного кода, возвращаются с hasSource:false и указанием на место, где и нужный инструмент.

describeAbapTable выдаёт имена полей, типы DDIC, длины, флаги ключей, элементы данных, домены и таблицы проверки — таблица проверки означает целевую сторону внешнего ключа, что является самым быстрым способом увидеть, как соединяются две таблицы. objectStructure для таблицы не возвращает полей, а sentence tableContents возвращает список значений, а не определение, так что ни тот, ни другой не дают ответ на вопрос «как выглядит эта таблица».

Правила для вашего системного промпта

  • Предпочитайте инструменты по именам. К searchObject → objectStructure → getObjectSource обращайтесь только тогда, когда нужны промежуточные результаты. Никогда не вручную создавайте пути /sap/bc/adt/....

  • Эффективные SELECT. Таблицы SAP велики. Всегда ограничи до SELECT через WHERE, и при любом возможности используйте SELECT SINGLE (когда все ключевые поля известны) или UP TO n ROWS.

SELECT vgbel FROM vbrp WHERE vbeln = @lv_vbeln INTO @DATA(lv_vgbel) UP TO 1 ROWS.
  EXIT.
ENDSELECT.

SAP отделён от вашей файловой системы: чтение исходного кода возвращается только как результат инструмента, а запись локального файла ничего не меняет в SAP. Локальные копии полезно брать только для сравнивания (diff).

В ранних README-файло перечислялись GetTable, GetStructure и GetTypeInfo. Они относятся к отдельному проекту mcp-abap-adt, не к этому серверу.


Разработка

npm run build          # tsc -> dist/
npm test               # vitest: parser, tool catalogue, JSON-RPC handler (no SAP system needed)
npx tsc --noEmit       # type check only

Тесты лежат в src/__tests__ и выполняются полностью локально — JSON-RPC-набор проверяет обработчик end-to-end на фейковом узле SAP Gateway.

Против реальной системы (при Kerberos-тикете) проверка end-to-end выполняется так:

npm run build
node scripts/live-jsonrpc-check.mjs      # add NODE_TLS_REJECT_UNAUTHORIZED=0 for an internal CA

Он управляет собранным сервером через MCP stdio точно так, как это делал бы клиент, и вызывает только функции чтения.

Добавить инструмент — это изменение одного файла — см. docs/MCP-Tools.md §10.

Устранение неполадок

Симптом

Причина / устранение

HTTP 401 при каждом вызове

Режим Kerberos: нет действующего билета, или система не принимает SPNEGO — проверьте klist и подключение к VPN/домену. Режим сертификата: см. docs/Authentication.md §6.

curl nicht gefunden

Сценарий настройки SSO не смог найти curl — задайте SSO_CURL_PATH.

SAP rejected the client certificate

Сопоставление CERTRULE, параметр icm/HTTPS/verify_client или доверие к ЦС в STRUST. В ошибке назван представленный субъект — сравните его с CERTRULE.

unable to get local issuer certificate

Внутренний ЦС. Установите NODE_TLS_REJECT_UNAUTHORIZED=0 (только для разработки).

RFC-инструменты возвращают reachable:false

Запустите checkJsonRpcEndpoint. Он отделяет неактивный узел SICF /sap/gw/jsonrpc от проблемы с CSRF или авторизацией.

-32601 из функционального модуля

Он не существует, не включён для RFC или S_RFC запрещает его функциональную группу.

Клиент не показывает инструменты

Проверьте абсолютный путь к dist/index.js и то, что npm run build был выполнен.

Подробнее в docs/MCP-Tools.md §8.

Участие

  1. Сделайте форк репозитория

  2. git checkout -b feature/your-feature-name

  3. Внесите изменения, сохраняя npm test и npx tsc --noEmit работающими

  4. git commit -m "Add some feature" и git push origin feature/your-feature-name

  5. Откройте pull request

Лицензия

MIT. Родительский проект и оригинальный автор: mario-andreschak.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    Not graded
    maintenance
    An MCP server that facilitates seamless interaction with SAP ABAP systems to manage development objects, transport requests, and source code. It provides a comprehensive suite of tools for performing syntax checks, object searches, and code modifications via the ADT API.
    100
    -
  • A
    license
    C
    quality
    D
    maintenance
    An MCP server that enables seamless communication between ABAP systems and MCP clients using the ABAP Development Tools (ADT) API. It provides tools for managing ABAP objects, handling transport requests, and performing code analysis directly through MCP-compatible interfaces.
    100
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A standalone MCP server for SAP ABAP development and customizing that connects directly to your SAP system via ADT REST API, enabling AI assistants to search, read, write, activate, transport, debug, and run quality checks on ABAP code, as well as manage customizing/IMG configurations with governed transport recording.
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP server for SAP ABAP development that enables AI assistants and code editors to interact with SAP systems via ABAP Developer Toolkit (ADT) APIs, supporting read, create, update, and delete of ABAP objects.
    100
    414 npm
    MIT