Build an assistant client
MCP server
The Setherion MCP endpoint for building your own client: transport, authentication, tools and errors.
https://www.setherion.com/api/mcpPlan: 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-18and2025-03-26.initializeanswers with the version you asked for if it is one of these, and2025-06-18otherwise. Afterinitialize, send the version in theMCP-Protocol-Versionheader. A different value is refused with400. - 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. GETandDELETEanswer405withAllow: POST.- Origin. A request from a browser page must come from
https://www.setherion.com. Any otherOriginanswers403. 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/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="Setherion", resource_metadata="https://www.setherion.com/.well-known/oauth-protected-resource/api/mcp"{
"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
| Method | Answer |
|---|---|
initialize | The protocol version, capabilities of { "tools": { "listChanged": false } }, serverInfo (setherion, Setherion, 1.0.0) and instructions for the model. |
ping | {} |
tools/list | The six tools below, with their input schemas. |
tools/call | Runs a tool. |
| Notifications and responses | 202 with the body {}. |
| Anything else | A JSON-RPC error -32601, Method not found: <method>. |
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
| Tool | Calls | Arguments | Credits |
|---|---|---|---|
list_projects | List your apps | query, offset (both optional) | None |
edit_project | Edit an app | project_id, instruction (both required) | Same as in the editor |
edit_status | Following an edit | project_id, run_id (both required) | None |
publish_project | Publish an app | project_id | None |
store_guide | App store readiness | project_id, way (optional) | None |
store_privacy_answers | Store privacy answers | project_id, way (required) | None |
write_store_listing | Write the store page | project_id | A 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.
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:
{
"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/progressevent, withprogressset to the seconds so far and the messageStill editing, 30s so far, when you put aprogressTokeninparams._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: messagewith the JSON-RPC response indata.
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:
{
"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
| Where | Error |
|---|---|
HTTP 401 | JSON-RPC code -32001. See Authentication above. |
HTTP 403 | { "error": "Origin not allowed" } |
HTTP 405 | Code -32000, Method not allowed. This server answers POST only. |
HTTP 400 | Code -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?
