MCP reference

OpenApps MCP reference.

The contract for https://mcp.openapps.network/connect, the one connection for every app: transports, protocol versions, sign-in, scopes, the six tools, and the shape of results and errors. For a walkthrough, read the agents guide first.

Last updated: 5 October 2026

Status

/connect is Building. It shares its host and its sign-in with OpenWallet's server, which is live at /mcp (moving to /openwallet) and documented in the OpenWallet tool reference. Rows below marked Live are true of that server today. Field names in the tool shapes may change before launch; this page will change with them.

Endpoint and protocol.

Value
Endpointhttps://mcp.openapps.network/connect Building. A trailing slash reaches the same server.
TransportStreamable HTTP, POST only. GET and DELETE answer 405. No session id.
Protocol versions2026-07-28 (stateless, server/discover) and 2025-11-25 (the initialize handshake), side by side. A sunset date for the older one will be published here.
Server nameopenapps, title OpenApps
Request sizeUp to 1 MiB; larger requests are refused. Files go through uploads.
Time per callNever more than 45 seconds. Long work is started, then polled.
Headers checkedMCP-Protocol-Version against the request's _meta; Mcp-Method and Mcp-Name against the body; Origin when present.
TracingA traceparent in _meta is carried into the run.

Addresses on this host.

One host, one address per connection. No address is a prefix of another, so a token issued for one is never accepted at another.

AddressWhat it isStatus
/connectEvery app, six tools (this page)Building
/openwalletOpenWallet's own toolsBuilding
/mcpOpenWallet's own tools, at their original address. Kept working after the move, because tokens already issued are bound to it.Live
/open…One app on its own, named after the app: /openpdfedit, /openslides, …Planned
/A page for people, saying which address to usePlanned

The host's other paths (/authorize, /token, /register, /revoke, the approval pages under /connect/…, /v1/…) are part of sign-in and runs, not MCP connections.

Discovery.

WhereWhatStatus
/.well-known/oauth-protected-resource/connectProtected-resource metadata (RFC 9728) for /connect: which authorization server and scopes. Each address has its own, ending in its path.Building
/.well-known/oauth-protected-resource/mcpThe same, for OpenWallet's server at /mcpLive
/.well-known/oauth-authorization-serverAuthorization-server metadata (RFC 8414)Live
/.well-known/mcp/server-card.jsonServer card: name, remotes, protocol versions, tools, docs. Server cards are still a draft proposal, so the fields follow our reading of it.Planned
MCP RegistryListed as network.openapps/openapps, verified by DNSPlanned
docs.openapps.network/llms.txtA plain-text map of these docs for agentsLive

Authorization.

OpenApps MCP is an OAuth 2.1 resource server, as the MCP authorization spec describes. The issuer is https://mcp.openapps.network, and the people behind each connection sign in with OpenWallet ID.

ValueStatus
GrantAuthorization code with PKCE (S256 only), plus rotating refresh tokensLive
Resource indicatorRFC 8707: ask for the resource you will call. Tokens are bound to it.Live
Issuer in the responseRFC 9207 iss on the redirectLive
Client registrationDynamic client registration at /registerLive
Client ID metadata documentsUse an https URL you control as your client id, with no registration. Registration stays for older clients.Planned
Access tokensShort-lived, sent as Authorization: Bearer. Usable only at the resource they were issued for.Live

Without a token you may call server/discover, tools/list, openapps_find and openapps_feedback, at a lower rate limit. Anything else without the right token answers 401, or 403 if a scope is missing, with a header saying what to ask for:

WWW-Authenticate: Bearer resource_metadata="https://mcp.openapps.network/.well-known/oauth-protected-resource/connect", scope="apps:run"

Scopes

ScopeAllowsStatus
wallet:readSee the agent wallet's status, balance and paymentsLive
wallet:payAsk OpenWallet to pay an x402 invoice within the person's limitsLive
apps:runPlan, start, watch and read receipts for operationsBuilding
credits:spendPay for runs with the person's OpenApps credits, within their delegationBuilding
feedback:writeFile feedback as the signed-in person; implied by any tokenPlanned

The six tools.

Descriptions are fixed: they never include a caller's limits, today's prices or the size of the catalogue. The list is sorted by name, marked cacheScope: "public", and cached for a day.

ToolRead-onlyDestructiveIdempotentOpen-worldNeeds
openapps_findyesnoyesnonothing
openapps_planyesnononoapps:run
openapps_startnoyesnonoapps:run and a spend scope
openapps_statusyesnoyesnoapps:run
openapps_receiptyesnoyesnoapps:run
openapps_feedbacknononononothing

openapps_start is marked destructive because a charge cannot be undone by the caller. A failed run is refunded by the system.

openapps_find

Search the catalogue, or fetch one operation's full contract.

{ "query": "split this PDF into invoices and pull the totals",
  "filters": { "app": ["openextract"], "max_price_usd": 0.5,
               "effects": ["reads", "writes"], "runs_on": "remote" },
  "limit": 5,          // 1–10
  "cursor": "…" }

// or, for one operation's full contract:
{ "detail": "doc.extract_to_schema" }

Returns compact cards (id, app, title, summary, price.typical_usd, price.p95_usd, grade, effects, runs_on), total_matches and next_cursor. Signed in, it also returns the account's credits and remaining limits. When nothing matches, no_match suggests near misses. Queries can be in any of our eight languages.

openapps_plan

Turn a job and its inputs into a priced plan.

{ "intent": "one PDF per invoice, with the totals",
  "files": [ { "file_id": "f_…" } ],     // or { "url": "https://…" }
  "policy": "balanced" }                 // best | balanced | cheapest

Returns plan_id, the quote, its classification, and needs_upload: a list of { name, accept, max_bytes, upload_url } for inputs still missing. A file path is refused.

openapps_start

{ "plan_id": "pl_…",
  "authorization": { "kind": "credits" },              // OpenApps credits
              // or { "kind": "openwallet", "max_usd": 0.5 }   device-approved
  "idempotency_key": "…",                              // required
  "events": true }                                     // optional AG-UI stream

Returns at once: run_id, state (queued, awaiting_approval or running), approval (url, expires_at) when the person must approve, events_url, and poll_after_ms. The same idempotency key for the same plan returns the same run.

openapps_status

{ "run_id": "run_…", "wait_ms": 30000 }. Holds for up to 45 seconds and returns as soon as the run changes: its state, step progress, what has been charged, and finished results as resource_links valid for one hour.

openapps_receipt

{ "run_id": "run_…" }. The Ed25519-signed receipt and how to verify it offline. The public keys are at https://mcp.openapps.network/v1/keys.

openapps_feedback

A report (kind, about, summary, details, expected, actual, error_code, contact_ok) returns ticket_id and status_url. { "ticket_id": "fb_…" } returns its state: received, triaged, planned, fixed_in a version, or wont_fix with a reason. The same report is accepted without MCP at POST https://mcp.openapps.network/v1/feedback. Limits: 20 reports an hour per token, 5 when anonymous.

Results and errors.

HTTP statusMeaning
401No token, or not one for this resource. Read WWW-Authenticate.
403The token is valid but lacks a scope.
405GET or DELETE on /mcp.
429Rate limited. Wait, then retry with the same idempotency key.

MCP servers inside the apps.

Building Some apps also ship their own MCP server that runs on your machine over stdio, for people who run the app locally: OpenPdfEdit, OpenRedact, OpenExtract, OpenOCR, OpenSlides, OpenPhotoEdit and others. Each will document its own install line when it ships. They all follow the same rules, so an agent that has used one knows them all: