The MCP server
CoRelayer exposes its API as a Model Context Protocol server, so an MCP client can discover pricing, buy a plan and relay a transaction as tool calls rather than as HTTP requests it has to construct.
The MCP server is part of the same binary as the API and ships with it. Every tool call runs the REST route it wraps inside the server, with your credentials and your client address, so a tool answers exactly as its route does.
Endpoints and editions
| Full | https://mcp.co-relayer.com/mcp |
| Read-only | https://mcp.co-relayer.com/readonly |
| Transport | Streamable HTTP, stateless, JSON-RPC 2.0 |
| Protocol revision | 2025-06-18 |
The read-only edition exposes only the tools that cannot change anything: pricing, network, status, relayers, quota, account, quotes, validation, transaction status, usage history, notices and the documentation search. Point untrusted or exploratory clients at it.
What it is, precisely
Every tool is a typed wrapper around one API route (two, where one answer is more useful than two round trips). The MCP server holds no key, adds no capability the REST API lacks, and applies the same authentication rings, the same rate limits and the same errors. A tool error is the problem document, as structured content.
This matters because the alternative — an MCP server that is its own service with its own credentials — would be a second path to the signer with its own security properties. There is one validation pipeline and one signer boundary, and MCP is an adapter in front of them.
The tools
Every tool runs in the full edition. The third column says which ones the read-only edition offers as well.
| Tool | Route | Read-only edition |
|---|---|---|
get_pricing | GET /v1/pricing | yes |
get_network_status | GET /v1/network + GET /v1/status | yes |
list_relayers | GET /v1/relayers | yes |
get_quota | GET /v1/account/{erd}/quota | yes |
get_relayer_for_sender | POST /v1/relay/assign | yes |
get_account | GET /v1/account/{erd} + /purchases | yes |
quote_relay | POST /v1/quote | yes |
validate_transaction | POST /v1/validate | yes |
prepare_subscribe | POST /v1/subscribe/prepare | no |
prepare_deposit | POST /v1/deposit/prepare | no |
prepare_set_flags | POST /v1/flags/prepare | no |
prepare_senders | POST /v1/senders/prepare | no |
relay_transaction | POST /v1/relay, then GET /v1/relay/{id} until the state you ask for | no |
relay_batch | several POST /v1/relay on one lease | no |
get_tx_status | GET /v1/relay/{id} | yes |
get_usage_history | GET /v1/usage | yes |
get_notices | GET /v1/account/{erd}/notices | yes |
buy_plan_x402 | POST /v1/x402/purchase (x402) | no |
topup_x402 | POST /v1/x402/topup | no |
search_docs | the operations of the OpenAPI document | yes |
Arguments, results and examples: Tools.
Resources and prompts
| Resource | Content |
|---|---|
corelayer://pricing | The live pricing document. |
corelayer://openapi | The OpenAPI document. |
corelayer://status | Service status. |
corelayer://docs/quickstart-agent | The agent quickstart. |
| Prompt | For |
|---|---|
go_gasless | Walking an account from nothing to a first relayed transaction. |
buy_plan | Choosing and buying a tier. |
tools/list is deterministic and cacheable for five minutes. As built, resources/list and
prompts/list return the entries above, but reading them — resources/read, prompts/get — is not
implemented yet and answers "unknown method". The same content is available over HTTP: the pricing
document at GET /v1/pricing, the OpenAPI document at /openapi.yaml,
status at GET /v1/status, and the quickstart on this site.
Client configuration
The server speaks Streamable HTTP, so any MCP client that supports a remote HTTP server can use it. Two examples of the usual shape:
{
"mcpServers": {
"corelayer": {
"type": "http",
"url": "https://mcp.co-relayer.com/mcp"
}
}
}
{
"mcpServers": {
"corelayer-readonly": {
"type": "http",
"url": "https://mcp.co-relayer.com/readonly"
}
}
}
The exact file and key names differ per client — consult your client's own documentation for where its server list lives. We will not reproduce a configuration path here that we have not verified against the client in question.
What the server cannot do
- It cannot sign. No private key ever reaches it. Every tool that needs a signature returns something for you to sign: a presence-proof message, an unsigned transaction, an x402 challenge.
- It cannot create entitlement.
prepare_*builds transactions; the chain decides. - It cannot bypass a limit. Same rate classes, same quotas, same errors as the REST API.
- There is no
subscribetool. Subscribing requires a signature, and an MCP server that cannot sign cannot offer one honestly.prepare_subscribeis the truthful shape.
Handling signed transactions safely
relay_transaction or relay_batchThese two tools take a user-signed transaction in their arguments. MCP hosts and model transcripts routinely log tool arguments, and a signed relayed transaction sitting in a transcript is a payload somebody else can hold.
Three mitigations, and one honest residual:
- the result and every error of these two tools never echo the signed transaction, the signature, the guardian signature or the lease — only sender, nonce, transaction hash, state and the problem fields;
- both tools set an idempotency key automatically, one per call;
- hosts are asked, in the tool descriptions themselves, not to log these arguments.
The residual — a logged payload that we never co-signed — is inert, because a relayed transaction without a relayer signature cannot execute. It is bounded further by the presence proof and by first-seen expiry. It is not zero.
The scrubbing is built and tested: every result and every error of these two tools passes through
a filter that drops signature, guardianSignature, relayerSignature, lease, transaction,
tx and secret members before anything is returned.
relay_batch, and why there is no REST equivalent
relay_batch sends several transactions from one sender, on strictly consecutive nonces, over one
lease, stopping at the first error. It exists because an MCP round trip per transaction is
expensive.
There is deliberately no REST batch route. One request, one intent keeps every error attributable to exactly one transaction. A batch of different nonces is not a set of variants of one action, so this does not conflict with the one-signature rule — each transaction in the batch was signed once, for itself. (One signature)