Overview
Relay makes an app without a server an MCP server that ChatGPT, Claude and other hosts can call.
Relay gives an app that has no backend an MCP server it does not have to run. The app opens one outbound WebSocket and registers its tools. Each person who uses the app gets a personal MCP URL to paste into ChatGPT, Claude or any MCP client. When the model calls a tool, Relay forwards the call down the socket to the running app and returns the app's answer to the host.
You write no MCP server, host no OAuth and deploy nothing. The protocol is a handful of JSON frames; a working client is about 30 lines.
Who it is for#
- Desktop apps, native or built with Tauri or Electron, whose data lives on the person's machine.
- Local-first web apps that keep their data in the browser.
- Command-line tools and agents that run on a laptop or a home server.
- Any app that would otherwise need a public server, a domain and an OAuth flow just to be reachable from ChatGPT or Claude.
How it works#
- Create a project in the dashboard. You get a publishable key that can create links and nothing else, so it is safe to ship inside the app.
- For each person and device, the app calls `POST /v1/links` once and keeps the link token and the person's MCP URL it gets back.
- The app opens a WebSocket and sends a `hello` frame with the link token and its tools. Relay answers
ready. - The person pastes that URL into ChatGPT, Claude or another client.
- Each tool call reaches the app as a
callframe. The app runs it and sends aresult, which Relay returns to the host over MCP.
Key ideas#
| Term | Meaning |
|---|---|
| Project | Owns the publishable key, the links, the settings and the usage. The free allowance and the spend cap are per project. |
| Publishable key | pk_…. Public by design: it can only create links. Ship it in the app. |
| Link | One person's installation on one device. It holds two secrets: the link token and the URL token. |
| Link token | lt_…. The app's credential for one link, sent in hello. Keep it in the platform's secure storage. |
| MCP URL | Ends in the URL token ut_…. The person's credential for the host. Anyone holding it can call the app's tools while the app runs. |
| Tool | A function the app registers in hello: a name, a description and a JSON Schema for its arguments. |
| Call | One tools/call from a host that Relay forwards to the app. Calls are what Relay bills. |
What Relay does and never does#
- Answers
initializeandtools/listfrom the tool list the app registered last, so a host can be set up while the app is closed. - Checks every call against the tool's input schema before the app sees it, and refuses tools the app did not register.
- Passes tool annotations such as
readOnlyHintthrough unchanged, and never renames or prefixes a tool. - Never stores arguments or results. It keeps call metadata (tool, outcome, sizes, duration) for 30 days.
- Never fetches a URL named in a payload and never runs your code. The app does the work.
Before you build on it#
WarningThe app must be running for a call to succeed. A call to a closed app answers at once with a tool error that tells the person to open the app, and it costs nothing.
NoteArguments and results pass through Relay in clear text, encrypted by TLS on both legs, the same way they reach the host itself. Expose only what the person would share with ChatGPT or Claude. See Security and privacy.
Endpoints#
All requests use HTTPS or secure WebSockets.
| Purpose | URL |
|---|---|
| Create a link | POST https://api.meslzy.com/relay/v1/links |
| App socket | wss://api.meslzy.com/relay/v1/socket |
| MCP endpoint, one per link | POST https://api.meslzy.com/relay/v1/mcp/{urlToken} |
Where to go next#
- Quickstart: a real ChatGPT or Claude call in about two minutes, then the same from your app.
- WebSocket protocol: every frame, close code and limit your app deals with.
- MCP endpoint: what hosts see at the person's URL.
- Usage and billing: what counts as a call and what never does.