Build an assistant client

MCP server

The Setherion MCP endpoint for building your own client: transport, authentication, tools and errors.

POSThttps://www.setherion.com/api/mcp

Plan: Every plan

Setherion has an MCP server, the standard way AI assistants use other services. If you only want to use it from Claude, ChatGPT, Cursor or VS Code, follow Connect an AI assistant. This page is for building your own client.

The server is the API in another voice. Each tool is a call to the endpoint of the same name in this reference, made with the caller's own credential, so the server can never do more than the API can.

Transport

  • Streamable HTTP, stateless. Send every message as one JSON-RPC 2.0 message in the body of a POST. There are no sessions and nothing to resume.
  • Protocol versions 2025-06-18 and 2025-03-26. initialize answers with the version you asked for if it is one of these, and 2025-06-18 otherwise. After initialize, send the version in the MCP-Protocol-Version header. A different value is refused with 400.
  • Tools only. The server offers no resources or prompts, and sends no messages of its own.
  • One message per request. A batch is refused with 400.
  • GET and DELETE answer 405 with Allow: POST.
  • Origin. A request from a browser page must come from https://www.setherion.com. Any other Origin answers 403. Requests from programs carry none and are allowed.

Keep the www in the address. The address without it redirects, and a redirect drops the credential.

Authentication

Send a credential in the Authorization header. Either works:

  • An API key: Authorization: Bearer sth_.... See Authentication.
  • An OAuth access token, which starts sto_, issued for this endpoint and no other. See the OAuth sign-in page of this reference.

A request with neither, or with a credential that is wrong, expired or revoked, answers 401 with a pointer to where to sign in:

http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="Setherion", resource_metadata="https://www.setherion.com/.well-known/oauth-protected-resource/api/mcp"
json
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32001,
    "message": "Sign in to Setherion to use this server, or send an API key from your account page as \"Authorization: Bearer sth_...\"."
  }
}

A client with no credentials follows resource_metadata to find the sign-in. The tokens work on this endpoint only: the REST endpoints of this reference take an API key.

Methods

MethodAnswer
initializeThe protocol version, capabilities of { "tools": { "listChanged": false } }, serverInfo (setherion, Setherion, 1.0.0) and instructions for the model.
ping{}
tools/listThe six tools below, with their input schemas.
tools/callRuns a tool.
Notifications and responses202 with the body {}.
Anything elseA JSON-RPC error -32601, Method not found: <method>.
bash
curl -X POST https://www.setherion.com/api/mcp \
  -H "Authorization: Bearer $SETHERION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'

Tools

ToolCallsArgumentsCredits
list_projectsList your appsquery, offset (both optional)None
edit_projectEdit an appproject_id, instruction (both required)Same as in the editor
edit_statusFollowing an editproject_id, run_id (both required)None
publish_projectPublish an appproject_idNone
store_guideApp store readinessproject_id, way (optional)None
store_privacy_answersStore privacy answersproject_id, way (required)None
write_store_listingWrite the store pageproject_idA few, Pro and up

instruction is sent as the prompt of the edit, up to 4,000 characters. way is easy or native. offset is a whole number, 0 or more, and may be sent as text. edit_project does not take a model: it runs on auto.

tools/list gives each tool's title, description, inputSchema and annotations. Reading tools are marked readOnlyHint: true, and publish_project is marked idempotent.

bash
curl -X POST https://www.setherion.com/api/mcp \
  -H "Authorization: Bearer $SETHERION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
        "params": { "name": "list_projects", "arguments": { "query": "coffee" } } }'

A tool's result

A tool answers with the JSON of its endpoint, in two forms for every kind of client:

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [{ "type": "text", "text": "{ \"ok\": true, \"total\": 1, ... }" }],
    "structuredContent": { "ok": true, "total": 1, "truncated": false, "offset": 0, "nextOffset": null, "projects": [] },
    "isError": false
  }
}

(projects is shortened here. It has the entries described on List your apps.)

When the endpoint refuses, isError is true, structuredContent is left out, and content holds the endpoint's error sentence alone, for the model to read. An edit that ends with ok: false is an error in this sense too.

Long edits

An edit takes minutes. Send the request with Accept: text/event-stream and the answer streams:

  • Every 10 seconds the server sends a notifications/progress event, with progress set to the seconds so far and the message Still editing, 30s so far, when you put a progressToken in params._meta. Without a token it sends a comment line, : still editing. Either one keeps the connection alive and lets a client reset its timeout.
  • The last event is the tool result, as event: message with the JSON-RPC response in data.
text
event: message
data: {"jsonrpc":"2.0","method":"notifications/progress","params":{"progressToken":"t1","progress":10,"message":"Still editing, 10s so far"}}

event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[...],"structuredContent":{"ok":true,"runId":"..."},"isError":false}}

Without that Accept header the request stays open and answers with one JSON object.

An edit still running after four minutes

edit_project waits about four minutes at most, because some assistants give up on a tool that has been quiet for five. An edit that is still working then answers ok: true with status: "running" and its runId:

json
{
  "ok": true,
  "status": "running",
  "runId": "b3f0e2d1-6a47-4c8e-9d15-0f2b7a3c8e61",
  "projectId": "7c1e4a52-9b0d-4f3e-8a61-2d5f0c9e7b14",
  "message": "Still editing. It carries on in Setherion without you: do not send it again. Call edit_status with this runId in a minute or so, until it says \"done\"."
}

The edit carries on in Setherion. Call edit_status with project_id and run_id every minute or so. It answers as in Following an edit, until status is done.

Closing the connection does not stop the edit

A client that closes the connection, or sends a cancel notification, leaves the edit running and paid for. It lands in the app as if you had waited. To stop it, press Stop in the Setherion editor, on the card that shows the edit running.

Errors

WhereError
HTTP 401JSON-RPC code -32001. See Authentication above.
HTTP 403{ "error": "Origin not allowed" }
HTTP 405Code -32000, Method not allowed. This server answers POST only.
HTTP 400Code -32700 Parse error for a body that is not JSON; -32600 for a batch, a message that is not JSON-RPC 2.0, or an unsupported MCP-Protocol-Version.
JSON-RPC error-32601 for a method that does not exist; -32602 for wrong tool arguments.
The sentences for wrong tool arguments

All come back with code -32602.

  • Unknown tool: <name>
  • Arguments must be an object.
  • Missing "project_id". (or any required argument)
  • Unknown argument "<name>".
  • "<name>" must be a string.
  • "way" must be one of: easy, native.
  • "offset" must be a whole number, 0 or more.

Refusals from the tools themselves, such as an app that is not found or a limit that was reached, are tool results with isError: true. Their sentences are the ones listed on Errors and limits.

Was this page helpful?

Join the community

Questions, ideas and what others are building.