Skip to content

MCP server

Connect Claude, Claude Code, Cursor or any MCP client to OrderLoop at /mcp, with the same tools as the assistant, limited by role.

OrderLoop serves its workspace tools to Model Context Protocol clients at https://orderloop.app/mcp. They are the tools of the assistant, so a client can check what needs attention, find and read orders, and, with the right role, decide approvals or cancel orders. Each person is limited to what their role allows.

The server is stateless: every request is answered by a fresh server that lists only the tools the caller’s role can use. It speaks streamable HTTP, the draft 2026-07-28 revision of the protocol and the 2025 stateless lane. Another agent that speaks Agent2Agent rather than MCP connects at /a2a; see A2A endpoint.

Add a custom connector with the URL https://orderloop.app/mcp. The client discovers the authorization server, registers itself and opens OrderLoop’s consent page in your browser:

  1. Sign in with your own account. Two-factor sign-in applies. The workspace password can’t connect an app, because an app’s actions must trace to a person.
  2. Check which app is asking and where access will be sent. An app that registered itself is marked as unverified; an app on your own computer gets an extra warning.
  3. Choose a role. You are offered your own role and the roles below it, lowest first, and the lowest (viewer) is selected. That role is the grant’s scope.
  4. Select Connect. Cancel refuses the app.
claude mcp add --transport http orderloop https://orderloop.app/mcp

Claude Code runs the same browser flow the first time you use the server. To skip the browser, pass an API token:

claude mcp add --transport http orderloop https://orderloop.app/mcp \
--header "Authorization: Bearer ol_live_…"

A client that takes a URL and headers can send Authorization: Bearer ol_live_… with every request. In Cursor’s mcp.json:

{
"mcpServers": {
"orderloop": {
"url": "https://orderloop.app/mcp",
"headers": { "Authorization": "Bearer ol_live_…" }
}
}
}

A client that runs OAuth itself finds the authorization server from /.well-known/oauth-protected-resource/mcp. It registers with dynamic client registration at /oauth/register or with a Client ID Metadata Document (an https client_id), sends the person to /oauth/authorize (authorization code with PKCE) and exchanges the code at /oauth/token.

A token carries the role it was created with and its expiry. /mcp accepts the same bearer credentials as the REST API: ol_live_ tokens, and the workspace password as a break-glass operator. These work on /a2a too. Wrong guesses are throttled (429 with Retry-After) and an expired token is refused (401 with the reason), as there.

A client sees only the rows its role can use. Write tools are the ones the assistant stops to confirm; over MCP the client decides how to ask, using the annotations below.

ToolRoleAccessDoes
needs_attentionviewer (Viewer)ReadWhat is waiting on people: open approvals (oldest first), orders that failed or rolled back in the last 3 days, and orders waiting on a business event for over a day.
find_ordersviewer (Viewer)ReadSearch orders. Totals compare in USD. Returns the count and total of all matches plus up to `limit` rows.
get_orderviewer (Viewer)ReadOne order: status, what it waits on (with where each decision leads), steps run so far and recent activity.
assess_orderviewer (Viewer)ReadAsk typed questions about one order and get a probability for every option: noul (yes/no, the probability of yes), choice (pick one of 2–255 options) or score (an ordered rubric of 2–10 levels, lowest first). Optionally pass up to 4 images (the order’s R2 document keys, https or data URLs; PNG, JPEG or WebP).
find_productsviewer (Viewer)ReadProducts with stock, reserved and available quantities and reorder points.
list_flowsviewer (Viewer)ReadAll flows and their published versions.
get_flowviewer (Viewer)ReadA flow’s saved draft: its steps, connections and validation problems.
propose_flow_changeoperator (Operator)ReadDraft a change to a flow from an instruction. Nothing is saved: a person reviews the proposal in the flow editor and applies it there.
decide_approvalapprover (Approver)WriteApprove or reject an approval an order is waiting on.
deliver_eventoperator (Operator)WriteDeliver a business event (e.g. payment.received) to the order waiting for it.
cancel_orderoperator (Operator)WriteCancel an order and undo what it did (release stock, void payment, cancel shipments).
publish_flowoperator (Operator)WritePublish a flow’s saved draft as a new version.
run_stock_reviewoperator (Operator)WriteRun the daily stock review now; it starts reorders for SKUs at or below their reorder point.

Each tool has a title, a description and a JSON input schema. Results come back as text and as structuredContent. A refusal from live data (nothing is waiting on that event, the approval is already decided, the order has finished) is returned as a tool error the model can read, not a protocol error. A tool the role can’t use is not listed, and calling it by name fails as unknown.

Annotations tell a client when to confirm:

Tools Hints
Reads and propose_flow_change readOnlyHint: true
decide_approval, cancel_order, publish_flow destructiveHint: true; the first two are also idempotentHint: true
deliver_event, run_stock_review writes, not destructive

All tools set openWorldHint: false.

A write made over MCP is attributed to the person who approved the connection, with the channel: <email> via MCP. That string is the approval’s by or ends the cancel reason, as <email> via assistant does for the panel (see Who decided). A client using an API token acts as token:<name>.

Account lists Connected apps (MCP clients and A2A agents alike): the app’s name, whether it connected over MCP or A2A, the address its access goes to, the role you granted and when it connected. Disconnect revokes the grant, and the app has to be connected again. Connecting and disconnecting are recorded in the audit log as oauth.app_connected and oauth.app_disconnected. Access tokens last one hour and refresh tokens 30 days.

  • One endpoint per token. /mcp and /a2a are separate OAuth resources of one authorization server. A client requests https://orderloop.app/mcp (a client that names no resource, and grants made before A2A existed, are for MCP), and the access token it gets is refused at /a2a; an A2A token is likewise refused here. Each endpoint publishes its own metadata at /.well-known/oauth-protected-resource/<path>.
  • Role cap. A grant is never higher than the role of the person who approved it, and the consent page offers no more. Pick the lowest role the client needs.
  • Checked on every request. OrderLoop re-reads the person each time. A disabled or deleted person’s grants stop working at once. The role is the lower of the one granted and the person’s current role, so demoting someone narrows the apps they connected. A person whose role must use two-factor sign-in and hasn’t set it up, or who is still on a temporary password, gets 403.
  • Credentials stay at the edge. OrderLoop resolves the caller before the request reaches the tools; Authorization and cookies go no further, and the model never sees a token.
  • Origin. A request whose Origin is not an http or https origin is refused with 403.
  • Rate limits. /oauth/register allows 10 requests a minute and /oauth/token 60, per address; over that it answers 429 { "error": "slow_down" } with Retry-After: 60.
  • Tokens at rest. Tokens are stored hashed and grant data encrypted.