Skip to content
ERP Preflight

MCP server

Connect coding agents through the Model Context Protocol: JSON-RPC endpoint, authentication, tools with their scopes and the local stdio bridge.

Content reviewed September 26, 2026

HTTP endpoint

POST /api/v1/mcp is a JSON-RPC 2.0 endpoint over plain HTTP. It implements the Model Context Protocol methods tools/list and tools/call; every other method — including initialize — is answered with the error -32601. The Streamable HTTP and SSE transports of MCP are not provided. MCP clients that need the full handshake use the stdio bridge below.

curl -s https://api.example.com/api/v1/mcp \
  -H "X-Api-Key: $ERP_PREFLIGHT_API_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_project_status","arguments":{"projectId":"<project id>"}}}'

Tool results are returned in result.content[0].text as JSON text. A tool call that fails — for example because a finding does not exist in your organization — sets result.isError. Protocol errors use -32601 (unknown method or tool), -32602 (invalid arguments) and -32003 (missing scope or tool not allowed).

Authentication and limits

  • Authenticate with an API key in X-Api-Key. A key needs at least one scope to reach the endpoint; each tool then checks its own scope (see below). Signed-in users can call the endpoint as well; the tool scopes do not apply to them.
  • Every call is tenant-scoped: tools read data of the caller's organization and global SAP knowledge only.
  • Limits: 600 calls per minute per organization and 120 per user or API key.
  • Every tools/list and tools/call request is recorded in the audit log.

Tools

  • search_knowledge (scope projects:read) — search the SAP knowledge graph (released objects, successors, release states) and published knowledge articles. Arguments: query (2 to 120 characters), optional targetRelease.
  • lookup_object (projects:read) — look up an SAP object in the organization's project object catalog and in the knowledge graph (release contract, Clean Core level, successors). Arguments: objectName, optional projectId.
  • compare_releases (projects:read) — compare the released-object lists of two SAP releases (newly released, deprecated, successor changes). Arguments: sourceRelease, targetRelease, optional objectPrefix and limit (1 to 200, default 50).
  • get_project_status (projects:read) — readiness of a project: latest completed analysis, open findings by severity and lifecycle status. Argument: projectId.
  • get_findings (findings:read) — findings of the latest completed analysis of a project, with lifecycle status. Arguments: projectId, optional severity and limit (1 to 200, default 50).
  • explain_finding (findings:read) — remediation guide, confidence and evidence pointers (path, line, SHA-256) of a finding. Argument: findingId.
  • generate_test (findings:read) — the regression test specifications generated for a finding; with promote: true the specification becomes an executable Test Lab case, which additionally requires findings:write. Arguments: findingId, optional promote.
  • get_analysis (analyses:read) — status, engines, timing and finding counts of one analysis run. Argument: analysisId.
  • preflight_change (changes:propose) — the Agent Change Firewall: submit a proposed SAP change before executing it. Arguments: projectId, summary (10 to 2000 characters), targetObjects (the touched SAP objects) and/or proposedDiff (the format of POST /agent-gate/propose), optional changeType, targetRelease, environment (DEV, QA — default —, STAGING, PROD) and agentId. The change is simulated and evaluated like a proposal in the Agent Gate; the result names proposalId, decision (APPROVE, REQUEST_CHANGES or BLOCK), the stored verdict, riskClass, the violated policies grouped into blocking, review and warnings with their messages, the evidence (target objects, blast radius, predicted findings, related findings), required approvals and tests, and reviewUrl, the page where a person decides. Requires the Agent Gate plan feature; shares the limit of 120 proposals per minute per organization and 30 per user or API key with the REST route.
  • get_change_verdict (projects:read) — the current decision, stored verdict, approvalStatus (PENDING_REVIEW, APPROVED, REJECTED, CHANGES_REQUESTED, EXECUTED) and the reviewer notes of a proposal. Arguments: proposalId, optional agentId. An agent reads only its own proposals; API keys must name the agent (X-Agent-Id or agentId); signed-in users read every proposal of their organization.

decision is derived from the stored verdict: CLEAR → APPROVE, CLEAR_WITH_WARNINGS → APPROVE with decisionWithWarnings: true, HUMAN_REVIEW_REQUIRED and INSUFFICIENT_EVIDENCE → REQUEST_CHANGES, BLOCKED → BLOCK. APPROVE is a recommendation: a person still approves every change. Never execute on BLOCK.

Apart from promoting a generated test and submitting a change proposal, the tools only read and explain; they change no data.

Registered agents

If a request carries the header X-Agent-Id with the id of an agent registered in your organization's Agent Gate, tools/list returns only the tools allowed for that agent and tools/call rejects all others with -32003. An agent without allowed tools can call none. Unknown or inactive agents are rejected. An agentId argument of preflight_change or get_change_verdict is held to the same allowed tools; if both are given they must match.

Agents are vendor-neutral: each has a kind (Claude, Codex, GitHub Copilot, SAP Joule or custom) and an optional vendor label, shown with its proposals. New agents may use search_knowledge, lookup_object, get_findings, explain_finding, get_project_status, preflight_change and get_change_verdict unless the registration names other tools. A preflight_change call that exceeds its budget returns -32029 with retryAfterSeconds; a plan without the Agent Gate returns -32003 with code: ENTITLEMENT_REQUIRED.

Local stdio bridge

The CLI package also provides erp-preflight-mcp, an MCP server over stdio for clients that start a local command. It answers initialize, tools/list, tools/call and ping. Its tools are prefixed erppreflight_ (for example erppreflight_list_projects, erppreflight_get_findings, erppreflight_search_knowledge) and call the REST API or the endpoint above with your API key, so the key's scopes apply. erppreflight_propose_change and erppreflight_simulate_changeset create and simulate change sets and need projects:write.

  • API key: ERP_PREFLIGHT_API_KEY, otherwise the key saved by erp-preflight login.
  • API URL: ERP_PREFLIGHT_API_URL, otherwise the URL saved by login, otherwise http://localhost:3001. /api/v1 is appended when missing, exactly as in the CLI.
  • Configuration directory: ERP_PREFLIGHT_CONFIG_DIR replaces ~/.erppreflight, as in the CLI.
  • Agent: ERP_PREFLIGHT_AGENT_ID (optional) is sent as X-Agent-Id on calls of the endpoint above, so the agent's allowed tools apply and change proposals are attributed to it.
  • erppreflight_preflight_change and erppreflight_get_change_verdict call the tools preflight_change and get_change_verdict with the same arguments.
  • erppreflight_get_status returns the API readiness report (/health/readiness: database, Redis, storage, analysis service, malware scanner) with its HTTP status.
  • erp-preflight mcp starts the same server as erp-preflight-mcp.

Example client configuration (the file and its location depend on your MCP client):

{
  "mcpServers": {
    "erp-preflight": {
      "command": "erp-preflight-mcp",
      "env": {
        "ERP_PREFLIGHT_API_KEY": "erppf_live_…",
        "ERP_PREFLIGHT_API_URL": "https://api.example.com",
        "ERP_PREFLIGHT_AGENT_ID": "<agent id from the Agent Gate>"
      }
    }
  }
}
MCP server — ERP Preflight Docs