MCP server

One hosted, stateless Streamable HTTP endpoint for every host, with OAuth 2.1, plus a small npx wrapper for hosts that only run local servers.

Endpoint: https://mcp.50heads.com/mcp

Hosted: add the endpoint and sign in with OAuth in the browser. Nothing to install, and you set the connection's daily spend cap when you sign in. Local: npx -y @50heads/mcp runs the same tools over stdio for hosts that launch a command. It needs Node 20 or later and an API key from Developers in the portal, or a one-time npx -y @50heads/mcp login.

Claude (claude.ai and Claude Desktop)

Hosted, sign in with OAuth. Settings, Connectors, Add custom connector. Paste the URL and sign in when asked. On Team and Enterprise plans an owner adds it for the organisation first.

https://mcp.50heads.com/mcp

Or with an API key, in claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\).

{
  "mcpServers": {
    "50heads": {
      "command": "npx",
      "args": [
        "-y",
        "@50heads/mcp"
      ],
      "env": {
        "FIFTYHEADS_API_KEY": "fh_live_…"
      }
    }
  }
}

Claude Code

Hosted, sign in with OAuth. Run in a terminal, then /mcp in Claude Code to sign in.

claude mcp add --transport http 50heads https://mcp.50heads.com/mcp

Or with an API key (CI and scripts):

claude mcp add --transport http 50heads https://mcp.50heads.com/mcp --header "Authorization: Bearer fh_live_…"

Cursor

Hosted, sign in with OAuth. ~/.cursor/mcp.json (or .cursor/mcp.json in a project). Cursor opens the sign-in page.

{
  "mcpServers": {
    "50heads": {
      "url": "https://mcp.50heads.com/mcp"
    }
  }
}

Or with an API key:

{
  "mcpServers": {
    "50heads": {
      "url": "https://mcp.50heads.com/mcp",
      "headers": {
        "Authorization": "Bearer fh_live_…"
      }
    }
  }
}

ChatGPT

Hosted, sign in with OAuth. Settings, Apps and Connectors, Advanced settings, turn on Developer mode, then Create. Paste the URL and choose OAuth. On Business and Enterprise plans an admin turns on Developer mode first.

https://mcp.50heads.com/mcp

VS Code

Hosted, sign in with OAuth. .vscode/mcp.json in the workspace, or MCP: Add Server from the command palette.

{
  "servers": {
    "50heads": {
      "type": "http",
      "url": "https://mcp.50heads.com/mcp"
    }
  }
}

Or from a terminal:

code --add-mcp '{"name":"50heads","type":"http","url":"https://mcp.50heads.com/mcp"}'

Windsurf

Local, with an API key. ~/.codeium/windsurf/mcp_config.json, or Windsurf Settings, Cascade, MCP servers, View raw config.

{
  "mcpServers": {
    "50heads": {
      "command": "npx",
      "args": [
        "-y",
        "@50heads/mcp"
      ],
      "env": {
        "FIFTYHEADS_API_KEY": "fh_live_…"
      }
    }
  }
}

Or the hosted server with an API key:

{
  "mcpServers": {
    "50heads": {
      "serverUrl": "https://mcp.50heads.com/mcp",
      "headers": {
        "Authorization": "Bearer fh_live_…"
      }
    }
  }
}

Any other host

Local, with an API key. Hosts that launch a local command. Needs Node 20 or later and an API key from the dashboard.

FIFTYHEADS_API_KEY=fh_live_… npx -y @50heads/mcp

Hosts that speak Streamable HTTP: https://mcp.50heads.com/mcp with the header "Authorization: Bearer fh_live_…", or OAuth.

{
  "mcpServers": {
    "50heads": {
      "url": "https://mcp.50heads.com/mcp",
      "headers": {
        "Authorization": "Bearer fh_live_…"
      }
    }
  }
}

npx -y @50heads/mcp config [host] prints any of these. To check it works, ask your host to use 50heads to estimate a question: estimate is free and never spends credits.

MCP Registry

50heads is in the official MCP Registry as com.50heads/mcp, with the hosted server and the npm package. Hosts and directories that read the registry can add it from there. Releases use calendar versions (2026.924.1 is the first release on 24 September 2026); the hosted server, the npm package and the registry entry carry the same one.

OAuth

The server is an OAuth 2.1 resource server. Hosts discover everything from https://mcp.50heads.com/.well-known/oauth-protected-resource, which points at the authorization server https://auth.50heads.com. PKCE (S256) and the resource parameter are required; dynamic client registration and client ID metadata documents are both supported. Access tokens last an hour; refresh tokens rotate and last 30 days.

At consent the person picks scopes and a daily spend cap for the connection (£50.00 unless they change it). They can change or revoke it any time under Developers in the portal; a revoked connection stops within a second.

Scopes

questions:read, questions:write, templates:read, account:read. A call that needs a scope the token lacks returns insufficient_scope so the host can ask for it.

Tools

ToolScopeDoes
estimatequestions:writePrice, time and validation. Never spends. Call it first.
askquestions:writePosts a question; returns a task (or a question id on older hosts). Needs idempotency_key.
get_resultsquestions:readThe results object, partial while live.
wait_for_resultsquestions:readOlder hosts: waits on our side up to 600 seconds, with min_answers.
list_questionsquestions:readRecent questions by status and date, to reuse before re-asking.
cancelquestions:writeStops a live question; returns refund_credits.
templatesnoneFixed-price templates. Cacheable.
balanceaccount:readCredits, reserved and cap_remaining.
upload_imagequestions:writeAn image from base64 or an https link into 50heads; returns image_url for a question.
get_answersquestions:readIndividual answers, a page at a time, filtered by option, tier, country, age band or keyword.
add_headsquestions:writeMore heads on the same question, merged into its result. Needs idempotency_key.
flag_answerquestions:writeReports one answer by its attestation_ref for review; upheld flags are refunded.
exportquestions:readThe results as a file: CSV, and a PDF report or PNG card where served.
build_ask_linknoneA portal link with the question filled in (the parameters below). Spends nothing.
list_targetingnoneCountries, languages, pool bands and the tags you can target.
search_helpnoneSearches the help centre; returns articles with links.
send_feedbacknoneSends feedback or a problem to support as a ticket.

https://50heads.com/app/ask?… opens the composer with a question filled in, for a person to check the price and time and ask. build_ask_link writes these; you can write them by hand too. Nothing is asked until the person presses Ask. The composer fills itself only when the link has text or at least one optionLabel.

ParameterMeaning
typesingle_choice, multi_choice, ab_image, pairwise, scale_1_5, ranking, yes_mostly_no or free_text.
textThe question.
contextOne line of background.
languageSuch as en or pt-BR. Default en.
optionLabelAn option; repeat for each, in order.
optionImageAn https image for the option in the same position; repeat, empty for none.
stimulusImage, stimulusTextShown above the question.
neither=onAdds a Neither option.
nHeads, 10 to 5,000.
tier1, 2 or 3.
rush=onAim for under an hour.
countryISO code; repeat for each.
tagA tag id; repeat. Kept at Tier 2 and 3 only.
templateOpens a template instead (other fields are ignored).
followUpOpens a follow-up to that question id; type and text apply.
reaskRe-asks the unanswered part of that question id.
mode=bulkOpens the bulk composer.

Errors

JSON-RPC errors carry error.data.code: validation and not_found as −32602; insufficient_credits, spend_cap_exceeded, idempotency_conflict and content_refused as −32001; rate_limited and unavailable as −32000. Every message is one sentence a model can act on.

Limits

1 MB request bodies. Images by URL or upload only, never large inline base64. 60 requests a minute per connection and 10 asks a minute.