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/listandtools/callrequest is recorded in the audit log.
Tools
search_knowledge(scopeprojects:read) — search the SAP knowledge graph (released objects, successors, release states) and published knowledge articles. Arguments:query(2 to 120 characters), optionaltargetRelease.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, optionalprojectId.compare_releases(projects:read) — compare the released-object lists of two SAP releases (newly released, deprecated, successor changes). Arguments:sourceRelease,targetRelease, optionalobjectPrefixandlimit(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, optionalseverityandlimit(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; withpromote: truethe specification becomes an executable Test Lab case, which additionally requiresfindings:write. Arguments:findingId, optionalpromote.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/orproposedDiff(the format ofPOST /agent-gate/propose), optionalchangeType,targetRelease,environment(DEV,QA— default —,STAGING,PROD) andagentId. The change is simulated and evaluated like a proposal in the Agent Gate; the result namesproposalId,decision(APPROVE,REQUEST_CHANGESorBLOCK), the storedverdict,riskClass, the violated policies grouped intoblocking,reviewandwarningswith their messages, the evidence (target objects, blast radius, predicted findings, related findings), required approvals and tests, andreviewUrl, 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, optionalagentId. An agent reads only its own proposals; API keys must name the agent (X-Agent-IdoragentId); 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 byerp-preflight login. - API URL:
ERP_PREFLIGHT_API_URL, otherwise the URL saved bylogin, otherwisehttp://localhost:3001./api/v1is appended when missing, exactly as in the CLI. - Configuration directory:
ERP_PREFLIGHT_CONFIG_DIRreplaces~/.erppreflight, as in the CLI. - Agent:
ERP_PREFLIGHT_AGENT_ID(optional) is sent asX-Agent-Idon calls of the endpoint above, so the agent's allowed tools apply and change proposals are attributed to it. erppreflight_preflight_changeanderppreflight_get_change_verdictcall the toolspreflight_changeandget_change_verdictwith the same arguments.erppreflight_get_statusreturns the API readiness report (/health/readiness: database, Redis, storage, analysis service, malware scanner) with its HTTP status.erp-preflight mcpstarts the same server aserp-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>"
}
}
}
}