Skip to content

Connecting to MCP

Status: GA Access: token required API contract: 0.3.0 · capability 2026-09-03.1 View as Markdown Open in Claude Open in ChatGPT

The platform exposes an MCP server over Streamable HTTP (JSON-RPC). This page is written for agents of any capability: follow the steps literally, in order. Every command is complete — nothing is assumed from outside this page.

FactValue
Endpointhttps://entherium.duckdns.org:8443/mcp/
TransportMCP Streamable HTTP (JSON-RPC over POST; responses are SSE)
AuthAuthorization: Bearer <AGENT_TOKEN> on every request
Discovery without authGET /mcp-info (onboarding page), GET /llms.txt
What you get14 tools + 5 resources (full reference)
Read-only mounthttps://entherium.duckdns.org:8443/mcp/readonly/ — same token, only the 7 read tools (why)
Docs MCP, no tokenhttps://entherium.duckdns.org:8443/mcp/docs/ — this documentation as search / fetch / submit_feedback (details)
  • You have an agent token (<AGENT_TOKEN> below). Without one, every call returns 401 — request a token from the platform owner first.
  • Your HTTP client can send POST with custom headers and read the response body as text. Responses arrive as Server-Sent Events: take the lines that start with data: and parse the rest of each line as JSON.
Terminal window
curl -sS -D headers.txt https://entherium.duckdns.org:8443/mcp/ \
-H "Authorization: Bearer <AGENT_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'

Expected: an SSE body whose data: line contains "serverInfo", and a response header mcp-session-id in headers.txt. Copy that value — it is <SESSION_ID> in the next steps. If you got 401, your token is missing or expired — see the table below. Do not proceed until this step returns 200.

Terminal window
curl -sS https://entherium.duckdns.org:8443/mcp/ \
-H "Authorization: Bearer <AGENT_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: <SESSION_ID>" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'

Expected: HTTP 2xx with an empty or trivial body. This step is required — skipping it makes some clients’ later calls fail.

Always call start_here first: it returns the ordered plan for using the platform and the capability version of the read surface.

Terminal window
curl -sS https://entherium.duckdns.org:8443/mcp/ \
-H "Authorization: Bearer <AGENT_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: <SESSION_ID>" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"start_here","arguments":{}}}'

Expected: a data: line whose JSON contains the plan. From here, use the tools reference — every tool page shows the exact tools/call payload for that tool.

The three curl steps above are what every client does under the hood. With a client you only give it the URL and the header:

Claude Code

Terminal window
claude mcp add --transport http enterium https://entherium.duckdns.org:8443/mcp/readonly/ \
--header "Authorization: Bearer <AGENT_TOKEN>"

Cursor / VS Code / any mcp.json-style client

{
"mcpServers": {
"enterium": {
"url": "https://entherium.duckdns.org:8443/mcp/readonly/",
"headers": { "Authorization": "Bearer <AGENT_TOKEN>" }
}
}
}

Replace readonly/ with /mcp/ only when you actually need the write tools. For the token-less docs server the install links work as-is: Add to Cursor · Add to VS Code · Claude Code: claude mcp add --transport http enterium-docs https://entherium.duckdns.org:8443/mcp/docs/.

/mcp/readonly/ serves the same server with the write tools removed: only tools whose readOnlyHint is true are listed, and calling a write tool by name fails. Same bearer token, same handshake, same start_here. Use it as the default for evaluation, for research assistants and for any client that must never file a ticket or move a task by accident — the choice is made by the URL, not by trusting the client to respect hints. The full server stays at /mcp/.

/mcp/docs/ turns this documentation into three tools and needs no token:

ToolWhat it does
search(query, limit)Ranks portal pages for a query; returns {results: [{id, title, url}]} — id is the page route
fetch(id)Returns a page as Markdown ({id, title, text, url, metadata}) — the .md twin, fewer tokens than HTML
submit_feedback(page, message)Files a suggestion for the documentation team; anonymous, at most 5 per hour per client; asks the user first

The tool names and shapes follow the deep-research connector contract, so the server can be added to ChatGPT or Claude as a connector unchanged. It never reads or writes platform data — everything comes from the published portal — which is why it sits outside the token gate.

SymptomCauseAction
401 on a plain browser GET /mcp/Auth is checked at the mount, before content negotiation — without a token you never reach the transportExpected. There is nothing to see in a browser; the human page is GET /mcp-info
406 Not Acceptable on GET /mcp/ with a tokenThis is not a browser URL; the server requires the JSON-RPC handshakeUse the three steps above, or an MCP client library
401 on every callToken missing, malformed or expired (auth is checked at the mount, before any tool runs)Tokens are issued by the platform owner (POST /api/v1/auth/agent-token is superuser-only) — ask for a re-issue. ⚠️ A new token replaces your grant set — re-check my_capabilities after
403 or a capability error inside a tool resultToken is valid but lacks the capability or the per-contract grant for that toolCall my_capabilities to see what you may do; request the missing grant from the owner
Tools list suddenly empty after a platform deployThe deploy restarted the API container and killed your live MCP session; sessions are not restoredRe-run the handshake from Step 1 (new mcp-session-id)
Response body looks unparseableYou are reading raw SSEParse only lines starting with data: ; join multi-line events before JSON-parsing
307 on /mcp (no trailing slash)The transport lives at /mcp/; the server redirectsUse /mcp/ directly — some clients do not follow redirects on POST
  1. Read payload values, not schemas. Explanatory context lives in the JSON responses themselves (for example, status notes inside the data) — the platform puts meaning in the payload because many agents never introspect tool descriptions.
  2. Re-check start_here after upgrades. Pass your cached capability_version as last_seen_version; if the surface changed, the response lists what to adopt before you act.