Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcp2_tests

Integration test bed for the mcp2 ABAP MCP Server SDK: ABAP test servers (src/), abapGit table-content provisioning (data/), and a Jest suite (test/) that exercises a live ABAP system over HTTP.

Compatibility profile

The native target is the MCP 2026-07-28 draft synchronous request/response profile. ABAP ICF cannot provide SSE or streaming responses, so sessions, subscriptions/listen, server-pushed notifications, and other streaming-only features are explicitly unsupported and tested as such. Ordinary requests use single application/json responses.

Legacy 2025-03-26, 2025-06-18, and 2025-11-25 requests are supported statelessly using the latest legacy (2025-11-25) data shapes. Without a session, requests following initialize cannot recover an older negotiated revision reliably because the older revisions did not require a per-request version header.

Layout

  • src/ — minimal, full-capability, schema, and authorization test servers. The schema server covers complex, wide, deep, and DDIC-derived schema integration cases; the authorization server is registered twice to exercise both allow and deny paths.
  • data/ — abapGit table-content files that provision the zmcp2_servers and zmcp2_origins rows the suite expects (area TEST, servers MINIMAL, FULL, SCHEMAS, ALLOWED, and DENIED).
  • test/ — Jest suite. cd test && npm test. Endpoint defaults to http://172.26.128.1:8000/zmcp2 (override with MCP2_BASE_URL).

Table-content provisioning (data/) — read this before debugging "missing rows"

The data/*.conf.json + *.tabu.json pairs are abapGit table content (TABU) files. abapGit only deserializes them when all of the following hold — otherwise it silently skips them or raises Table … not supported for updating data, and the rows never appear:

  1. The target table must pass abapGit's data supporter. By default only customer-defined customizing tables qualify: transparent table, delivery class C, data class APPL2, active, not SAP-owned (zcl_abapgit_data_supporter->get_supported_objects). The mcp2 config tables (zmcp2_servers, zmcp2_origins, zmcp2_config) are set up exactly like that — note APPL0 would not work, which is why data pulls silently did nothing before the tables were switched to APPL2. Alternatively a system-wide abapGit user exit (zif_abapgit_exit~change_supported_data_objects) can whitelist tables.
  2. The data objects must be confirmed in the pull dialog. TABU entries show up as decisions alongside overwrite prompts; unconfirmed entries are skipped.
  3. Customizing request. In a transportable package, pulling customizing-table rows prompts for a customizing request. In a $-package this doesn't apply.
  4. Client. Rows are written to the client you are logged into during the pull, and the suite's servers run in client 001 — pull in 001.

Manual fallback

If data deserialization still doesn't cooperate, enter the rows by hand (SE16/SM30). Values are case-insensitive where noted:

Table Row
zmcp2_servers TEST / MINIMAL / ZCL_MCP2_TEST_MINIMAL
zmcp2_servers TEST / FULL / ZCL_MCP2_TEST_FULL
zmcp2_servers TEST / SCHEMAS / ZCL_MCP2_TEST_SCHEMAS
zmcp2_servers TEST / ALLOWED / ZCL_MCP2_TEST_AUTH
zmcp2_servers TEST / DENIED / ZCL_MCP2_TEST_AUTH
zmcp2_origins TEST / FULL / ALLOW1 / https://allowed.example (origin matching is case-insensitive, uppercase is fine)

In the SAP client running the suite, zmcp2_config must have no cors_mode = ignore row — the CORS tests assume the default check mode (an empty table is fine).

License

MIT. See LICENSE.

Running the suite

cd test
npm test          # full suite against the live system
npx tsc --noEmit  # typecheck only

The suite is the authoritative test count; it covers both protocol eras (legacy initialize clients and modern _meta clients), raw-HTTP edge cases, header mirroring, CORS, tasks, and MRTR input round-trips.

Manual ABAP schema benchmark

Run ZMCP2_SCHEMA_BENCH from SE38, or profile it directly with SAT. Parameters control schema width, nesting depth, iterations, and whether DDIC generation is included. The report prints separate build, serialization, validation, and DDIC timings plus the serialized schema size. Defaults are intentionally moderate; use SAT variants for repeatable comparisons.

Pinned specification schemas

test/schema/ vendors the official generated JSON schemas for every supported legacy revision and the modern draft. test/schema/pin.json records the exact upstream commit and SHA-256 hashes, so normal tests remain network-independent. Run npm run schema:refresh -- <git-ref> from test/ to update the snapshot and pin manifest, then review the resulting schema diff before committing it. The modern Tasks extension is pinned independently from the core specification using the generated schema from modelcontextprotocol/ext-tasks. The pin manifest records both upstream commits and every vendored schema hash.

The test:schema suite validates representative JSON-RPC envelopes and method-specific results using draft-07 for older revisions and 2020-12 thereafter. Legacy method results intentionally use the 2025-11-25 schema profile for all supported legacy headers because the stateless server cannot retain the version negotiated by an earlier initialize request.

SDK versus raw HTTP coverage

The test project pins the v2 TypeScript SDK packages to the exact published 2.0.0-beta.4 release; the v1 alias remains for legacy compatibility coverage. The modern and legacy suites use the SDK for ordinary tools, resources, prompts, completion, discovery, and elicitation flows. Raw HTTP remains intentional for transport headers, HTTP status codes, malformed JSON-RPC nodes, media types, exact result metadata, and legacy/modern wire-shape checks.

Modern Tasks also remain raw: beta.3's 2026 wire registry does not expose tasks/get, tasks/update, or tasks/cancel, and its exported task schemas are the deprecated 2025 vocabulary rather than SEP-2663's flat task results. This prevents the beta SDK from masking Tasks interoperability defects until it adds the extension surface (confirmed still unimplemented as of 2.0.0-beta.4; see modelcontextprotocol/typescript-sdk#2189).

Modern serverInfo is checked in both places the server writes it. The 2026-07-28 draft moved serverInfo out of the top-level DiscoverResult and into every modern result's _meta under io.modelcontextprotocol/serverInfo (schema change merged 2026-07-16, three days after 2.0.0-beta.4 shipped) — but every currently published SDK release, including 2.0.0-beta.4, bundles a DiscoverResultSchema that still requires the old top-level field, and fails client.connect()'s version-negotiation probe outright if it's missing (not just a stale getServerVersion() — the whole modern SDK connection breaks). The server therefore writes serverInfo top-level (discover only, for every current SDK) and in _meta (every modern result, spec-current). modern/discover.test.ts keeps asserting the top-level field via the SDK; the ... (via _meta) tests in raw/http.test.ts cover the new location until a released SDK reads it for the modern era, at which point the top-level write can be dropped.

About

Tests for the V2 SDK

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages