OrgRelay

REST compatible mode

For systems that only do plain REST. You implement two endpoints; OrgRelay treats the result exactly like an MCP connector, with the same tools, approvals and error codes.

Use this mode when MCP is not practical yet. A PHP 7 ERP, a Java service behind a strict gateway, or a team that already has a REST framework and no appetite for JSON-RPC. Everything in the connector spec applies unchanged; only the wrapper differs from the MCP transport.

The contract is published as spec/orgrelay-rest.openapi.yaml in the developer kit, so you can generate a server stub from it. All four templates serve REST mode on /orgrelay/* alongside MCP.

The two endpoints

Method and path Purpose
GET {base}/manifest Return the manifest. Each tool includes its inputSchema here
POST {base}/tools/{name} Call one tool. Body: { "arguments": { ... } }

{base} is whatever the admin types into OrgRelay, for example https://erp.example.internal/orgrelay. Authentication is the same as for MCP; see authentication.

Request headers

Header When Meaning
Authorization Always Bearer <token>, or Basic, or your API key header
X-OrgRelay-Actor Always base64url-encoded JSON: { "id", "name", "role", "department" }
Idempotency-Key Approved write calls orgrelay-approval-<approval id>. Execute once per key for 24 hours
X-OrgRelay-Approval-Id Approved write calls The approval request that authorised this call

These carry the same information as _meta in MCP. How the idempotency key must behave is described in approvals and write tools.

Responses

Success is 200 with the result object:

200 OK
{ "result": { "items": [ { "order_no": "SO-1001", "status": "paid" } ], "next_cursor": null },
  "text": "1 order found" }

text is optional; it is a short human-readable summary.

Failure uses an HTTP status plus an error object:

409 Conflict
{ "error": { "code": "conflict", "message": "SO-1002 has already shipped and cannot be cancelled." } }
Status code
400 or 422 invalid_arguments
401 unauthorized
403 forbidden
404 unknown_tool or not_found
409 conflict or idempotency_conflict
429 rate_limited, with Retry-After
502 upstream_error
500 internal_error

As with MCP, message reaches people. Keep stack traces, SQL and paths out of it; the security page has the full list.

Try it with curl

Start any template from the quickstart, then:

Read the manifest
curl -s http://127.0.0.1:8787/orgrelay/manifest \
  -H "Authorization: Bearer <tenant-a-token>" | head -c 400
Call a read tool
curl -s -X POST http://127.0.0.1:8787/orgrelay/tools/orders.search \
  -H "Authorization: Bearer <tenant-a-token>" \
  -H "Content-Type: application/json" \
  -d '{"arguments":{"status":"paid"}}'
Call a write tool twice with one key
for i in 1 2; do
  curl -s -X POST http://127.0.0.1:8787/orgrelay/tools/inventory.adjust \
    -H "Authorization: Bearer <tenant-a-token>" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: orgrelay-approval-test-1" \
    -d '{"arguments":{"sku":"HX-100","delta":1,"reason":"count"}}'; echo
done

The second write must return the first result and leave stock unchanged. The self-test tool automates exactly this with --mode rest --write.

Moving to MCP later

Because tool names, schemas, error codes and idempotency rules are shared, upgrading means adding an MCP endpoint that calls the same run() function. The templates show this: one dispatcher, two thin wrappers. Owners can then switch the connection type in OrgRelay without the AI noticing any difference.

REST mode or OpenAPI import?

They are easy to confuse:

REST compatible mode OpenAPI import
Who builds it You implement two endpoints Nobody; the API already exists
Tool names You choose, ideally standard names Derived from tags and operationIds
Read or write Declared per tool GET and HEAD default to read; everything else to write
Best for In-house systems SaaS platforms with published API docs

If the platform is a common SaaS product, check the connector directory first; it may already be covered.

Common questions

When to choose REST over MCP? When MCP is impractical in your stack or your security review prefers plain HTTPS endpoints.

Where does inputSchema go? On each tool inside the manifest.

How is this different from OpenAPI import? See the table above.

Next

Updated (Singapore time) · OrgRelay Team