{"server":"electionsmcp","transport":"Streamable HTTP — POST JSON-RPC to this URL; responses are JSON (no SSE).","endpoint":"https://www.electionsmcp.com/mcp","protocol_versions":["2026-07-28","2025-06-18","2024-11-05"],"protocol":{"modern":{"versions":["2026-07-28"],"how":"No handshake. Every POST carries its own protocol version and capabilities in `params._meta`, and the server holds no session between requests. Required on EVERY request: `_meta[\"io.modelcontextprotocol/protocolVersion\"]` and `_meta[\"io.modelcontextprotocol/clientCapabilities\"]` (an empty object is valid); `_meta[\"io.modelcontextprotocol/clientInfo\"]` is recommended. Mirror the version into the `MCP-Protocol-Version` header and the method into `Mcp-Method` (plus `Mcp-Name` for tools/call) — the server validates header against body and answers -32020 on a mismatch. Results carry `resultType` and `_meta[\"io.modelcontextprotocol/serverInfo\"]`.","discover":"POST server/discover for supportedVersions + capabilities in one call. Optional — you may invoke any method inline and handle -32022 (UnsupportedProtocolVersion) if the version is not served."},"legacy":{"versions":["2025-06-18","2024-11-05"],"how":"The handshake era: POST initialize first, then tools/list → tools/call. Still fully supported and unchanged — send no `_meta` protocol fields and the server serves you exactly as before. Requests whose `MCP-Protocol-Version` header names one of these versions, and requests with no header at all, are served this way."}},"auth":"Send your key as `Authorization: Bearer <key>` OR `x-electionsmcp-key: <key>` for the authenticated Workbench. Without a valid key this endpoint can still answer in the Core sandbox: a successful HTTP response does not prove authentication. Call connection_status to verify logged_in and the intended workspace; billing_status reports current save entitlement.","product":"Build user-controlled election scenarios at the finest supported local grain, compare candidates, and coordinate campaign work through MCP.","baseline":{"baseline_id":"2024_president_mixed_grain","year":2024,"office":"president","grain":"mixed","provenance_version":"2024-president-mixed-grain-v1","description":"The canonical mixed-grain 2024 presidential baseline uses verified precinct or reporting-unit results where supported, with declared county/state fallbacks elsewhere.","disclosure":"Results are approximate. Precinct and county totals may vary because of source coverage, reporting, and geographic differences."},"tool_profiles":"tools/list is an authority boundary: keyless sessions get the CORE modeling loop; authenticated sessions get WORKBENCH (modeling + campaign operations, people, tasks, Discussions, approved files/outputs). An explicit Core OAuth grant or `x-electionsmcp-tools: core` stays Core; authentication does not widen it. Legacy `full` resolves to the caller's normal profile.","connect":{"streamable_http_clients":"Use Streamable HTTP at this URL. Modern clients use server/discover or per-request metadata; legacy clients use initialize. Both then use tools/list and tools/call. The client handles protocol headers; no custom HTTP caller is needed.","claude_code":{"command":"claude mcp add --scope user --transport http electionsmcp https://www.electionsmcp.com/mcp --header \"Authorization: Bearer $ELECTIONSMCP_API_KEY\"","next":"Set the environment variable privately first. Open a new Claude Code session, check /mcp, then run the first-use checks below. A project-local entry can override a user-scope entry."},"codex":{"command":"codex mcp add electionsmcp --url https://www.electionsmcp.com/mcp --bearer-token-env-var ELECTIONSMCP_API_KEY","config_toml":"[mcp_servers.electionsmcp]\nurl = \"https://www.electionsmcp.com/mcp\"\nbearer_token_env_var = \"ELECTIONSMCP_API_KEY\"","next":"Set the environment variable in the environment that launches Codex. Restart the connector/session and check /mcp, then run the first-use checks below."},"cursor":{"config_json":"{\n  \"mcpServers\": {\n    \"electionsmcp\": {\n      \"url\": \"https://www.electionsmcp.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer $ELECTIONSMCP_API_KEY\"\n      }\n    }\n  }\n}","next":"Cursor → Settings → MCP → Add new server, or paste into ~/.cursor/mcp.json."},"personal_connector_url":"https://www.electionsmcp.com/mcp/k/YOUR_KEY — the same key carried in the path, for clients that cannot send a header (claude.ai custom connectors, ChatGPT connectors). Treat the URL as the secret it is; rotate it from your account page.","url_plus_headers_config":{"mcpServers":{"electionsmcp":{"url":"https://www.electionsmcp.com/mcp","headers":{"x-electionsmcp-key":"YOUR_KEY"}}}},"stdio_clients_eg_claude_desktop":{"mcpServers":{"electionsmcp":{"command":"npx","args":["-y","mcp-remote","https://www.electionsmcp.com/mcp","--header","x-electionsmcp-key:YOUR_KEY"]}}},"legacy_sse_clients":"If your client uses the older HTTP+SSE transport: connect to https://www.electionsmcp.com/sse (it advertises the POST /messages endpoint).","quick_test_curl":"curl -sX POST https://www.electionsmcp.com/mcp -H 'content-type: application/json' -H 'x-electionsmcp-key: YOUR_KEY' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'"},"first_use":{"configuration_is_not_connection":true,"campaign_onboarding":{"tool":"get_campaign_onboarding","arguments":{"section":"connection"},"prompt":"onboard-campaign","guide_version":"2026-09-10-774f392781b7","instruction":"When the user wants to set up or join a campaign, call get_campaign_onboarding first and lead the setup in this AI conversation. Resume existing work before creating anything. Connecting alone never authorizes setup writes."},"tool_guidance":"For any unfamiliar tool, call get_catalog with its exact tool name. The returned tool.guidance contains the same complete AI instructions as its use-<tool> MCP prompt; prompt support is optional.","checks":["connection_status","billing_status","help"],"verify":"Confirm logged_in and the intended workspace from connection_status, then can_save and entitlements from billing_status. A saved connector URL, HTTP 200, or a nonempty Core catalog alone is not authenticated readiness. Do not print or share keys.","prompt":"Check my ElectionsMCP connection and workspace without changing anything. Explain whether I can save, then ask which race and candidates I want to model. Resolve that race before creating a scenario, and keep the same scenario/version in the map, Discussions and outputs.","prompts":"MCP prompts (prompts/list, prompts/get) include onboard-campaign, check-in, open-race, model-swing, connect-check, daily-brief, and use-<tool> for each tool in your profile. For campaign setup, tool-only clients call get_campaign_onboarding. The client decides how prompts are offered; connection alone does not start setup.","steps":[{"id":"checkin","title":"Check in","prompt":"Call electionsmcp connection_status and report logged_in, auth_method, tool_profile and workspace. Then call billing_status and report can_save. Finally call help and tell me what I can do. Report any tool errors instead of assuming setup succeeded.","done_by":["connection_status","help"]},{"id":"race","title":"Open a practice model","prompt":"Create a separate practice model for the 2026 Iowa Senate race using the supported 2024 presidential baseline. Name it \"Practice — 2024 baseline\", report the source election, and leave my campaign unchanged. If that baseline is unavailable, stop and explain.","done_by":["create_simulation","create_scenario","set_race_scope","set_view","describe_open_campaign"]},{"id":"swing","title":"Model a swing and save it","prompt":"In that practice model only, apply a 2-point uniform swing toward the Democrat, then commit a version called \"First swing\". Leave my campaign unchanged.","done_by":["apply_uniform_swing","set_performance","set_feature_percentages","set_precinct_pcts","set_turnout","bulk_set_primary_shares","set_primary_shares"],"then":"commit_version"}]},"quickstarts":[{"goal":"Build a presidential scenario","steps":["create_simulation","set_cycle(2028) + set_mode(\"general\")","set_candidates(level:\"president\")","set_performance / set_turnout — your assumptions","get_tally(\"president\") — the Electoral College result","list_scenario_versions / diff_versions — compare versions","share_simulation — a public read-only scenario link"]},{"goal":"Model a presidential primary","steps":["create_simulation","set_mode(\"dem_primary_2028\" or \"rep_primary_2028\")","set_primary_candidates — define the prospective field","set_primary_shares — model states","roll_up_primary — calculate delegates","set_compare_paths — compare candidate paths"]},{"goal":"Explore a scenario by geography","steps":["bind_session({page_url}) when a model is already open","get_view — read the exact scenario and selection","get_shapes(layer:\"actuals:pres_2024\") — load supported geography","aggregate_precincts(simulation_id) — scenario-scoped local rollup with provenance","render_view — create a map from the same scenario version"]},{"goal":"Coordinate campaign work","steps":["create_campaign — establish the campaign context","list_people — find collaborators","add_map_comment — discuss the selected geography","assign_task — turn the selection or conversation into work","membership_summary — read concise leadership status"]},{"goal":"Share a modeled result","steps":["read the exact scenario version with get_scenario","share_simulation — mint a public read-only scenario link","authenticate when you need generate_report — create a durable report pinned to that version"]}],"feedback":"Use the in-app Feedback panel for product feedback and support.","next":"Once connected, call help for the profile-aware workflow. When the user wants to set up or join a campaign, call get_campaign_onboarding first and lead the setup in this AI conversation. Resume existing work before creating anything. Connecting alone never authorizes setup writes."}