Any MCP client
The Streamable HTTP contract, a curl that lists the eight tools, and the mcp-remote bridge for stdio-only clients.
Wellworn is one endpoint that speaks MCP over Streamable HTTP:
https://mcp.wellworn.dev/mcpAny client that can POST JSON-RPC to a URL can use it. The server is stateless: it issues no session id, holds nothing between calls, and answers each POST on its own. That means no initialize handshake is required before a tool call, no Mcp-Session-Id header to echo back, and no long-lived connection to keep open. A retry is just another POST.
Two headers
Send both:
content-type: application/json
accept: application/json, text/event-streamThe accept header must name both types. The server answers a single-type accept with 406 Not Acceptable and this body, which is the fastest way to identify the mistake:
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "Not Acceptable: Client must accept both application/json and text/event-stream"
},
"id": null
}Listing the tools with curl
curl -sN https://mcp.wellworn.dev/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'The reply comes back as one Server-Sent Events frame, so the JSON body sits after data: on the second line:
event: message
data: {"result":{"tools":[{"name":"recommend", ...The eight tool names in that payload are recommend, compare, alternatives, traps, skill, design, docs and submit_trap. Each carries a JSON Schema for its arguments; the tools reference documents them in prose.
Calling one takes the same shape:
curl -sN https://mcp.wellworn.dev/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"traps","arguments":{"library":"better-auth","version":"1.7.3"}}}'Sending a key
One header, on every request:
authorization: Bearer ww_your_keyWithout it the call runs on the anonymous tier, 60 calls a day per IP. Read tools work there; submit_trap does not. See keys for where the key comes from and limits for what each tier allows.
Clients that only speak stdio
A client that launches MCP servers as local programs, with command and args, reaches a remote endpoint through mcp-remote, which runs as that local program and forwards to the URL.
{
"mcpServers": {
"wellworn": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.wellworn.dev/mcp"]
}
}
}With a key, put the whole header value in an environment variable. mcp-remote documents a spacing bug on Cursor and on Claude Desktop for Windows, and the workaround is to write --header with no space after the colon:
{
"mcpServers": {
"wellworn": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.wellworn.dev/mcp",
"--header",
"Authorization:${WELLWORN_AUTH}"
],
"env": {
"WELLWORN_AUTH": "Bearer ww_your_key"
}
}
}
}mcp-remote negotiates HTTP first and falls back to SSE. --transport http-only skips the fallback, which is what you want here: this server has no SSE endpoint, so a fallback attempt only costs a round trip.
Verified 2026-09-08 against github.com
If your client is not listed
The pages in this section were each checked against the client's own documentation on the date at the bottom of the page. A client that takes a URL, sends both accept types, and can attach an Authorization header needs nothing else. If you get one working that has no page here, the contributing guide covers how to send it in.