Skip to main content
Glama

SAP-MCP

SAP on-premise 向けの MCP サーバー(ADT 経由)。MCP エンドポイントと Web 管理画面の両方を 1 つのプロセスで実行し、複数の SAP システムへ同時接続可能。デバッガーとランタイム診断ツールを備えています。ツール名は vibing-steampunk の PascalCase 規約に従い、さらにマルチシステムモデルと管理ページが追加されています。

使用するために SAP に ABAP オブジェクトをインストールする必要はありません — 唯一の例外は RunReport で、サーバーが自動的にインストールします(グループ D のセクションを参照)。

インストール

Windowsinstall.bat をダブルクリックするか、ターミナルで実行:

install.bat

Python 3.10+ をチェックし、.venv を作成し、依存関係をインストールし、サンプルファイルから systems.json を作成します。その後、systems.json を開いて実際の SAP システムの URL / ユーザー / パスワードを入力し、run.bat を実行します。

その他のプラットフォーム:

python -m venv .venv && . .venv/bin/activate
pip install -e .
cp systems.example.json systems.json   # sửa URL, user, password
python -m sap_mcp

systems.json にはパスワードが含まれており、.gitignore に含まれています — コミットしないでください。

サーバーの起動

Windowsrun.bat をダブルクリックするか:

run.bat              :: cổng 8765, chế độ focused (50 tool)
run.bat 8766         :: đổi cổng
run.bat 8766 expert  :: đổi cổng + bật đủ 66 tool

run.bat はコンソールを自動的に UTF-8 に設定し(ログにベトナム語が含まれ、コンソールが cp1252 だと Python がクラッシュします)、systems.json が存在しない場合はサンプルファイルから自動作成し、uvicorn が生のソケットエラーを投げる代わりに、どの PID がポートを占有しているかを明確に報告します。

http://127.0.0.1:8765 を開いて、システムの追加/編集/テストを行います。MCP エンドポイントは /mcp にあります。

MCP クライアントへの接続

mcp.example.json をプロジェクトディレクトリの .mcp.json にコピーするか、mcpServers セクションをクライアントの既存設定ファイルにマージします:

{
  "mcpServers": {
    "sap-mcp": {
      "type": "http",
      "url": "http://127.0.0.1:8765/mcp"
    }
  }
}

別のポートで run.bat を実行する場合は、ポートを合わせて修正してください。クライアントが接続する前にサーバーが起動している必要があります — これは streamable-http トランスポートであり、クライアントは stdio のようにプロセスを自動起動しません。

システム設定(systems.json

フィールド

デフォルト

意味

url

SAP システムの https://host:port

client

100

sap-client

language

EN

sap-language

username / password

Basic 認証

verify_ssl

true

自己署名証明書の場合は false に設定

ca_bundle

独自 CA のパス(verify_ssl の代わり)

timeout

30

通常の HTTP 上限(秒)

allow_write

false

有効にすると書き込み可能

write_packages

["Z*","Y*","$TMP"]

書き込みが許可されるパッケージ

write_objects

オブジェクト名による追加の制限

require_transport

true

トランスポート可能なパッケージは TR が必須

allow_debug

false

有効にするとグループ D を使用可能(デバッガー+コード実行)

debug_timeout

1800

ブレークポイントで停止できる時間(秒)

debug_listen_seconds

300

DebuggerListen のデフォルト待機時間(秒)

標準 SAP 名前空間のオブジェクトは常に拒否され、設定で無効にすることはできません。

debug_timeout は単なる気休めの数値ではありません。 ブレークポイントで停止したコードは、それを実行した HTTP リクエストを保持し続けるため、通常の timeout(30 秒)は変数を確認している最中に切断してしまいます。バックグラウンドスレッドが死に、レポート結果は失われ、DebuggerDetach はデータの代わりに The read operation timed out を返します。この上限はデバッグ中のみ(リスナーが存在するか、デバッギーで停止中)引き上げられます — すべての実行で引き上げると、ハングしたレポートが誰も見ていないのに SAP のワークプロセスを30分間占有することになります。

環境変数

変数

デフォルト

意味

SAP_MCP_SYSTEMS

./systems.json

設定ファイルのパス

SAP_MCP_PORT

8765

HTTP ポート

SAP_MCP_MODE

focused

focused(50 ツール)または expert(66 ツール)

SAP_MCP_DISABLED_GROUPS

機能グループを無効化、例: C または C,D

グループコード: C トランスポートリクエスト、D デバッガー、P ランタイム診断(ダンプ、トレース)— 下記のツールのセクションを参照。コアツールはどのグループにも属さず、常に有効です。両方を無効化(SAP_MCP_DISABLED_GROUPS=D,P)すると、focused/expert は 30/45 ツールに戻ります。

ツール

管理 ListSystems GetConnectionInfo GetSystemInfo

読み取り GetSource GetObjectStructure GetClassInfo GetPackage GetFunctionGroup SyntaxCheck · expert: GetProgram GetClass GetInterface GetInclude GetFunction GetClassInclude

GetSource はオブジェクト全体ではなく一部を読み取れます: around="SELECT" はコメント外の最初の出現箇所の周囲のウィンドウを取得し、from_line/to_line は正確な行範囲を取得します。どの部分も、それが部分であることを示すコメント行で始まります — UpdateSource に渡せるのは完全版のみで、ウィンドウで上書きすると残りが削除されます。GetPackage には max_objects の上限があり、切り詰めた場合にその旨を明示します。

検索 SearchObject GrepObjects GrepPackages · expert: GrepObject GrepPackage

データ RunQuery GetTableContents

RunQuery は Open SQL SELECT を実行し、結果テーブルを返します。GetTableContents は SELECT 文を自動生成します。allow_write は不要です。なぜならSAP 自体がこのエンドポイントでの書き込みコマンドを拒否するからです:

DELETE FROM t001 …  → 400 Invalid query string. Only SELECT statement is allowed.

読み取りの境界は systems.json の SAP ユーザーの権限です — そのユーザーが読み取れるすべてのテーブルはエージェントも読み取れます(人事テーブルも含む)。万能ユーザーを設定しないでください。

ソースコードナビゲーション FindDefinition FindReferences

FindDefinition(system, 'CLAS', 'ZCL_X', symbol='cl_salv_bs_runtime_info') — サーバーがソース内のシンボルを自動検索し(コメントはスキップ)、その位置で解決して、型、名前、コンポーネントのリストを返します。名前はもっともらしく聞こえますが navigation/target は使用しません。解決できない場合に入力 URI 自体を返すため、偽の成功になります。使用可能なパスは abapsource/codecompletion/elementinfo で、ボディにソース全体が必要です。

FindReferences は where-used を返します。SAP は3種類のノードが混在するツリーを返します。gradeDirect を持つインデックスのみが実際の使用箇所です。gradeComponent は調査中のオブジェクト自体のコンポーネントです — これを数えると、誰も呼んでいないクラスが突然6つの使用箇所を持つことになります。

書き込み WriteSource EditSource Activate ActivatePackage CreatePackage GetInactiveObjects LockObject UnlockObject · expert: CreateObject UpdateSource DeleteObject

合成 CompareSource CloneObject PrettyPrint ImportFromFile ExportToFile

グループ C ListTransports · expert: GetTransport CreateTransport ReleaseTransport DeleteTransport

グループ D — デバッガー SetBreakpoint DeleteBreakpoint DebuggerListen DebuggerPoll DebuggerStopListener DebuggerAttach DebuggerDetach DebuggerGetStack DebuggerGetVariables DebuggerStep RunClass RunReport RunUnitTests

allow_debug: true が必要です。使用手順:

  1. SetBreakpoint — 行は実行可能なステートメントである必要があり、宣言ではありません。行を数える必要はありません: statement="SELECT" でサーバーが自動検索します(コメントをスキップするため、実行不可能な行に落ちることはありません)そして行番号を報告します。

  2. DebuggerListen — 即座に返り、リスナーはバックグラウンドで実行

  3. RunClass / RunReport / RunUnitTests — コードを実行

  4. ブレークポイントが発火した場合、ステップ3は即座に ブレークポイントで停止しました … を返します(データではありません)。DebuggerPoll はいつでも状態を確認できます。

  5. DebuggerAttachDebuggerGetStack / DebuggerGetVariables / DebuggerStep

  6. DebuggerDetach — デバッギーを解放。コードは実行を完了し、ステップ3の結果はここで返されます(長時間実行の場合は DebuggerPoll で)

ブレークポイントが発火しなかった場合、ステップ3は通常のツールと同様に結果を直接返します。

なぜ3つのコード実行ツールがバックグラウンドで実行されるのか。 コードがブレークポイントで停止すると、SAP はそれを実行している HTTP リクエストを保持します — 呼び出しはデバッギーが解放された後にのみ返ります。同期呼び出しでは、そのツール自体がハングし、エージェントは DebuggerAttach を呼び出して解放することができなくなります: 自分自身でロックしてしまうのです。そのため、これら3つのツールはバックグラウンドスレッドの専用セッションで実行され、リスナーがデバッギーを捕捉するとすぐに応答します。

デバッグ時、各システムは3つの独立した HTTP セッションを使用します: リスナー+デバッグセッション用(ステートフル、数十秒間保持される)、コード実行用(デバッギー解放までブロックされる可能性あり)、ブレークポイント設定/削除用。分離しないと互いにブロックし合います: リスナーのセッションでコードを実行すると、2つのロングポーリングの間の隙間に入り込むだけです — ちょうど SAP にリスナーが登録されていない瞬間なので、ブレークポイントは決して発火しません。

選択画面付きレポートのデバッグ。 外部ブレークポイントはダイアログセッションを捕捉できません — SE38 で F8 を押してもデバッガーは何も検出しません(実システムで測定済み)。ステップ3で RunClass の代わりに RunReport を使用してください: 外部セッションでレポートを実行するため、ブレークポイントが発火します。

RunReport は ALV 表示をブロックしつつデータを取得します(cl_salv_bs_runtime_info)。そのため、ALV で終わるレポートも途中でダンプしません。PARAMETERSSELECT-OPTIONS(パラメータ名が S_ で始まるもの)およびバリアントの両方を受け付けます。

RunReportSAP に書き込みを行うため、他のデバッガーツールのような allow_debug だけでなく、allow_writeallow_debug の両方が必要です。サーバーが2つのオブジェクトを $TMP に自動インストールするため、何もする必要はありません:

  • ZCL_MCP_RUNNER — 中間クラス。汎用的で、決して変更されません。 これは SUBMIT (mv_report) WITH SELECTION-TABLE mt_sel を実行します。つまり、レポート名と選択画面全体が実行時のデータです。

  • ZMCP_RUNNER_ARGS — コメント行のみで構成されるプログラムで、実行のたびに書き換えられます。クラスは実行時に READ REPORT で読み取ります。

*@MCP TOKEN 24b8bff8dfb8477b
*@MCP REPORT ZPG_DEMO
*@MCP MAX 100
*@MCP SEL S_BUKRS S I BT
*@MCP LOW 1000
*@MCP HIGH 2000

なぜ書き込みが必要なのか: IF_OO_ADT_CLASSRUN~MAIN( out ) はパラメータを受け付けません — クエリパラメータもボディもありません。オブジェクトのソースは、ADT REST が開く唯一のパラメータ転送チャネルです。

最も重要な結果は安全性です: エージェントが提供するものが ABAP コードになることはもうありません。以前のバージョンはフィルタ値を ABAP リテラルに埋め込んでいたため、クォートが1つ漏れると SAP システムに任意のコマンドを注入できました — その箇所はエスケープしないと安全ではありませんでした。現在は値がコメント行にあり、RSPARAMS テーブルを通じて SAP に届くため、壊す構文はありません。禁止されているのは改行文字のみです(偽のパラメータ行を生成します)。また、45 文字を超える値は拒否されます。RSPARAMS-LOWCHAR45 であり、SAP は黙って切り詰めるため、誰も気づかないうちにフィルタが誤動作します。

実行のたびにトークンが付与され、クラスはそのトークンを返し、サーバーが照合します。パラメータの書き込みが壊れていても実行が続行された場合、レポートは古いパラメータで実行され、結果には新しいリクエストのラベルが付けられます — トークンはこの種の静かな誤動作を防ぎます。

vibing-steampunk(プラグイン ZADT_VSP が必要: 1 インターフェース、3 クラス、WebSocket ハンドラー)と比較すると、RunReport は必要なものが少なく、SAPC + SICF の手動設定も不要です:

vsp (ZADT_VSP)

SAP-MCP (RunReport)

インストールが必要な ABAP オブジェクト

4

2

SAPC + SICF の設定

basis 管理者が必要

不要

サーバーが自動インストール

不可

可能

実行ごとにクラスを変更

しない

しない

SELECT-OPTIONS

不可(kind='P' をハードコード)

可能

実行ごとに SAP へ書き込み

しない

する(コメントファイル1つ)

最後の行は、管理者によるインストールが不要であることの代償です: vsp は WebSocket 経由でパラメータを渡すためシステムに触れませんが、RunReport は ADT REST が他のチャネルを開かないためソース経由で渡します。その代わり、書き込まれるオブジェクトはコメントのみのファイルです — 壊れる構文はなく、ロジックを含むクラスはそのままです。

グループ P — ランタイム診断 ListDumps GetDump StartTrace ListTraces GetTrace DeleteTrace GetSQLTraceState · expert: DeleteTraceRequest

ショートダンプ(ST22)。 ListDumpsuser/error/program/since でフィルタリングし、 GetDumpsummary(何が起きたか、エラー分析、停止箇所、コール スタック)、source(障害発生箇所のソースコード)、full、または meta を返す。

パフォーマンス測定(SAT/ATRA)。 StartTrace('ZPG_X', 'report') → コードを実行 → ListTracesGetTraceGetTrace はデフォルトで呼び出しごとの時間プロファイルを 降順で返す。view='db' はテーブルごとのDBアクセスを返す — 回数、バッファ取得回数、時間。 RunReport(..., trace=True) は一連の流れを簡潔にする:自動でそのレポートに限定した測定リクエストを設定する。

   NET µs      %  GROSS µs   LẦN  GỌI TỪ                     VIỆC
     3800   51.2      3800     1  CL_HTTP_SERVER_NET=======C DB: Exec Static
      368    5.0      4185     1  SAPLHTTP_RUNTIME           Call M. …SEND_RESPONSE

NW 758で実測した3つの事柄は、vibing-steampunkが想定していたことと逆であり、 それぞれが指示どおりに実行するとツールを静かに壊す:

vsp のやり方

NW 758 での実測結果

ダンプの Accept

application/atom+xml

406…;type=feed でなければならない

ダンプのフィルタリング

$filter の FQL を送信

SAP は無視して全リストを返す

ST05 trace/directory

フィードトレースとして読む

URLひとつを返し、レコードがない

そこで ListDumps はMCPサーバー側でフィルタリングし、SQLステートメントはST05ではなくABAPトレースのdbAccessesから取得する。GetSQLTraceState は、オンのまま放置されたトレース(システム全体を遅くするが外からは見えない)を検出するのに依然として有用である。

StartTrace にはオブジェクト名が必須。 制限なしのトレース要求は、それを生成したまさにそのHTTP呼び出しを捕捉してしまう。つまり、計測結果は ICFSERVICE/HTTP_HEADER_HEADER_REG だらけになり、ADTの仕組みを計測することになってコード自体は計測されないのに、非常にそれらしい数値の表に見える。制限を付ければ、計測はその後の実行に正しく落ちる(T001DDFTXVARID…)。

StartTraceDeleteTraceDeleteTraceRequest には allow_debug が必要:これらはシステムの動作を変更し、放置されたリクエストは後続の実行を密かに計測することになる。読み取り専用の3つのツール(ListDumpsGetDumpGetSQLTraceState)には不要。

ステータス

コアツール群、Dグループ(デバッガー、RunReport を含む)、Pグループ(ダンプ+トレース)は完了:50ツールが focused モード / 66ツールが expert モードで、NetWeaver 758 上で実行済み。i18n付きDDIC、abapGit、ABAPヘルパーは未完了。

既知の制限

1. ImportFromFile / ExportToFile はパスを制限しない。 この2つのツールは、モデルが与えるあらゆるパスを受け付ける。import_from_fileos.path.isfile のチェックのみ、export_to_fileos.path.isfile のチェックのみで、許可リストもワークスペースディレクトリへの制限も、相対パスや絶対パスのブロックもない。つまり、(SAPから読み取った内容に影響を受けるエージェントを含む)エージェントは、サーバープロセスが読み取れる任意のファイルを読み取ってSAPに渡したり、SAPソースを書き込み可能な任意のパスに書き出したりできる。現在の回避策:サーバーは、あなたが管理するマシン上で、エージェントにアクセスさせたいファイル以外にアクセス権のないアカウントでのみ実行する。

2. REST管理ルートに認証がない。 //api/systems*127.0.0.1 へのバインドでのみ保護されている。そのポートのループバックに到達できるものはすべて、システム構成の一覧表示・追加・編集・削除、および接続テストの起動ができる。このポートをローカルマシンの外に公開したり、共有ホスト上で実行したりしないこと。

3. デバッガーはメモリ内のすべての変数を読み取れる。 DebuggerGetVariables はブレークポイントで実際の値を返す。そこには変数内に存在する機密データ(パスワード、キー、個人データ)が含まれる。これはデバッグの本質である。さらに RunClass は任意のABAPを実行する。そのため allow_debug はデフォルトでオフであり、開発システムでのみ有効にすべきである。

4. RunReport は単一のパラメータファイルを共有する。 $TMP 内の ZMCP_RUNNER_ARGS は毎回上書きされる。1つのサーバー内では実行はすでに直列化されている(システムごとに1つの実行スレッド)が、同じシステムを共有する2つのサーバーや2人のユーザーは互いのパラメータを上書きし合う。出力内のトークンがこれを検出してエラーに変換し、誤ったデータを返すことはない。vibing-steampunkは、セッションごとに専用のWebSocket APCを使用することでこれを完全に回避しており、その代わりにSAP*を手動で設定する必要がある

  • SICF。

アーキテクチャ

transport/(HTTP、認証、CSRF)→ adt/(オブジェクトタイプ、データ返却)→ tools/(フォーマット + MCP登録)。adt/uri.py テーブルがURI構築の唯一の情報源である。Dグループはさらにシステムごとに3つの AdtSession を使用する(transport/debug_pool.py、チャネルで分割)。リスナーがバックグラウンドで実行され、デバッグセッションは複数の呼び出しにわたって状態を維持する必要があり、実行中のコードがブレークポイントでブロックされる可能性があるため、共有の SessionPool からはどのセッションも借用できない。

ツールはイベントループ上ではなくワーカースレッドで実行される。 FastMCPはイベントループ上で同期的な関数を直接呼び出すため、そのままにしておくとSAP呼び出しがサーバー全体をブロックしてしまう:RunReport が待機している間、エージェントは DebuggerPoll を呼び出せず、異なるシステムが互いにブロックし合い、Web管理画面もフリーズする。tools/_registry.py は、登録前にすべてのツールを anyio.to_thread.run_sync でラップする。システムごとの直列化は残っており、意図的である — それは SessionPool にあり、SAPのロックハンドルは接続ごとにのみ有効だからである。

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.

  • Official Microsoft MCP Server to query Microsoft Entra data using natural language

  • GibsonAI MCP server: manage your databases with natural language

View all MCP Connectors

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/NhatPD-VNEXT/SAP-MCP'

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