MCP transport
The recommended way to connect a system. One URL, four JSON-RPC methods, and the same server works in OrgRelay, Claude, Codex and any other MCP client.
MCP is the transport we recommend for new connectors. The alternative, REST compatible mode, uses exactly the same tool definitions and error codes, so moving between them later only changes the wrapper. If you have not run a connector yet, the quickstart gets one running in a few minutes.
What OrgRelay sends
Everything is POST to one URL, for example https://erp.example.internal/mcp, with Authorization: Bearer <token> (or whatever authentication you chose) and a JSON-RPC 2.0 body.
| Method | When | What you return |
|---|---|---|
initialize |
On binding and after a session expires | protocolVersion, serverInfo, capabilities: { tools: {}, resources: {} } |
notifications/initialized |
Right after initialize |
202 Accepted, no body |
tools/list |
On binding and on Test connection | Your tools with inputSchema and annotations.readOnlyHint |
resources/read |
On binding, with uri: "orgrelay://connector/manifest" |
The manifest as JSON text |
tools/call |
Whenever the AI or an approved request uses a tool | structuredContent plus a JSON copy in content |
Protocol version 2025-06-18; servers answering 2025-03-26 also work. Replies may be application/json or text/event-stream. Plain JSON is simplest.
Sessions
You may return an Mcp-Session-Id header on the initialize response. OrgRelay sends it back on every later request. If a session has expired, answer 404 and OrgRelay initialises again. Stateless servers that never issue a session id are fine too; all four templates are stateless.
A tools/call request
{
"jsonrpc": "2.0",
"id": 17,
"method": "tools/call",
"params": {
"name": "inventory.adjust",
"arguments": { "sku": "HX-220", "delta": 60, "reason": "cycle count" },
"_meta": {
"orgrelay/actor": { "id": "u_42", "name": "Lin Wei", "role": "manager", "department": "warehouse" },
"orgrelay/approval_id": "apr_7c1e",
"orgrelay/idempotency_key": "orgrelay-approval-apr_7c1e"
}
}
}The _meta block is how your system learns who asked and who approved. orgrelay/actor is present on every call. The approval id and idempotency key appear only on write calls that a person approved, as described in approvals and write tools. Logging the actor and approval id in your own audit trail is encouraged.
A successful result
{
"jsonrpc": "2.0",
"id": 17,
"result": {
"structuredContent": { "ok": true, "id": "HX-220", "message": "HX-220 on hand 200", "on_hand": 200 },
"content": [{ "type": "text", "text": "{\"ok\":true,\"id\":\"HX-220\",\"message\":\"HX-220 on hand 200\",\"on_hand\":200}" }]
}
}OrgRelay reads structuredContent. The content copy is for clients that only read text, such as an MCP client that is not OrgRelay.
Errors
There are two layers, and it matters which one you use:
- Protocol problems use JSON-RPC errors. An unknown tool or arguments that fail the schema return
-32602. - Business problems are a normal result with
isError: trueandstructuredContent: { error: { code, message } }. "Order not found" and "already shipped" belong here.
{
"jsonrpc": "2.0", "id": 18,
"result": {
"isError": true,
"structuredContent": { "error": { "code": "conflict", "message": "SO-1002 has already shipped and cannot be cancelled." } },
"content": [{ "type": "text", "text": "SO-1002 has already shipped and cannot be cancelled." }]
}
}Authentication failures are plain HTTP: 401 for a bad or revoked token, 403 for a valid token without permission, 429 with Retry-After for rate limiting. The full code list is in the connector spec.
readOnlyHint must match access
Every tool in tools/list carries annotations.readOnlyHint. It must be true exactly for tools whose manifest access is read. If the two disagree, OrgRelay assumes write, and the self-test tool fails the check readOnlyHint consistent.
This matters beyond OrgRelay. When the same server is used directly from Claude Code or Codex, those clients also use the hint to decide whether to ask before running a tool.
Reachability
OrgRelay normally runs on the customer's LAN, so an internal address such as http://10.0.0.12:8787/mcp is fine. Use HTTPS whenever traffic leaves the LAN, and do not redirect: OrgRelay does not follow redirects. More on network placement is in security requirements.
Same server, more clients
A connector built this way is an ordinary MCP server. Developers often test it in an AI client before involving OrgRelay at all:
claude mcp add --transport http sample-erp http://127.0.0.1:8787/mcp \
--header "Authorization: Bearer <tenant-a-token>"That is also why we recommend MCP over REST for new work. The trade-off is explained for buyers on orgrelay.com's integrations page; for developers the short version is that MCP gives you more clients for the same code.
Common questions
Which protocol version? 2025-06-18, compatible with 2025-03-26.
Do I need server-sent events? No. JSON replies are enough.
Will it work in Claude or Codex too? Yes. They ignore the manifest resource and the OrgRelay _meta fields.
Next
- Implement authentication beyond a static token.
- Add event push so OrgRelay hears about new orders without polling.
- When a vendor already runs its own MCP server, see third-party MCP instead of building one.
- Browse the connector directory to see how existing connectors name and describe their tools.
- If MCP is not an option for your stack, the same tools work over REST compatible mode.
- Prove it with the self-test tool before binding.
- Name tools after the standard tools so OrgRelay routes them to department agents.
- Why write tools wait for a person: human-in-the-loop for MCP.
Related pages
- MCP overview: OrgRelay as an MCP server for staff.
- Enterprise patterns: permissions, offboarding and data residency.