MCP Server

ElectionsMCP

com.electionsmcp/electionsmcp
Data & Analytics Public & reachable MCP 2025-11-25

What this MCP does

Models and compares U.S. election scenarios at state, district, county, and precinct levels, including turnout, swing, candidate shares, and vote rollups.

add_annotation
Pin a note or highlight on the map — an annotation that travels with the scenario, so collaborators see what the scenario is targeting at a glance. Three types: "pin" (a labeled marker at lng/lat, or anchored to a…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'type'], 'properties': {'geo': {'type': 'object', 'properties': {'level': {'type': 'string'}, 'feature_id': {'type': 'string'}}, 'description': "pin/note: anchor to a feature's centroid instead of raw lng/lat.", 'additionalProperties': False}, 'lat': {'type': 'number', 'description': 'pin: latitude'}, 'lng': {'type': 'number', 'description': 'pin: longitude'}, 'note': {'type': 'string', 'description': 'Longer descriptive text (the "why").'}, 'type': {'enum': ['pin', 'highlight', 'note'], 'type': 'string'}, 'color': {'type': 'string', 'description': 'CSS color or hex (e.g. "#f59e0b") for visual coding. Optional — a default is chosen by type.'}, 'label': {'type': 'string', 'description': 'Short title shown on the pin / highlight / note.'}, 'level': {'type': 'string', 'description': 'highlight: geography level of feature_ids (president→county/state fips, house→district id, etc.).'}, 'style': {'enum': ['border', 'fill'], 'type': 'string', 'description': 'highlight render style (default "border").'}, 'feature_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'highlight: the precinct/county/state/district ids to emphasize.'}, 'source_query': {'type': 'object', 'required': ['tool', 'arguments'], 'properties': {'tool': {'enum': ['target_precincts', 'list_flipped'], 'type': 'string'}, 'arguments': {'type': 'object', 'additionalProperties': True}}, 'description': 'Optional read-only recipe that selected these features. Store target_precincts/list_flipped arguments without model/workspace/campaign IDs (8 KiB maximum). This records a snapshot, does not execute or verify the query, and does not automatically refresh membership. A clone returns a refresh_query bound to the clone; re-run it in the authorized workspace and replace reviewed annotations.', 'additionalProperties': False}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
add_candidate
Add a candidate to the candidates list for a simulation+level. Returns the candidate_id assigned. Pass an optional id (e.g. "boebert") to give the candidate a stable, human-readable id you can reference in later…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'name'], 'properties': {'id': {'type': 'string', 'description': 'Optional stable id for the candidate (e.g. "boebert"). Must be unique on the level roster; auto-minted as C<n> when omitted.'}, 'name': {'type': 'string'}, 'color': {'type': 'string', 'pattern': '^#[0-9a-fA-F]{6}$'}, 'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'party': {'type': 'string'}, 'ideology': {'type': 'string', 'description': 'Optional ideology lane (e.g. "progressive", "moderate").'}, 'incumbent': {'type': 'boolean', 'description': 'Optional: mark as the incumbent.'}, 'home_state': {'type': 'string', 'description': 'Optional home-state postal/FIPS (powers home-state map annotations + plausibility lints).'}, 'incumbency': {'type': 'string', 'description': 'Optional incumbency status (e.g. "incumbent", "challenger", "open").'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
add_map_comment
Leave a Google-Docs-style COMMENT on the scenario map — a threaded, resolvable discussion anchored to a place. CAMPAIGN ISOLATION: when working inside a campaign, pass campaign_id; the scenario must be filed under it…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'body'], 'properties': {'lat': {'type': 'number', 'description': 'Free-point anchor latitude (use with lng).'}, 'lng': {'type': 'number', 'description': 'Free-point anchor longitude (use with lat).'}, 'body': {'type': 'string', 'description': 'The comment text (supports @mentions by email/handle).'}, 'level': {'type': 'string', 'description': 'Feature anchor level (county|precinct|state|house|state_senate|state_assembly). Defaults to the sim level.'}, 'title': {'type': 'string', 'description': 'Optional short name for the post (a strategy/target/event has one; plain chat does not — feeds fall back to a body excerpt). Indexed for full-text search alongside body.'}, 'object': {'type': 'object', 'required': ['kind', 'ref'], 'properties': {'ref': {'type': 'string'}, 'kind': {'enum': ['strategy', 'strategy_step', 'annotation', 'version', 'candidate', 'person', 'report_widget'], 'type': 'string'}}, 'description': 'Anchor the comment to an OBJECT (a strategy / strategy step / annotation / version / candidate / workspace person / canonical report widget), not a map place — the comment is ABOUT that object. A person ref must resolve inside this workspace and, when campaign-scoped, the person must be assigned to that campaign. A report_widget ref is verified against this exact saved scenario version.', 'additionalProperties': False}, 'payload': {'type': 'object', 'description': 'Category-specific structured fields, stored as-is. Examples — target: { priority, channel, universe_ref }; action: { status, assignee, due_at, priority }; need: { qty, unit, urgency }; event: { event_kind, starts_at, ends_at }.'}, 'regions': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The post\'s MANY-TO-MANY location — the region/turf/shapefile ids this post covers (a multi-area comment\'s selected regions, a canvass turf, a target\'s shapes). ONE comment can anchor to MANY areas: pass every id here. Written to the post_regions junction ("what is happening in this region?" stays one indexed query) AND stamped by the server onto the comment\'s payload.regions, so every reader of the post gets the full set back and the open map frames all of it. Returns regions_saved = what actually landed.'}, 'category': {'enum': ['note', 'target', 'canvass', 'action', 'need', 'event', 'strategy'], 'type': 'string', 'description': 'UNIFIED WAR ROOM OBJECTS: what kind of floater this placement is. Every category shares the same anchor model and starts a thread; the category drives the icon, the War Room grouping, and which payload fields make sense. A canvass_kind implies category "canvass" automatically.'}, 'icon_type': {'type': 'string', 'description': 'The icon/subtype within the category — e.g. note: why|risk|fact|question; target: by role; canvass: the drop kind; action: follow_up|call|door|research|decision.'}, 'parent_id': {'type': 'string', 'description': "Reply to this comment id (creates a thread; inherits the parent's anchor)."}, 'feature_id': {'type': 'string', 'description': 'Anchor to this feature (5-digit county FIPS / precinct external_id / 2-digit state FIPS / district GEOID).'}, 'attachments': {'type': 'array', 'items': {'type': 'object', 'properties': {'url': {'type': 'string'}, 'kind': {'enum': ['link', 'view'], 'type': 'string'}, 'mime': {'type': 'string'}, 'name': {'type': 'string'}, 'size': {'type': 'number'}, 'object_path': {'type': 'string'}}}, 'description': 'Attachments on the message: [{name,url,mime,size,object_path?,kind?}]. An UPLOADED FILE rides as the object_path returned by /api/chat-upload — the bucket is private, so each read mints a fresh short-lived signed url into `url` (never store or share one; it expires). kind:"link" for pasted links; kind:"view" for a PINNED MAP VIEW whose url is a same-origin /sim?… deep link (the message carries the exact map context, and clicking the chip restores it).'}, 'campaign_id': {'type': 'string', 'description': 'Campaign that owns this War Room message. The simulation must be tagged into it. Omit only for scenario-global discussion.'}, 'region_kind': {'type': 'string', 'description': 'What grain the regions[] ids are (precinct|county|state|district). Defaults to the anchor level.'}, 'canvass_data': {'type': 'object', 'description': 'Optional structured data for a field pin: { label, status, support_score, contacted_at, … } — anything your campaign tracks per pin.'}, 'canvass_kind': {'enum': ['supporter', 'voter', 'door', 'target', 'note'], 'type': 'string', 'description': 'Make this a color-coded FIELD-MAP PIN (Map View canvassing) instead of a plain comment: supporter (green) | voter (amber) | door (blue) | target (red) | note (teal). Use with a point anchor (lng+lat) or a feature_id. The body is the pin label.'}, 'simulation_id': {'type': 'string'}, 'audience_scope': {'type': 'object', 'required': ['audience', 'precinct_ids', 'boundary_version'], 'properties': {'audience': {'enum': ['campaign', 'leadership', 'finance'], 'type': 'string'}, 'precinct_ids': {'anyOf': [{'type': 'array', 'items': {'type': 'string', 'maxLength': 160, 'minLength': 1}, 'maxItems': 5000, 'minItems': 1, 'uniqueItems': True}, {'type': 'null'}], 'description': 'Exact precinct IDs. Preserve leading zeros. Null means campaign-wide.'}, 'boundary_version': {'type': ['string', 'null'], 'maxLength': 120, 'description': 'The exact boundary version for these precinct IDs; required for precinct access.'}}, 'description': 'Who can read this discussion or assignment. Replies and work originating in a discussion inherit its audience.', 'additionalProperties': False}, 'report_context': {'type': 'object', 'required': ['report_id', 'widget_id'], 'properties': {'report_id': {'type': 'string'}, 'widget_id': {'type': 'string'}}, 'description': "Bind this discussion to the exact immutable report widget the user is viewing. The report and widget must belong to simulation_id and the caller's workspace; the resulting receipt uses that report's pinned version and truthful widget coverage.", 'additionalProperties': False}, 'idempotency_key': {'type': 'string', 'description': 'Optional retry key. Replays return the same post and immutable context instead of duplicating the message.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
aggregate_precincts
Roll up the active user-controlled scenario from its canonical precinct and fallback atoms, returning modeled totals plus the scenario's 2024 baseline comparison and provenance. Requires state, nonempty states[],…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'level': {'enum': ['senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string', 'description': "Optional, with simulation_id — RACE-SCOPE the rollup to one statewide office (tk_3c0569e9b02541): applies exactly that race's overrides (precinct edits tagged to it via precinct_override_levels / race_scope fallback, then its 5-digit county overrides; precinct > county precedence) and adds per-group baseline vs modeled (baseline, baseline_margin_pp, modeled_margin_pp, overridden_precincts, basis) + contribution_pp — each group's shift of that race's STATEWIDE margin. Omitted = the classic president-grain rollup, byte-identical to before."}, 'limit': {'type': 'integer', 'default': 200, 'maximum': 5000, 'minimum': 1}, 'scope': {'enum': ['national'], 'type': 'string'}, 'state': {'type': 'string'}, 'filter': {'type': 'object', 'description': 'Precinct property → condition map within the requested geography. Properties: external_id, GEOID, name, state, county, county_fips, shape_id, votes_dem, votes_rep, votes_total, pct_dem_lead, official_boundary, lat, lng, population, mhi, median_home, pct_bachelors, pct_foreign_born, unemp_pct, median_age, owner_occ_pct, modeled_margin_pp, modeled_pct_dem_lead, flipped, overridden. A bare scalar means exact equality; an array means membership. Object operators: gt, gte, lt, lte, in, not_in. Comparisons take finite numbers; in/not_in take arrays of scalars. Conditions are ANDed. pct_dem_lead is a baseline two-party share lead in -1..1. Scenario-scoped target_precincts, aggregate_precincts and apply_swing_to_query also accept modeled_margin_pp (D minus R over ALL modeled ballots, percentage points), modeled_pct_dem_lead (same margin / 100), modeled_share.CANDIDATE_ID (0..1 all-ballot share), flipped (winner differs from baseline, including ties) and overridden (saved precinct or county share override). These require a supported general statewide scenario with an allocated local model; missing shares never match numeric comparisons. Example: {external_id:{in:["48009-11"]},votes_total:{gte:500}}. Unknown properties/operators and malformed conditions are rejected before matching or writing.'}, 'states': {'type': 'array', 'items': {'type': 'string'}}, 'sort_by': {'enum': ['margin', 'votes_dem', 'votes_rep', 'votes_total', 'count'], 'type': 'string', 'default': 'margin', 'description': 'Metric to rank groups by (desc).'}, 'group_by': {'enum': ['county', 'none'], 'type': 'string', 'default': 'county'}, 'region_group': {'type': 'string', 'description': 'Optional saved workspace map region-group slug. Returns one modeled rollup per named region.'}, 'simulation_id': {'type': 'string', 'description': "Optional — apply this sim's precinct overrides to the modeled votes."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
analyze_primary_inflections
INFLECTION + SENSITIVITY analysis of a modeled presidential primary — under YOUR scenario's assumptions: not just who leads, but when your modeled race clinches and which contests could flip it. Walks roll_up_primary…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'top_n': {'type': 'integer', 'description': 'How many contests to return in each ranked list (leverage / sensitivity / decisive). Default 8, clamped 1..25.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
announce_presence
HEARTBEAT — announce that this session (a browser tab or an MCP agent) is live in the workspace, optionally on one scenario. Presence rows power the "who's here" roster: list_presence, plus presence[] on get_view /…
Destructive Idempotent
Input schema
{'type': 'object', 'properties': {'level': {'type': 'string', 'description': 'Optional — the office level you are looking at (president/senate/house/…), shown on the roster.'}, 'typing': {'type': 'boolean', 'description': 'Optional — true while you are composing in thread_key; shows a typing indicator there for ~8s per heartbeat.'}, 'state_fips': {'type': 'string', 'description': 'Optional — the 2-digit state FIPS you are focused on.'}, 'thread_key': {'type': 'string', 'description': 'Optional — the discussion thread you are reading or writing in (a list_threads thread key, e.g. "feature:county:42003" or "post:<comment_id>"). Shows as "viewing" on that thread for everyone in the room.'}, 'actor_label': {'type': 'string', 'description': 'Optional display name for the roster (e.g. "Claude — targeting pass").'}, 'scenario_id': {'type': 'string', 'description': 'The sim you are working on (defaults to your bound sim from bind_session, else a workspace-level heartbeat).'}, 'focus_geo_id': {'type': 'string', 'description': 'Optional — the specific geography you are working (county fips / district / precinct id).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
answer_assumption
SCENARIO TRUST assumptions ledger (tk_960747792b23d3) — record a question you asked the user (or a premise you were given) and the answer that now drives this scenario's modeling: "Does the field consolidate after…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'question', 'answer'], 'properties': {'answer': {'type': 'string', 'description': "The answer now baked into the modeling — the user's premise or stated scenario assumption."}, 'source': {'type': 'string', 'description': 'Optional provenance for the user-authored assumption, such as a chat statement or source citation.'}, 'question': {'type': 'string', 'description': 'The assumption being pinned down, as the question that was (or should be) put to the user.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
apply_calendar_scenario
Apply a saved calendar scenario BY REFERENCE to a simulation — sets the sim's Democratic calendar to that ordering (reusing the define_dem_calendar path, so the delegate math is untouched). scenario is a saved…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'scenario'], 'properties': {'scenario': {'type': 'string', 'description': 'A saved calendar-scenario id or name.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
apply_primary_cohort
BULK conditional primary edit — for every precinct in a HOUSE district that matches a 2024 cohort filter, set the candidate shares, in ONE call (instead of one set_primary_precinct_shares per precinct). Scopes to THIS…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'url': {'type': 'string', 'description': 'Alternatively the open page URL — the district + level are parsed from ?race=house:0617&level=house.'}, 'clear': {'type': 'boolean', 'description': 'true = RESET: un-model every matching precinct back to its 2024 baseline (no shares needed). e.g. {where:{votes_total_gte:0}, clear:true} resets the whole district. Live.'}, 'level': {'enum': ['house', 'state_senate', 'state_assembly'], 'type': 'string', 'default': 'house'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': 'Which primary field. A top-two (nonpartisan) race: pass "D" (it buckets under d).'}, 'where': {'type': 'object', 'properties': {'dem_share_gt': {'type': 'number', 'description': 'D two-party share strictly greater than this (0-100).'}, 'dem_share_lt': {'type': 'number'}, 'rep_share_gt': {'type': 'number', 'description': 'R two-party share strictly greater than this (0-100).'}, 'rep_share_lt': {'type': 'number'}, 'votes_total_gte': {'type': 'number', 'description': 'Only precincts with at least this many 2024 votes.'}}, 'description': "Cohort filter on each precinct's 2024 TWO-PARTY share. e.g. {rep_share_gt: 40} (R got >40% of the two-party vote).", 'additionalProperties': False}, 'shares': {'type': 'object', 'description': 'The {candidate_id: pct} outcome to set on every matching precinct, e.g. {"<candidate_id>": 80}. Ids from describe_open_campaign / the field roster. Omit when clear:true.'}, 'dry_run': {'type': 'boolean', 'description': 'true = preview only (matched_count + sample, no write). Recommended first.'}, 'district_id': {'type': 'string', 'description': 'The house district external_id, e.g. "0617" (state 06 + district 17). Or pass `url`.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
apply_swing_to_query
Apply a uniform swing or an explicit per-precinct weights vector to a filtered cohort in one atomic call. Weights select only their named IDs, support canonical statewide mechanisms, and optionally rescale a persuasion…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'state', 'filter'], 'properties': {'mix': {'type': 'number', 'default': 0.5, 'maximum': 1, 'minimum': 0, 'description': 'mode:"mixed" only — the fraction of swing_pp delivered via persuasion (the rest via turnout).'}, 'mode': {'enum': ['persuasion', 'turnout', 'mixed'], 'type': 'string', 'description': 'HOW the swing happens (EM-008). persuasion = conversion (×2 margin, ballots hold); turnout = one-sided ballots (×1 margin, votes_total moves); mixed = mix persuasion + the rest turnout. Omit for the classic call.'}, 'level': {'enum': ['senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly', 'president'], 'type': 'string', 'description': 'The office these swung precincts model — folds them into that race\'s state rollup (same tag as set_precinct_pcts). REQUIRED for mode:"turnout"/"mixed" (the ballots ride that race\'s lever kernel; president excluded).'}, 'state': {'type': 'string', 'description': 'Postal, FIPS, or resolve_geography slug ("us-pa") — required, scopes the query (EM-056: all formats accepted; also fills from geo_id).'}, 'filter': {'type': 'object', 'description': 'Precinct property → condition map within the requested geography. Properties: external_id, GEOID, name, state, county, county_fips, shape_id, votes_dem, votes_rep, votes_total, pct_dem_lead, official_boundary, lat, lng, population, mhi, median_home, pct_bachelors, pct_foreign_born, unemp_pct, median_age, owner_occ_pct, modeled_margin_pp, modeled_pct_dem_lead, flipped, overridden. A bare scalar means exact equality; an array means membership. Object operators: gt, gte, lt, lte, in, not_in. Comparisons take finite numbers; in/not_in take arrays of scalars. Conditions are ANDed. pct_dem_lead is a baseline two-party share lead in -1..1. Scenario-scoped target_precincts, aggregate_precincts and apply_swing_to_query also accept modeled_margin_pp (D minus R over ALL modeled ballots, percentage points), modeled_pct_dem_lead (same margin / 100), modeled_share.CANDIDATE_ID (0..1 all-ballot share), flipped (winner differs from baseline, including ties) and overridden (saved precinct or county share override). These require a supported general statewide scenario with an allocated local model; missing shares never match numeric comparisons. Example: {external_id:{in:["48009-11"]},votes_total:{gte:500}}. Unknown properties/operators and malformed conditions are rejected before matching or writing.'}, 'source': {'type': 'string', 'maxLength': 300, 'description': "mode calls that move ballots: stored on the lever's audit entry."}, 'weights': {'type': 'object', 'description': 'Alternative to swing_pp: exact precinct external_id -> signed swing percentage points. Only these IDs change; all must be inside the state/filter with canonical ballots. Requires explicit D/R target, mode, statewide level and a cap covering the whole vector. President supports persuasion only. Optional target_margin_pp rescales a persuasion vector by a nonnegative factor (closest to 1 when several solutions exist), preserving its signs; target scope is weighted IDs only. Shares use sum-preserving 2-decimal rounding; receipt reports achieved margin/residual, clamps, weighted mean and one audit entry. Incremental; do not blindly replay after timeout.', 'maxProperties': 20000, 'minProperties': 1, 'additionalProperties': {'type': 'number', 'maximum': 50, 'minimum': -50}}, 'swing_pp': {'type': 'number', 'maximum': 50, 'minimum': -50, 'description': 'Percentage-point swing toward the target candidate. mode:"turnout": the percent of each precinct\'s ballots added for the target side.'}, 'assumption': {'type': 'string', 'maxLength': 600, 'description': "mode calls that move ballots: stored on the lever's audit entry."}, 'max_precincts': {'type': 'integer', 'default': 5000, 'maximum': 20000, 'minimum': 1, 'description': 'Safety cap on how many precincts get mutated.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'target_margin_pp': {'type': 'number', 'maximum': 100, 'minimum': -100, 'description': 'Alternative to swing_pp: desired margin of the target party over the other major party, as a percentage of all modeled ballots in the filtered cohort. Requires mode:persuasion, explicit toward_candidate_id and statewide level (including president). Cannot be combined with swing_pp.'}, 'toward_candidate_id': {'type': 'string', 'description': 'The candidate id receiving the swing (e.g. "D", "R", or a custom id). Inferred to the level\'s first candidate of opposite party if omitted.'}}, 'additionalProperties': False}
apply_uniform_swing
Apply an incremental swing in points toward one candidate at the requested office. A saved race_scope restricts writes to that state or district and refuses a different office or unresolved geography. Unscoped and…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'swing_pp'], 'properties': {'as_of': {'type': 'string', 'description': 'YYYY-MM-DD timeline point at which to evaluate the decayed swing. Default: decay_start_date (full magnitude). Only used when decay_halflife is set.'}, 'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'swing_pp': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'simulation_id': {'type': 'string'}, 'decay_halflife': {'type': 'number', 'description': "Optional. Half-life in DAYS: past decay_start_date the applied swing halves every this-many days (exponential fade toward baseline). Omit for a permanent swing (today's behavior).", 'exclusiveMinimum': 0}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'decay_start_date': {'type': 'string', 'description': 'YYYY-MM-DD the shift lands / peaks (decay measured forward from here). Default: today. Only used when decay_halflife is set.'}, 'toward_candidate_id': {'type': 'string', 'default': 'D'}}, 'additionalProperties': False}
billing_status
BILLING — your subscription state: {billing_enabled, logged_in, plan (personal|team|null), status, active, renews, can_save}. billing_enabled is false until the server is configured with Stripe; while it is false,…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
bind_session
BIND this agent session to the USER'S OPEN /sim — the session-bootstrap contract (tk_2ba54e8466bc19 / tk_7069d33b0c682e). Call this FIRST, before creating or editing anything: pass the page URL the user has open…
Destructive Idempotent
Input schema
{'type': 'object', 'properties': {'clear': {'type': 'boolean', 'description': 'true = unbind this session (removes the binding + the warning/refusal behavior). Ignores the other params.'}, 'strict': {'type': 'boolean', 'description': 'true = mutations targeting any OTHER sim (and orphan create_simulation calls) are REFUSED while this binding stands (error bound_session_mismatch). Default false = soft binding_warning only.'}, 'page_url': {'type': 'string', 'description': 'The /sim URL the user has open (…?sim=sim_xxx…) — the sim id is parsed from it. Prefer this: it is the ground truth of what they are looking at.'}, 'actor_label': {'type': 'string', 'description': 'Optional display name for your presence row (e.g. "Claude — FL county modeling"). Defaults to your key\'s agent label.'}, 'simulation_id': {'type': 'string', 'description': 'Alternatively the raw sim id (sim_xxx).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
bulk_set_primary_shares
Write user-authored presidential-primary shares across many retained state or county geographies in one call. Uses the same validation, scenario storage, and delegate-allocation kernel as the single-geography primary…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'level': {'enum': ['state', 'county'], 'type': 'string', 'default': 'state', 'description': 'The geographic grain to write. "state" (default) writes statewide primary shares; "county" writes county-grain shares that turnout-weight up into their state. National fan-out (`shares` topline) is state-grain only.'}, 'party': {'enum': ['D', 'R'], 'type': 'string'}, 'by_geo': {'type': 'object', 'description': 'EXPLICIT per-geo map: { "<geo>": { candidate_id: pct, ... }, ... }. Keys are state FIPS/abbr at level "state", or 5-digit county FIPS at level "county". Pass empty shares ({}) for a geo to un-model it. Provide this OR `shares`, not both.'}, 'shares': {'type': 'object', 'description': 'NATIONAL FAN-OUT topline: a map of candidate_id → percentage (0-100) written to every targeted state. Provide this OR `by_geo`, not both. Only valid at level "state".'}, 'states': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional target list for the fan-out — state FIPS ("19") or 2-letter abbr ("IA"). Omit to fan the topline out to ALL 50 states + DC.'}, 'dry_run': {'type': 'boolean', 'description': 'true = preview the per-geo plan (no write).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
candidate_path_explainer
PATH-TO-THE-NOMINATION explainer — for each candidate in a presidential-primary scenario (or one candidate_id), a DERIVED, plain-numbers account of HOW they win or WHY they fall short, straight from the delegate…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'asof': {'type': ['integer', 'null'], 'description': 'Optional. Evaluate the race as of this many contests counted (0 = before Iowa); omit/null = the full projected race (matches roll_up_primary with no asof).'}, 'party': {'enum': ['D', 'R'], 'type': 'string'}, 'best_n': {'type': 'integer', 'description': 'Optional. How many best_states to return (default 5, clamped 1..20).'}, 'weak_n': {'type': 'integer', 'description': 'Optional. How many weak_states to return (default 5, clamped 1..20).'}, 'candidate_id': {'type': 'string', 'description': 'Optional. Explain ONE candidate — a roster id (e.g. "newsom-d") or their name. Omit for every candidate in the field.'}, 'max_swing_pp': {'type': 'number', 'description': 'Optional plausibility cap (percentage points, default 10, clamped 1..40) — the largest per-state swing minimal_swing_scenario may assume. A gap needing more than this across the modeled contests returns minimal_swing_scenario:null.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
candidate_standing
PORTAL — one candidate/official's standing across every race you model them in. Give a {name} (and optional {party} to disambiguate); it finds all their appearances across your sims, builds each sim's impact report,…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': "The candidate/official's name as it appears in your rosters (case-insensitive)."}, 'party': {'type': 'string', 'description': 'Optional party (D/R/I/…) to disambiguate same-named candidates.'}, 'candidate_id': {'type': 'string', 'description': 'Optional precise selector (the local roster id, e.g. "C1") to pick ONE candidate when a same-name same-party pair can\'t be split by {party} alone — take it from an ambiguous match\'s candidate_id/disambiguator.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
check_workspace_consistency
SCENARIO TRUST cross-scenario consistency sweep (tk_57e0d6adfac63d) — do this workspace's primary scenarios contradict each other? Groups the COMPARABLE presidential-primary scenarios (same mode+party, same calendar…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'maximum': 40, 'minimum': 2, 'description': 'Max scenarios to sweep, most recently updated first (default 20).'}, 'simulation_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional — sweep exactly these scenarios instead of the most recent.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clear_annotations
Remove all annotations from a scenario, or only those of one type when "type" is given.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'type': {'enum': ['pin', 'highlight', 'note'], 'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clear_dem_calendar
Discard the simulation's user-defined Democratic calendar and revert to the default 2024-based Dem calendar.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clear_feature_override
Clear the manual percentage override on a single feature (county/state/district), reverting it to its baseline.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'feature_id'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer', 'custom'], 'type': 'string'}, 'feature_id': {'type': 'string', 'description': 'Same feature id set_feature_percentages / set_performance accept — for a statewide level a state as FIPS ("39"), postal ("OH"), or "us-oh" slug are all accepted (normalized server-side).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'The last-read updated_at token; custom model writes refuse stale edits.'}}, 'additionalProperties': False}
clear_precinct_override
Remove a precinct-level override from a simulation, reverting that precinct to its 2024 baseline.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'precinct_id'], 'properties': {'precinct_id': {'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clear_primary_shares
Remove a state's primary vote shares for a party (un-model that contest).
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'state'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'State FIPS or 2-letter abbr.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clear_race_scope
Remove the race scope from a simulation, returning it to national/retrospective mode.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
clone_simulation
Duplicate a simulation under a new name. Useful for "save as / variant" workflows. The clone carries the source scenario's overrides, candidates, description, campaign membership AND its annotations…
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id', 'new_name'], 'properties': {'new_name': {'type': 'string'}, 'fork_event': {'type': 'string', 'description': 'Optional label for the inflection that splits this branch from its siblings (e.g. "Baltimore indictment 2026-06-15"). Stored on the clone so list_siblings can present "one of N futures of <event>".'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'include_annotations': {'type': 'boolean', 'description': "Carry the source scenario's annotations (pins/highlights/notes) onto the clone with fresh ids. Default true."}}, 'additionalProperties': False}
commit_version
Save the scenario's current state as a new immutable, hash-stamped version in the append-only chain. Records a diff vs the parent version and the recomputed top_line, and returns a content `hash` (+ `prev_hash`…
Destructive
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'title': {'type': 'string', 'description': 'Optional SHORT card title (<=80 chars), distinct from the longer summary — what the VERSIONS card shows as its heading, e.g. "Orange County flip".'}, 'summary': {'type': 'string', 'description': 'Human-readable note on what changed, e.g. "Flipped Orange County to D+40".'}, 'insight_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': "Optional — insight ids (ins_…) this version explains. Validated against the sim's insights; unknown ids are reported in `unlinked` and dropped."}, 'scenario_id': {'type': 'string'}, 'include_diff': {'type': 'boolean', 'default': False, 'description': 'Inline the full before/after diff in the response (can be very large). Default false: return compact diff_stats only; fetch the full diff via diff_versions when needed.'}, 'annotation_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': "Optional — annotation ids (pins/highlights/notes on this sim) this version explains. Validated against the sim's annotations; unknown ids are reported in `unlinked` and dropped, never invented."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
compare_simulations
Compare two simulations. Without grain, returns the existing chamber/feature comparison. With grain:county|precinct and one state, compares exact saved canonical vote rows: margin(B)-margin(A), winners, flips, ballots…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id_a', 'simulation_id_b', 'level'], 'properties': {'grain': {'enum': ['county', 'precinct'], 'type': 'string', 'description': 'Return canonical local outcomes instead of a chamber tally.'}, 'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'limit': {'type': 'integer', 'default': 500, 'maximum': 2000, 'minimum': 1}, 'state': {'type': 'string', 'description': 'Required for county/precinct comparison: one state postal code or FIPS.'}, 'format': {'enum': ['json', 'csv', 'geojson'], 'type': 'string', 'description': 'Local comparison table format; CSV/GeoJSON add a private complete-file download URL.'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0}, 'version_a': {'type': 'string', 'description': 'Difference comparison: exact saved version of A. Omit only when its latest version matches the live model.'}, 'version_b': {'type': 'string', 'description': 'Difference comparison: exact saved version of B. Omit only when its latest version matches the live model.'}, 'campaign_id_a': {'type': 'string', 'description': 'Optional campaign custody for A when the model belongs to multiple readable campaigns. Does not grant access.'}, 'campaign_id_b': {'type': 'string', 'description': 'Optional campaign custody for B when the model belongs to multiple readable campaigns. Does not grant access.'}, 'expected_hash_a': {'type': 'string', 'description': 'Optional expected immutable version hash for A; mismatches refuse.'}, 'expected_hash_b': {'type': 'string', 'description': 'Optional expected immutable version hash for B; mismatches refuse.'}, 'simulation_id_a': {'type': 'string'}, 'simulation_id_b': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
compute_vote_goal
Calculate the deterministic win number and remaining vote gap for the active user-controlled scenario. Supports plurality, majority, or explicit share goals and reconciles from the scenario's geography, turnout, and…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'geo_id': {'type': 'string', 'description': 'Contest geography (district or state). Accepts the resolve_geography slug ("us-pa"), postal ("PA"), or FIPS ("42") — EM-056. Defaults to the simulation\'s race_scope geography.'}, 'margin': {'type': 'number', 'default': 1, 'description': 'plurality: win by at least this many votes (default 1).'}, 'goal_mode': {'enum': ['plurality', 'majority', 'share'], 'type': 'string', 'default': 'plurality', 'description': 'plurality = beat the leading opponent (default); majority = 50.01% share; share = explicit target_pct.'}, 'target_pct': {'type': 'number', 'default': 0.5001, 'description': 'share mode: target win share, 0–1.'}, 'scenario_id': {'type': 'string', 'description': 'The scenario/simulation handle (EM-056: simulation_id is accepted as an alias — same sim_ value).'}, 'candidate_id': {'type': 'string', 'default': 'D', 'description': 'Which candidate the goal is computed for.'}, 'rolloff_rate': {'type': 'number', 'maximum': 1.5, 'minimum': 0.05, 'description': 'Explicit roll-off rate to apply instead of deriving (e.g. 0.94 = the office sees 94% of presidential ballots).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
confirm_connection
CUSTOMER SETUP — confirm a connection challenge THROUGH the MCP pipe: proves this key reaches this account (and workspace, when bound), records the client family, and advances the setup to activate. Typed states:…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['challenge'], 'properties': {'challenge': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
connection_status
WHO AM I — how THIS session is authenticated and which workspace this request resolved to. Returns authentication fields plus workspace {workspace_id, role, selection_source}. Modern MCP clients select a workspace with…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/connection_status/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'required': ['logged_in', 'auth_method', 'tool_profile', 'workspace'], 'properties': {'first_run': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'logged_in': {'type': 'boolean'}, 'workspace': {'anyOf': [{'type': 'null'}, {'type': 'object', 'required': ['workspace_id', 'role', 'selection_source'], 'properties': {'role': {'type': ['string', 'null']}, 'workspace_id': {'type': 'string'}, 'selection_source': {'type': 'string'}}, 'additionalProperties': True}]}, 'connection': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'onboarding': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'auth_method': {'enum': ['anonymous', 'session', 'api_key', 'oauth']}, 'tool_profile': {'type': 'string'}}, 'additionalProperties': True}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
create_connection_challenge
CUSTOMER SETUP — mint a short-lived (15 min), ONE-TIME connection challenge for a setup session you own. Your human tells their AI the code; the AI calls confirm_connection through MCP — that call itself is the…
Destructive
Input schema
{'type': 'object', 'properties': {'setup_id': {'type': 'string'}, 'expected_client': {'enum': ['claude', 'chatgpt', 'codex', 'cursor', 'any'], 'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
create_custom_candidate
Create a workspace-scoped prospective or write-in candidate with a stable identity, party, color, and optional office, then add that identity to canonical general- or primary-model rosters.
Destructive
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'Candidate full name.'}, 'color': {'type': 'string', 'description': 'Optional hex color (e.g. "#7c3aed").'}, 'party': {'type': 'string', 'description': 'Party letter (D, R, I, L, G, …).'}, 'office': {'type': 'string', 'description': 'Optional office context, e.g. "President".'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
create_race
Instantiate a tenant workspace (a Race) on a real-world Contest. Pass a canonical contest_id ({geo_id}:{office}:{cycle}:{stage}, e.g. "us-nc-cd-04:ushouse:2028:general"). Creates an empty race the caller then adds…
Input schema
{'type': 'object', 'required': ['contest_id'], 'properties': {'name': {'type': 'string', 'description': 'Optional; defaults to a label derived from the contest.'}, 'contest_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
create_scenario
Create a new Scenario (a modeled path) — optionally inside a Race and seeded from a contest_id or an existing scenario (import_from). Seeds an immutable baseline version (v1). Returns scenario_id + version_id. (A…
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string'}, 'tags': {'type': 'array', 'items': {'type': 'string'}}, 'race_id': {'type': 'string', 'description': 'Optional; the Race this scenario belongs to.'}, 'contest_id': {'type': 'string', 'description': "Optional; sets the scenario's race_scope from a canonical contest_id."}, 'baseline_id': {'type': 'string', 'description': 'Optional explicit source pin. Only 2024_president_mixed_grain is currently selectable. Known county sources return baseline_selection_unavailable; unreconciled sources return baseline_not_model_eligible; unknown IDs return unknown_baseline. No source is silently substituted.'}, 'campaign_id': {'type': 'string', 'description': 'Custom campaign to model inside its exact attached city boundary.'}, 'import_from': {'type': 'string', 'description': 'Optional; copy overrides+candidates from an existing scenario_id.'}, 'idempotency_key': {'type': 'string', 'maxLength': 160, 'minLength': 1, 'description': 'Optional workspace-scoped retry key for listed races; required for custom campaign models. Identical retries return the same scenario and baseline version. Reusing a key with different creation inputs returns idempotency_conflict.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'boundary_version': {'type': 'string'}, 'expected_campaign_revision': {'type': 'integer', 'minimum': 1}}, 'additionalProperties': False}
create_simulation
Start a brand-new what-if model: an empty simulation of any race, ready for candidates, swings, and turnout. Returns simulation_id you can pass to subsequent calls. Pass level to pick the office (president | senate |…
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'mode': {'type': 'string', 'description': 'President modeling mode: general | dem_primary_2028 | rep_primary_2028 (default general).'}, 'name': {'type': 'string'}, 'cycle': {'type': 'integer', 'description': 'Election cycle being modeled (default 2028). Drives the default president roster.'}, 'level': {'enum': ['president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': "The office the scenario models (default president). RACE PARITY: every office gets the same scenario machinery — a house sim shares/reports as the U.S. House map, a senate sim as the Senate map. Primary modes are presidential only (state-race primaries ride set_primary_* on a race scope). set_view changes only the CAMERA; this sets the scenario's identity."}, 'description': {'type': 'string'}, 'scenario_type': {'enum': ['projection', 'hypothetical', 'counterfactual'], 'type': 'string', 'description': 'SCENARIO TRUST (tk_960747792b23d3): what this scenario claims to be. "projection" (the default when omitted) = the author\'s expected outcome; "hypothetical" = a stated what-if (a best-case, a stress test); "counterfactual" = a world that did not happen. hypothetical/counterfactual stamp a visible badge on get_view and bake a banner into every report/publish of this scenario (same plumbing as the publish-trust watermark), and check_workspace_consistency treats them as labeled what-ifs rather than competing projections. Omitted = byte-identical to before this field existed.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
data_provenance
GOVERNANCE — read the supported 2024 presidential mixed-grain baseline, boundary identities, and user-authored scenario provenance. Pass state:"TX" for the audited 254-county baseline-versus-certified comparison and…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'state': {'type': 'string', 'description': 'Optional state postal code or FIPS: TX/48 also returns all 254 audited county baseline-versus-certified vote differences, exact source receipts, and unchanged-baseline status. Attach observed precinct geometry counts, source URLs, lossless ID rules and geometry fingerprints. Original boundary vintage and cross-cycle precinct-name mappings remain unknown; saved versions do not pin geometry bytes.'}, 'source': {'enum': ['2024_president_mixed_grain', 'boundaries_tiger_2024', 'precinct_boundaries_2024', 'simulation_model'], 'type': 'string', 'description': 'Optional retained provenance card; omit to return the complete supported workbench set.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
define_dem_calendar
Define a user-authored Democratic primary calendar order and dates for this simulation. Read list_primary_calendar first for the model's pinned calendar and recorded official schedule evidence. This overrides the model…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'calendar'], 'properties': {'calendar': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Ordered contests: [{state, date, type?, delegates?}]. state = FIPS or abbr; delegates defaults to the 2024-based count if omitted; type defaults to "primary".'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
delete_race
Delete one workspace-scoped race. Its standalone scenarios remain available until explicitly deleted.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['race_id'], 'properties': {'race_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
delete_report
Delete one generated, workspace-scoped scenario report.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['report_id'], 'properties': {'report_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
delete_simulation
Permanently delete a simulation.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
describe_open_campaign
Show the agent the campaign the user has OPEN right now, as one editable packet. Pass the page URL the user is on (e.g. https://www.electionsmcp.com/sim?sim=sim_xxx&level=house&stage=top_two) OR a raw simulation_id,…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'url': {'type': 'string', 'description': 'The page URL the user has open; the ?sim= token + the level/stage/cycle/race view params are parsed from it.'}, 'bind': {'type': 'boolean', 'description': 'true = ALSO bind this session to the resolved sim (identical to calling bind_session on it): subsequent writes to a different sim carry a binding_warning, and your presence is announced on the open sim.'}, 'strict': {'type': 'boolean', 'description': 'With bind:true — make the binding STRICT: a mutation targeting any OTHER sim (or an orphan create_simulation) is refused, not just warned. Default false.'}, 'simulation_id': {'type': 'string', 'description': 'Alternatively the raw sim id (sim_xxx) if you do not have the URL.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
diff_calendar_scenarios
Diff two calendar orderings — each an id/name of a saved calendar scenario, or the literal "default" (the platform calendar). Returns per-contest position moves (earlier/later) and, when you pass a simulation_id +…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['a', 'b'], 'properties': {'a': {'type': 'string', 'description': 'First ordering — a saved calendar scenario id/name, or "default".'}, 'b': {'type': 'string', 'description': 'Second ordering — a saved calendar scenario id/name, or "default".'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': 'Party whose calendar to diff. Default D.'}, 'candidate_id': {'type': 'string', 'description': 'Optional — the candidate to measure clinch/lead timing for (requires simulation_id).'}, 'simulation_id': {'type': 'string', 'description': 'Optional — a modeled primary sim; with candidate_id, adds the per-ordering clinch/lead timing for that candidate.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
diff_versions
Structured diff between two immutable versions. Raw before/after remain stored override patches (null means no saved override). Precinct cells also include effective_before/effective_after shares with their…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id', 'version_a', 'version_b'], 'properties': {'limit': {'type': 'integer', 'default': 100, 'maximum': 500, 'minimum': 1, 'description': 'Maximum changed precinct cells in this page. Summary counts cover the full version pair.'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Use precinct_page.next_offset to continue in stable precinct-id order.'}, 'version_a': {'type': 'string'}, 'version_b': {'type': 'string'}, 'scenario_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
election_calendar
The election planning calendar. National form ({cycle}) returns federal contests, governors and by_state office lists; state form ({state,cycle}) returns a four-year horizon. Other statewide executive offices use the…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'cycle': {'type': 'integer', 'description': 'Defaults to the next election year from today.'}, 'state': {'type': 'string', 'description': 'Postal abbreviation ("PA") for the per-state 4-year horizon; omit for the national summary.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
exit_primary_candidate
Remove a candidate from a party's presidential-primary FIELD and REDISTRIBUTE their modeled vote share to the survivors in one atomic, provenance-carrying edit — the "so-and-so drops out, where do their voters go?"…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'candidate_id'], 'properties': {'mode': {'enum': ['proportional', 'second_choice'], 'type': 'string', 'default': 'proportional', 'description': '"proportional" (default) reallocates the exiting share by the survivors\' existing shares in each cell; "second_choice" uses the second_choice weight map.'}, 'party': {'enum': ['D', 'R'], 'type': 'string'}, 'dry_run': {'type': 'boolean', 'description': 'Preview the per-layer reallocation + resulting roll_up without saving.'}, 'candidate_id': {'type': 'string', 'description': 'The id of the candidate leaving the field — must be on the party roster (set_primary_candidates / list_candidates).'}, 'second_choice': {'type': 'object', 'description': 'Required when mode="second_choice": map of surviving candidate_id → weight (any positive scale), e.g. {"newsom": 0.7, "shapiro": 0.3}. Weights are normalized to sum 1. Must NOT reference the exiting candidate, and every key must be on the roster.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'remove_from_roster': {'type': 'boolean', 'default': True, 'description': 'Also drop the candidate from the primary roster (default true). Pass false to keep them listed (now at 0 everywhere).'}}, 'additionalProperties': False}
exposure
Run a deterministic swing-sensitivity sweep over the active user-controlled scenario and return the modeled control curve, swing-to-flip values, and most sensitive races.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'cycle': {'type': 'integer', 'maximum': 2040, 'minimum': 2024}, 'level': {'enum': ['senate', 'president', 'governor', 'house'], 'type': 'string', 'description': 'Default senate. "house" sweeps all 435 seats around the 218-seat majority line.'}, 'simulation_id': {'type': 'string', 'description': "Optional. Sweep from this scenario's modeled margins instead of the static 2024 baseline; un-modeled races fall back to baseline."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
focus_view
Fly the LIVE map camera to a geography — frame the state / county / district / precinct the viewer is watching, so "show them the decisive counties" actually moves the view (tk_9e8de8). Pass a geo to frame: feature_id…
Destructive Idempotent
Input schema
{'type': 'object', 'properties': {'zoom': {'type': 'number', 'maximum': 20, 'minimum': 0, 'description': "Optional zoom; omit to fit the geography's bounding box."}, 'level': {'enum': ['state', 'county', 'district', 'precinct'], 'type': 'string', 'description': 'The grain of feature_id (or geo_id), if ambiguous.'}, 'state': {'type': 'string', 'description': 'Convenience: a postal code or 2-digit fips to frame that state.'}, 'geo_id': {'type': 'string', 'description': 'A raw id to frame: 2-digit state fips, 5-digit county fips, district GEOID, or precinct id.'}, 'feature_id': {'type': 'string', 'description': 'The id to frame, paired with level.'}, 'duration_ms': {'type': 'integer', 'maximum': 8000, 'minimum': 0, 'description': 'Camera flight time in ms (default 900).'}, 'simulation_id': {'type': 'string', 'description': "Scope the camera move to this scenario's viewers (so it doesn't yank another session's view)."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_ballot_order
BALLOT DESIGN — read back the ballot order recorded by set_ballot_order for a simulation+level: every roster candidate with its printed ballot position (candidates with a position first, in ballot order, then any…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_campaign_context
Load one campaign geography's state of play: canonical modeled/baseline context and the linked campaign plan, with source and as-of provenance.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'year': {'enum': [2024], 'type': 'integer', 'description': 'The canonical baseline year.'}, 'as_of': {'type': 'string', 'description': 'Optional point-in-time for the retained baseline and plan context.'}, 'state': {'type': 'string', 'description': '2-letter state (alternative to geo_id).'}, 'geo_id': {'type': 'string', 'description': 'Place id: "us-de" (state), "us-nc-4"/CD id "3704" (district), or a 5-digit county FIPS.'}, 'include': {'type': 'array', 'items': {'enum': ['baseline', 'plan'], 'type': 'string'}, 'description': 'Retained sections to include. Defaults to baseline and plan.'}, 'district': {'type': 'string', 'description': 'Optional district for the race.'}, 'scenario_id': {'type': 'string', 'description': 'Or a simulation/scenario id — resolves the place from its race_scope + includes its insights.'}, 'office_level': {'type': 'string', 'description': 'Optional race office (president|us_house|us_senate|governor|state_senate|state_assembly) for a race-level baseline.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_campaign_onboarding
CAMPAIGN ONBOARDING — guide a campaign manager or joining staff member through setup in their connected AI. Read one step or the complete guide: connection, campaign identity, team access, optional data imports, first…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'section': {'enum': ['connection', 'campaign', 'team', 'data', 'work', 'complete', 'all'], 'type': 'string', 'default': 'connection', 'description': 'The next conversational step. Read connection first; all returns the complete guide when campaign tools are available.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_catalog
DISCOVERY — browse workflow/category groups, search tool names and descriptions, or fetch one complete schema and AI guide with tool. No arguments returns a compact counted index of the authorized inventory. Core…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'tool': {'type': 'string', 'description': "Exact retained tool name — returns the complete inputSchema and versioned AI guidance matching its use-<tool> MCP prompt when it is present in this session's tools/list."}, 'limit': {'type': 'integer', 'default': 20, 'maximum': 50, 'minimum': 1, 'description': 'Maximum tool entries per discovery page, subject to the response byte budget. Repeat the same filters with next_cursor as cursor until null.'}, 'query': {'type': 'string', 'description': "Text search over this session's retained tool names and descriptions. Ranked: exact name, name substring, then description matches."}, 'cursor': {'type': 'string', 'maxLength': 512, 'description': 'Opaque next_cursor from the previous discovery page. Keep the same query, category and workflow; restart if the authorized catalog changed.'}, 'category': {'type': 'string', 'description': 'Browse one category (e.g. "Scenario") in bounded pages. The category count is the full matching inventory, not this page length.'}, 'workflow': {'enum': ['modeling', 'campaign_operations', 'imports', 'account_and_support', 'staff_support', 'discovery'], 'type': 'string', 'description': 'Opt into a workflow from the compact index. Filters browsing or search within the authorized inventory; never grants access or changes the connection profile.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_catalog_version': {'type': 'string', 'pattern': '^[a-f0-9]{64}$', 'description': 'Optional catalog_version from a previous tools/list or get_catalog response. Returns catalog_changed so clients can detect schema drift and refresh cached bindings.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/get_catalog/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'oneOf': [{'type': 'object', 'required': ['tool'], 'properties': {'tool': {'type': 'object', 'required': ['name', 'category', 'description'], 'properties': {'name': {'type': 'string'}, 'category': {'type': 'string'}, 'annotations': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'description': {'type': 'string'}, 'inputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'outputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'additionalProperties': True}}, 'additionalProperties': True}, {'type': 'object', 'required': ['query', 'matched', 'returned_count', 'truncated', 'next_cursor', 'matches'], 'properties': {'query': {'type': 'string'}, 'matched': {'type': 'integer', 'minimum': 0}, 'matches': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'category', 'description'], 'properties': {'name': {'type': 'string'}, 'category': {'type': 'string'}, 'annotations': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'description': {'type': 'string'}, 'inputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'outputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'additionalProperties': True}}, 'truncated': {'type': 'boolean'}, 'next_cursor': {'type': ['string', 'null']}, 'returned_count': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}, {'type': 'object', 'required': ['total_tools', 'returned_tools', 'categories'], 'properties': {'mode': {'enum': ['category_index', 'category', 'workflow']}, 'matched': {'type': 'integer', 'minimum': 0}, 'truncated': {'type': 'boolean'}, 'workflows': {'type': 'array', 'items': {'type': 'object', 'required': ['workflow', 'label', 'count'], 'properties': {'count': {'type': 'integer', 'minimum': 0}, 'label': {'type': 'string'}, 'workflow': {'type': 'string'}, 'recommended_tools': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': True}}, 'categories': {'type': 'array', 'items': {'type': 'object', 'required': ['category', 'count', 'tools'], 'properties': {'count': {'type': 'integer', 'minimum': 0}, 'tools': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'category', 'description'], 'properties': {'name': {'type': 'string'}, 'category': {'type': 'string'}, 'annotations': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'description': {'type': 'string'}, 'inputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'outputSchema': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'additionalProperties': True}}, 'category': {'type': 'string'}}, 'additionalProperties': True}}, 'next_cursor': {'type': ['string', 'null']}, 'total_tools': {'type': 'integer', 'minimum': 0}, 'returned_count': {'type': 'integer', 'minimum': 0}, 'returned_tools': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}], 'required': ['profile'], 'properties': {'profile': {'type': 'object', 'required': ['active', 'visible_in_tools_list', 'catalog_scope'], 'properties': {'active': {'type': 'string'}, 'catalog_scope': {'type': 'string'}, 'visible_in_tools_list': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}, 'workflow': {'enum': ['modeling', 'campaign_operations', 'imports', 'account_and_support', 'staff_support', 'discovery']}}}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
get_election_dates
When is the New Hampshire primary? — the REAL, dated election-day rows from the amendable election_dates object (tk_090052d2e6ceda): the primary/caucus date per office and party where known, plus the general election…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'cycle': {'type': 'integer', 'description': 'Election cycle, e.g. 2028. Omit to match all cycles.'}, 'state': {'type': 'string', 'description': 'Postal abbreviation ("NH") or 2-digit FIPS ("33"). Omit for all states (national general rows use "US").'}, 'office': {'type': 'string', 'description': 'Filter to one office (president|senate|governor|house|state_senate|state_assembly|attorney_general|secretary_of_state|treasurer|general).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_geography
Boundary reference, children, and a demographic summary (county grain — ACS 2023; states and districts return boundary + identity only) for a canonical geo_id (us, us-ca, us-ca-cd-03, us-ca-county-06017,…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['geo_id'], 'properties': {'geo_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'include_children': {'type': 'boolean', 'default': False}, 'include_demographics': {'type': 'boolean', 'default': True}}, 'additionalProperties': False}
get_geo_knowledge
STRATEGIC KNOWLEDGE — the documented ruleset + knowledge for a geography, so an AI does not have to KNOW the rules; the platform supplies them. Two tiers MERGED on read: (1) a system-seeded, CITED GLOBAL canonical…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['geo_id', 'level'], 'properties': {'level': {'enum': ['state', 'county', 'precinct'], 'type': 'string', 'description': 'Geography grain.'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Optional — which party's rules to return (allocation method + viability differ by party). Default D."}, 'geo_id': {'type': 'string', 'description': "The geography handle — a state postal/FIPS/name (state level), a 5-digit county FIPS (county level), or a precinct id (precinct level). County/precinct inherit their parent state's global rules."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_impact_report
Nation-wide election impact across ALL 6 legislative levels in one call. Cascades county-level (president) overrides to senate/governor state outcomes. Computes state-chamber control where state-leg overrides exist.…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'version_id': {'type': 'string', 'description': 'Optional saved version to replay exactly. Requires expected_version_hash; a version from another scenario is not accepted.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version_hash': {'type': 'string', 'description': 'Required with version_id. The saved payload is computed only when its stored id and content hash match this exact identity.'}, 'cascade_county_to_state': {'type': 'boolean', 'default': True, 'description': 'If true, county-level overrides also recompute senate + governor state outcomes via vote aggregation.'}}, 'additionalProperties': False}
get_manual_edits
Every manual edit in a scenario — the human's (or an agent's) overrides — in one scenario-scoped read, so a connected AI can see exactly what has been modeled and the deltas it produced. Lists each override grouped by…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_plan_catalog
COMMERCIAL CATALOG — the server-owned plan catalog every surface consumes (/pricing, /get-started, account billing, provisioning): six active client types with label, audience, offer (Stripe live price when the store…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_provisioning_status
CUSTOMER SETUP — the per-step provisioning state for a setup session you own: queued/running/done/failed with the exact failed step and a safe retry (provision_customer resumes; done steps never repeat). Powers the…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['setup_id'], 'properties': {'setup_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_race
One Race with its contest, scenario list, and latest top-line per scenario.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['race_id'], 'properties': {'race_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_scenario
A Scenario at its latest version (or a specified version_id): metadata (incl. latest_hash) + the version's top_line (margin / EC / viability) + its content hash/prev_hash. EM-119: pass a version_id (or…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'version_id': {'type': 'string', 'description': 'Optional; defaults to the latest version. When set, the response includes the full per-precinct `state` for that version.'}, 'scenario_id': {'type': 'string'}, 'include_state': {'type': 'boolean', 'description': 'Include the full per-precinct `state` even for the latest version (for redrawing the map).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version_hash': {'type': 'string', 'maxLength': 160, 'minLength': 1, 'description': 'Optional exact content hash from list_scenario_versions. Requires version_id; a mismatch is refused rather than returning a different saved model.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/get_scenario/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'required': ['scenario', 'version', 'context'], 'properties': {'state': {'type': ['object', 'null'], 'additionalProperties': True}, 'context': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'version': {'type': ['object', 'null'], 'additionalProperties': True}, 'scenario': {'type': 'object', 'required': ['scenario_id', 'version_count'], 'properties': {'name': {'type': 'string'}, 'contest_id': {'type': ['string', 'null']}, 'race_scope': {'type': ['object', 'null'], 'additionalProperties': True}, 'scenario_id': {'type': 'string'}, 'version_count': {'type': 'integer', 'minimum': 0}, 'latest_version': {'type': ['string', 'null']}}, 'additionalProperties': True}, 'provenance': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'additionalProperties': True}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
get_shapes
Return state, county, district, or precinct boundaries for the active election model, optionally colored by canonical scenario metrics or the validated 2024 presidential baseline. Responses carry stable geography ids,…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['level'], 'properties': {'ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Only these feature ids (district external_ids like "3704", county FIPS, precinct ids).'}, 'year': {'type': 'integer'}, 'layer': {'enum': ['actuals:pres_2024'], 'type': 'string', 'description': 'Optional canonical 2024 presidential baseline paint.'}, 'level': {'enum': ['custom', 'state', 'county', 'district', 'precinct'], 'type': 'string'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Primary metrics: which side's stores (defaults to the sim's own primary party)."}, 'state': {'type': 'string', 'description': '2-letter (e.g. "NC"). Optional when ids/precincts_of carry a FIPS prefix (inferred); otherwise required except level:state with explicit ids.'}, 'metric': {'type': 'string', 'description': 'Optional metric to color county/district shapes by (margin, turnout, net_votes_to_flip, …) — or "primary_leader"/"primary_share" (with simulation_id) to color state/county/precinct shapes from a primary scenario\'s share stores.'}, 'geojson': {'type': 'boolean', 'description': 'EM-120: return renderable GeoJSON inline — a FeatureCollection with real polygon coordinates per feature (for Mapbox/Leaflet), instead of the slim id/name/value catalog.'}, 'highlight': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Ids to emphasize when there is no metric overlay.'}, 'version_id': {'type': 'string', 'description': 'Exact saved version for a custom city model.'}, 'candidate_id': {'type': 'string', 'description': 'metric:"primary_share" — the set_primary_candidates id whose share colors the shapes.'}, 'max_features': {'type': 'integer', 'default': 1200, 'maximum': 4000, 'minimum': 1, 'description': 'geojson mode: cap features returned inline (payload guard). If exceeded, capped:true + narrow with ids/precincts_of.'}, 'office_level': {'type': 'string', 'description': 'For district level / metric overlay: us_house, state_senate, state_assembly.'}, 'precincts_of': {'type': 'string', 'description': 'With level:precinct — only the precincts inside this district id (e.g. "3704").'}, 'simulation_id': {'type': 'string', 'description': 'With metric:"primary_leader"/"primary_share" — the primary scenario whose stores color the shapes.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version_hash': {'type': 'string'}}, 'additionalProperties': False}
get_simulation
Read the canonical simulation/scenario state, including candidates, race scope, geography overrides, active version identity, provenance, and optional summary or selected dot-path fields.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'fields': {'description': 'Optional read shaping: the string "summary" → the compact identity card (target <5KB); an array of dot-paths (e.g. ["id","mode","primary.asof","primary.grain_pref","updated_at"]) → just those values from the document (plus mode_truth / campaign_identity / provenance as pickable top-level paths). Omit for the full state.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_tally
Compute the current per-candidate tally for a simulation+level. For President: state-aggregated EVs. For others: feature counts. For level:"senate" the default is the 50-state per-candidate race scoreboard; pass…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level'], 'properties': {'cycle': {'type': 'integer', 'description': 'Election cycle for chamber control (level:"senate", chamber:true); default 2028. Ignored otherwise.'}, 'level': {'enum': ['custom', 'president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'chamber': {'type': 'boolean', 'description': 'level:"senate" only — return real chamber control ({D,R,I,seats_up,held_over,majority_status}) via the same math as senate_control, instead of the 50-state race scoreboard.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_texas_certified_ballot
Read Texas November 2026 candidates and races from the Secretary of State certified general-election ballot and certified write-in supplement. Preserves official names, source pages and dates, candidate IDs, and…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 25, 'maximum': 100, 'minimum': 1}, 'county': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': 'Texas county name. Includes races appearing on that county ballot.'}, 'office': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': 'Structured office key, e.g. senate, house, governor, state_senate or state_assembly. Omit to browse all offices.'}, 'offset': {'type': 'integer', 'default': 0, 'maximum': 100000, 'minimum': 0}, 'district': {'type': 'string', 'maxLength': 30, 'minLength': 1, 'description': 'Source district or precinct designation, where applicable.'}, 'election_type': {'enum': ['general', 'special'], 'type': 'string', 'default': 'general'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_texas_election_reference
Read the versioned 2024 Texas county reference pilot: presidential precinct returns, ballots cast, registered voters and voting methods where supplied. Omit county_fips for available counties and coverage; select a…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'page': {'type': 'integer', 'default': 1, 'maximum': 100000, 'minimum': 1}, 'per_page': {'type': 'integer', 'default': 25, 'maximum': 100, 'minimum': 1}, 'county_fips': {'type': 'string', 'pattern': '^48[0-9]{3}$', 'description': 'A county from the pilot inventory; omit to list coverage.'}, 'precinct_code': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': 'Exact original source precinct code within county_fips. Does not identify a current model precinct.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_usage
OBSERVABILITY — session usage meter: total api_calls (every tool invocation since this server session began), distinct tools used, a by_category breakdown, and the per-tool leaderboard. Note: LLM token counts are not…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 50, 'maximum': 173, 'minimum': 1, 'description': 'Max tools in the by_tool leaderboard.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
get_view
Read the exact map/view state the application renders for a canonical scenario: headline totals, selected geography, modeled feature colors, annotations, primary-calendar playhead, candidate roster, presence, and a…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'view': {'enum': ['result', 'difference'], 'type': 'string', 'description': 'difference uses compare_simulation_id as B and simulation_id as A; returns the zero-centered B-minus-A color scale and exact county/precinct rows.'}, 'cycle': {'type': 'integer', 'maximum': 2040, 'minimum': 2024}, 'grain': {'enum': ['city', 'county', 'precinct'], 'type': 'string', 'description': 'With a state scoped, the grain of the local features returned: "county" (default) or "precinct". Applies to a statewide-level race (senate/governor/exec — its own overrides) AND to a PRIMARY sim scoped to a state (its per-county/precinct share-leader map from primary.feature_shares — mirroring render_view; a state-scoped primary defaults to county instead of the national delegate calendar). Ignored without a state.'}, 'level': {'enum': ['custom', 'president', 'senate', 'house', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'state_senate', 'state_assembly'], 'type': 'string', 'description': "Which map the view renders. Default president (or whatever set_view last scoped). house = HOUSE CONTROL (per-state delegation winners + the 218 banner); state_senate/state_assembly = one state's chamber (state required)."}, 'state': {'type': 'string', 'description': 'Optional postal code or 2-digit FIPS — scope the map to one state. president → its county breakdown; senate/governor/exec → that RACE\'s local county (default) or precinct features from its own overrides (each with modeled margin, baseline_margin, and a basis label: direct_override | county_override | state_override_uniform | presidential_proxy / race_returns) — never the presidential county baseline relabeled. On a PRIMARY sim, scoping to a state returns that state\'s per-COUNTY (default; grain:"precinct" for finer) share-leader features from primary.feature_shares — modeled counties filled by the county primary WINNER\'s candidate color, unmodeled grey — instead of the national delegate calendar (which is the unscoped view).'}, 'version_a': {'type': 'string', 'description': 'Difference comparison: exact saved version of A. Omit only when its latest version matches the live model.'}, 'version_b': {'type': 'string', 'description': 'Difference comparison: exact saved version of B. Omit only when its latest version matches the live model.'}, 'version_id': {'type': 'string', 'description': 'Exact saved version for a custom city model.'}, 'campaign_id_a': {'type': 'string', 'description': 'Optional campaign custody for A when the model belongs to multiple readable campaigns. Does not grant access.'}, 'campaign_id_b': {'type': 'string', 'description': 'Optional campaign custody for B when the model belongs to multiple readable campaigns. Does not grant access.'}, 'simulation_id': {'type': 'string'}, 'expected_hash_a': {'type': 'string', 'description': 'Optional expected immutable version hash for A; mismatches refuse.'}, 'expected_hash_b': {'type': 'string', 'description': 'Optional expected immutable version hash for B; mismatches refuse.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'difference_scale_pp': {'type': 'number', 'maximum': 200, 'description': 'Difference-only symmetric color extent: legend runs from negative this value through zero to positive this value. Omit to fit the largest absolute delta; out-of-scale values are disclosed as clamped.', 'exclusiveMinimum': 0}, 'compare_simulation_id': {'type': 'string', 'description': 'Compare B against simulation_id (A), using D-minus-R margin(B) minus margin(A). Requires one explicit state and county/precinct grain; both saved general-election models must share office/cycle/electorate and be readable.'}, 'expected_version_hash': {'type': 'string'}}, 'additionalProperties': False}
help
Orient an AI client to campaign onboarding through get_campaign_onboarding, user-controlled election modeling, candidate and presidential-primary workflows, supported geography, scenario versions, contextual War Room…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_annotations
List every annotation (pins, highlights, notes) on a scenario.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_calendar_scenarios
List the named calendar orderings saved in your workspace (save_calendar_scenario), newest first, optionally filtered by party. Requires a verified account.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string', 'description': 'Optional party filter.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_candidates
List candidates currently configured for a simulation+level. Defaults: a 2024 presidential sim is Harris (D) / Trump (R); every other cycle and down-ballot level defaults to generic Democrat / Republican until you set…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_contests
Discover contests for a geography and election cycle. Filter general, primary (dem_primary/rep_primary), or all stages; count describes the returned top-level rows. National presidential primaries are discoverable in…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['geo_id'], 'properties': {'cycle': {'type': 'integer', 'description': 'Defaults to the next election year from today.'}, 'stage': {'enum': ['primary', 'general', 'all'], 'type': 'string', 'default': 'all', 'description': 'primary selects the dem_primary and rep_primary variants; general excludes them; all returns both.'}, 'geo_id': {'type': 'string', 'description': '"us" (national), a state as "us-pa" / postal "PA" / FIPS "42", or a district id — all accepted.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/list_contests/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'required': ['cycle', 'geo_id', 'count', 'contests'], 'properties': {'count': {'type': 'integer', 'minimum': 0}, 'cycle': {'type': 'integer'}, 'stage': {'enum': ['general', 'primary', 'all']}, 'geo_id': {'type': 'string'}, 'contests': {'type': 'array', 'items': {'type': 'object', 'required': ['contest_id', 'office', 'geo_id', 'level', 'stage'], 'properties': {'level': {'type': 'string'}, 'stage': {'type': 'string'}, 'geo_id': {'type': 'string'}, 'office': {'type': 'string'}, 'contest_id': {'type': 'string'}}, 'additionalProperties': True}}, 'not_on_ballot': {'type': 'array', 'items': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'office_coverage': {'type': 'object', 'required': [], 'properties': {'status': {'enum': ['complete', 'partial']}, 'offices_checked': {'type': 'array', 'items': {'type': 'string'}}, 'unknown_offices': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': True}, 'unknown_offices': {'type': 'array', 'items': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}}, 'additionalProperties': True}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
list_custom_candidates
List the workspace's custom (write-in) candidates created via create_custom_candidate — the non-canonical field, distinct from the baked candidate registry. Each carries a stable cust_… id, name, party, and color. Pass…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'q': {'type': 'string', 'description': 'Optional case-insensitive substring filter on the candidate name — a typeahead for the add-candidate picker.'}, 'party': {'type': 'string', 'description': 'Optional filter — return only customs of this party (e.g. "D", "R", "I"). Normalized to upper-case letters, matching how create_custom_candidate stores party. Omit to return every party.'}, 'office': {'type': 'string', 'description': 'Optional filter — return only customs whose office contains this text, case-insensitive (e.g. "president"). Customs with no office set are excluded when this filter is used. Omit to return every office.'}, 'exclude_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional — omit these custom-candidate ids (cust_…) from the results, e.g. candidates already on the roster.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_districts
List every district at a given race level. Returns id, name, state. For House: 435 CDs. For state_senate: ~1900 districts. For state_assembly: ~5400 districts.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['level'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'Optional state filter (FIPS or abbr).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_events
WITNESS STREAM (EM-116) — replay the ordered server-side event log of every tool-call (a running then a done event each, carrying category, latency_ms, args_digest, affected{precinct_ids,count}, delta{margin_shift},…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'integer', 'default': 200, 'maximum': 2000, 'minimum': 1}, 'since': {'type': 'integer', 'description': 'Return only events with seq greater than this replay cursor.'}, 'channel': {'enum': ['mcp', 'ui'], 'type': 'string', 'description': 'Filter to a channel ("mcp" = Claude\'s server-side tool calls).'}, 'purpose': {'enum': ['activity', 'first_run'], 'type': 'string', 'default': 'activity', 'description': 'first_run returns bounded successful setup receipts in this workspace, independent of activity volume and ticker retention. Activity paging filters apply only to activity.'}, 'scenario_id': {'type': 'string', 'description': 'Only events touching this scenario/simulation.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_features
List the geographic features (counties, states, districts, etc.) for a given level. Returns id + name + state.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['level'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'limit': {'type': 'integer', 'default': 500, 'maximum': 5000, 'minimum': 1, 'description': 'Page size (max 5000).'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Pagination offset. The response returns count (total), returned, offset, limit, has_more — page through with offset += limit until has_more is false.'}, 'state_in': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Optional state-FIPS filter (e.g. ["06","42"]).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_flipped
List baseline-to-model winner changes. Defaults to state for statewide offices, county for president, and district for house/state legislature. Explicit grain:county|precinct uses canonical integer local votes for a…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level'], 'properties': {'grain': {'enum': ['state', 'county', 'precinct', 'district'], 'type': 'string'}, 'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'limit': {'type': 'integer', 'default': 100, 'maximum': 5000, 'minimum': 1}, 'state': {'type': 'string', 'description': 'One postal code/FIPS for explicit county/precinct enumeration; may be inferred from a saved state race.'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_geo_knowledge
List your workspace's CUSTOM geo-knowledge overlays (the rows set_geo_knowledge has written), newest grain first. The global canonical layer is not listed here — read it per-geography with get_geo_knowledge. Requires a…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'scope': {'type': 'string', 'description': 'Optional filter by level (state/county/precinct).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_levels
List the office levels available to a user-controlled scenario, with typed modelability and coverage status for each level.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_map_comments
List one campaign's map comments on a scenario (oldest-first), each with its campaign_id, anchor, author, body, @mentions, parent_id, and resolved state. Pass campaign_id inside a campaign; only that exact campaign is…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'campaign_id': {'type': 'string', 'description': 'Exact campaign War Room to read. The simulation must be filed under it.'}, 'comment_ids': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 50, 'description': 'Read only these comments (a delta after a live event named them). The reply carries subset:true plus missing[] for ids that are not in this War Room.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'include_resolved': {'type': 'boolean', 'description': 'Include resolved comments (default true).'}}, 'additionalProperties': False}
list_map_themes
MAP THEMES — the audience-preset registry (tk_bb87df86fdbc28): every theme with its semantic color tokens (party safe/likely/lean steps, tossup, missing, independent, selection, canvas). The SAME registry the live map…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_modeled_candidates
PORTFOLIO — every candidate or elected official you are modeling, unioned across ALL of your simulations and every level, deduped by name+party. One call returns the roster behind the candidate portals: each entry…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_precinct_overrides
List every precinct override stored in a simulation. Useful for AI clients to inspect what state they've already mutated.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_presence
WHO IS LIVE in this workspace right now — every browser tab and MCP agent with a presence heartbeat in the last ~45s, one row per actor: {actor, name, color, scenario_id (the sim they have open / are bound to), level,…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'scenario_id': {'type': 'string', 'description': 'Optional — only presence rows on this sim.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_primary_calendar
Read the 2028 primary calendar with source dates, schedule certainty, modeled delegate coverage, missing jurisdictions, and threshold basis. New calendars include the six DNC-approved early dates; other unverified…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['party'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'simulation_id': {'type': 'string', 'description': "Optional. If given (and party=D), returns the sim's user-defined Dem calendar when one is set."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_races
List the Races (contest workspaces) in this workspace, with scenario counts.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_scenarios
Page saved scenarios/simulations in this workspace by updated_at descending and scenario_id ascending, without version blobs. Returns scenario_id, name, level, cycle, contest_id, race_id, tags, durable_id, published…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'tags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Return only scenarios carrying any of these tags.'}, 'limit': {'type': 'integer', 'default': 100, 'maximum': 500, 'minimum': 1}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Use previous next_offset with unchanged tags and limit. Ordered by updated_at descending, scenario_id ascending. Restart at 0 after inventory changes.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_scenario_versions
The append-only version chain for a scenario, newest last, with per-version summary + top_line. The record of how the read on the contest evolved.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'limit': {'type': 'integer', 'default': 50, 'maximum': 200, 'minimum': 1}, 'scenario_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_siblings
List scenario branches that share a common parent so user-authored alternatives remain navigable and comparable.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'include_self': {'type': 'boolean', 'description': 'Include the queried sim itself in the siblings list (marked is_self:true). Default true.'}, 'simulation_id': {'type': 'string', 'description': 'The sim whose siblinghood you want. Its forked_from (if any) selects the group; otherwise its own id is the group key (its direct children).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_simulations
List saved simulations in this workspace (id, name, level, cycle, mode, contest_id, last-modified; rows stamped with an identity also carry created_by/updated_by member user_ids). Optional filters narrow a large…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'q': {'type': 'string', 'description': 'Case-insensitive substring match on the simulation name.'}, 'mode': {'type': 'string', 'description': 'Filter by president modeling mode: general | dem_primary_2028 | rep_primary_2028.'}, 'cycle': {'type': 'integer', 'description': 'Filter by election cycle year (e.g. 2028).'}, 'level': {'type': 'string', 'description': 'Filter by office/level (e.g. president, senate, house, governor).'}, 'limit': {'type': 'integer', 'maximum': 500, 'minimum': 1, 'description': 'Max rows to return (pagination page size).'}, 'owner': {'type': 'string', 'description': 'Filter to sims created by this member user_id (the stable UUID from list_members) — "my sims" / "Dana\'s sims". Sims saved before identity stamping have no owner and never match.'}, 'offset': {'type': 'integer', 'minimum': 0, 'description': 'Rows to skip before returning (pagination cursor).'}, 'race_id': {'type': 'string', 'description': 'Filter to sims bound to this race_id.'}, 'contest_id': {'type': 'string', 'description': 'Filter to sims bound to this contest_id.'}, 'updated_since': {'type': 'string', 'description': 'Only sims modified at or after this ISO timestamp/date.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_threads
The War Room as ONE campaign-scoped feed of THREADS — full discussion context in a single call. Pass campaign_id inside a campaign; omit it for scenario-global discussion only. Every content object is a thread: the…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'campaign_id': {'type': 'string', 'description': 'Exact campaign War Room to read. The simulation must be filed under it.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
list_workspace_comments
List contextual War Room discussion across the active workspace, optionally limited to one campaign. Deep links preserve the exact campaign, scenario, geography, and selected-map context.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Max items (default 200, max 500).'}, 'since': {'type': 'string', 'description': 'ISO timestamp — only items created at/after this.'}, 'campaign_id': {'type': 'string', 'description': 'Optional exact campaign feed. Excludes comments owned by other campaign containers even when they share a scenario.'}, 'include_notes': {'type': 'boolean', 'description': 'Include annotations/notes (default true).'}, 'unresolved_only': {'type': 'boolean', 'description': 'Only open (unresolved) comments.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
lookup_address
Resolve a US street address, ZIP, state, or U.S. House district and show workspace campaigns covering the result. Street addresses return a geocoded point and containing districts, with a precinct when coverage exists.…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['address'], 'properties': {'address': {'type': 'string', 'description': 'A full street address ("123 Main St, Dallas, TX"), a 5-digit ZIP, a district code ("NC-4", "AK-AL"), a state name/abbreviation, or a canonical state/House geography ID.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'include_officials': {'type': 'boolean', 'default': True, 'description': 'Attach the sitting officeholder for each resolved seat (from the committed legislator file).'}}, 'additionalProperties': False}
manage_billing
BILLING — returns {portal_url} to the Stripe Customer Portal, where the USER can update payment, switch plan, or cancel (opened in a browser). Requires a verified account that already has a subscription.
Destructive Open world
Input schema
{'type': 'object', 'properties': {'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
optimize_calendar
RANK primary-calendar orderings for a candidate against the sim's modeled per-state delegate hauls — which calendar order best helps candidate X. DETERMINISTIC and EXPLAINED, with NO invented probabilities: the total…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'candidate_id'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'early_k': {'type': 'integer', 'description': 'How many opening contests count as "early" for most_early_momentum (default 4 — the carve-outs).'}, 'objective': {'enum': ['earliest_clinch', 'earliest_lead', 'most_early_momentum'], 'type': 'string', 'description': 'Ranking objective. Default earliest_clinch.'}, 'candidate_id': {'type': 'string', 'description': 'The candidate to optimize for — a roster id or name.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
precincts_in_district
Page precincts whose centroid falls inside the district boundary, in precinct-id order. Returns at most 100 rows plus total_precincts, returned, has_more and next_offset. Repeat with next_offset and unchanged filters…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['level', 'district_id'], 'properties': {'level': {'enum': ['house', 'state_senate', 'state_assembly'], 'type': 'string'}, 'limit': {'type': 'integer', 'default': 100, 'maximum': 100, 'minimum': 1}, 'state': {'type': 'string', 'description': 'Hint state to restrict the precinct search (FIPS or abbr). Strongly recommended for perf.'}, 'detail': {'enum': ['full', 'ids'], 'type': 'string', 'default': 'full'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Use the previous next_offset with unchanged district and filters.'}, 'district_id': {'type': 'string', 'description': 'External id of the district (e.g. "4207" for PA-07).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
primary_batch_edit
ATOMIC batch-edit transaction for a PRIMARY scenario — validate, preview, apply, and roll back a whole SET of candidate / share / calendar edits as ONE transaction. Pass edits:[{op, ...}, …] where each entry carries…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'edits'], 'properties': {'edits': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Ordered heterogeneous list of primary edits, each an object {op, …opArgs}. op is one of set_primary_shares, set_primary_county_shares, set_primary_precinct_shares, set_primary_candidates, set_primary_asof, clear_primary_shares, define_dem_calendar, clear_dem_calendar, set_primary_grain_pref, set_primary_demo_levers. The remaining fields are exactly the args that single-edit tool takes, e.g. {"op":"set_primary_shares","party":"d","state":"SC","shares":{"newsom":31,"harris":24}}. Applied in array order onto the working copy.'}, 'force': {'type': 'boolean', 'description': 'Apply despite soft WARNINGS (just-over-100 totals, viability flags, mode/geo/calendar notes). Still BLOCKS on hard errors (unknown candidate, malformed edit, shares over 100.5). Default false.'}, 'party': {'type': 'string', 'description': "Default party (d/r) for edits that omit their own party. Defaults to the sim's primary party."}, 'dry_run': {'type': 'boolean', 'description': 'DEFAULT true — preview only: returns before/after/delta/warnings/errors/viability_flags and writes NOTHING. Pass false to actually apply.'}, 'simulation_id': {'type': 'string', 'description': 'The scenario/simulation to edit (sim_…).'}, 'setup_evidence': {'type': 'object', 'description': 'For automatic public-profile initialization: {kind:"primary_profile_start",model:"geographic-context-v1",profile_version:"2026-09-05.v1",ranking:[{id,name}]}. Use the same ordered ranking; the server validates the catalog and final roster/shares before one atomic save. Dry runs return proposed evidence; only applied evidence with version identity confirms success.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'checkpoint_label': {'type': 'string', 'description': 'Optional label for the pre-batch rollback checkpoint version created on apply.'}, 'expected_version_hash': {'type': 'string', 'pattern': '^v1:[0-9a-f]{32}$', 'description': 'Copy expected_version_hash from the setup dry run to refuse overwriting an intervening edit. Exact already-applied replay returns the existing version.'}}, 'additionalProperties': False}
primary_narrative
DATA-ONLY narrative package for a presidential-primary scenario — the STORY of the race as structured data an AI client turns into its own storyboard, press piece, memo, or social thread (electionsmcp returns the…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Which primary to narrate. Defaults to the scenario's own primary party (dem_primary_2028 → D, rep_primary_2028 → R)."}, 'audience': {'enum': ['press', 'social', 'internal', 'general'], 'type': 'string', 'default': 'general', 'description': 'Framing hint the client can use when composing (press briefing, social thread, internal memo, general). Affects only the headline phrasing; all numbers are identical across audiences.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
primary_state_effective
ONE STATE's primary exactly as the delegate count sees it — the per-state READ view of roll_up_primary. When a state is modeled at COUNTY or PRECINCT grain, the statewide sliders no longer set its number: the state's…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'state'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Optional — defaults to this scenario's own primary party (from its dem_primary_2028 / rep_primary_2028 mode)."}, 'state': {'type': 'string', 'description': 'State FIPS ("12") or 2-letter abbr ("FL").'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
provision_customer
CUSTOMER SETUP — run (or RESUME) the checkpointed provisioning saga for a setup session you own: exactly one workspace with its client type, owner membership, roster record and the exact versioned map binding; returns…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['setup_id'], 'properties': {'setup_id': {'type': 'string'}, 'custom_campaign': {'type': 'object', 'required': ['office_label', 'jurisdiction_name', 'state', 'cycle'], 'properties': {'cycle': {'type': 'integer', 'maximum': 2200, 'minimum': 1900}, 'state': {'type': 'string', 'pattern': '^[A-Z]{2}$'}, 'office_label': {'type': 'string', 'maxLength': 100, 'minLength': 2}, 'jurisdiction_name': {'type': 'string', 'maxLength': 160, 'minLength': 2}}, 'description': 'Explicit custom setup identity for recovery. Existing campaign/model identities are never overwritten. Read custom_campaign_readiness before submitting.', 'additionalProperties': False}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
react_map_comment
Toggle an emoji reaction on a War Room chat message (map comment): adds the caller to reactions[emoji] if absent, removes them if present. reactions = { "<emoji>": ["<email/agent>", …] }. Live (~1s).
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'comment_id', 'emoji'], 'properties': {'emoji': {'type': 'string', 'description': 'The emoji to toggle, e.g. "👍".'}, 'comment_id': {'type': 'string'}, 'campaign_id': {'type': 'string', 'description': 'Campaign that owns the comment; omit only for a scenario-global comment.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
remove_annotation
Remove a single annotation by its id.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'annotation_id'], 'properties': {'annotation_id': {'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
remove_candidate
Remove one candidate from a simulation+level roster (and drop them from any feature overrides). Cannot remove the last candidate.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'candidate_id'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'candidate_id': {'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
remove_map_comment
Delete a map comment by id (soft-delete, so threads stay intact). Only the comment's author can delete it.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'comment_id'], 'properties': {'comment_id': {'type': 'string'}, 'campaign_id': {'type': 'string', 'description': 'Campaign that owns the comment; omit only for a scenario-global comment.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
rename_simulation
Rename a simulation/scenario — give the map a real title instead of the stuck default. Sets the name and appends a metadata version to the audit chain. Accepts simulation_id or scenario_id (same thing). A focused alias…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The new title (non-empty).'}, 'scenario_id': {'type': 'string', 'description': 'Alias of simulation_id.'}, 'simulation_id': {'type': 'string', 'description': 'The sim/scenario to rename (alias: scenario_id).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
render_chart
share_comparison compares candidate shares for two saved versions of one model or two same-contest statewide general-election models. Returns canonical integer candidate votes, all-ballot shares, D-minus-R margins,…
Read only Idempotent
Input schema
{'type': 'object', 'anyOf': [{'required': ['simulation_id']}, {'required': ['simulation_id_a'], 'properties': {'type': {'const': 'share_comparison'}}}], 'required': ['type'], 'properties': {'asof': {'type': ['integer', 'null'], 'description': 'For the primary charts — evaluate the race at this calendar checkpoint (contests counted), the same asof roll_up_primary takes: standings/clinch totals, the momentum timeline\'s end, and the calendar strip\'s counted set all stop there. Omit to use the scenario\'s STORED playhead (set_primary_asof) when one is set, else the full projected calendar. The response echoes the effective asof + contests_counted so a caption like "Through FL" can be verified against the data (tk_2840156e3f1d8b).'}, 'type': {'enum': ['delegate_standings', 'clinch_dial', 'delegate_momentum', 'calendar_strip', 'ranking_board', 'swing_bars', 'chamber_control', 'seat_hemicycle', 'decisive_seats', 'share_comparison'], 'type': 'string', 'description': 'Which widget. share_comparison = saved candidate shares before/after, with paired version anchors and one state. Primary: delegate_standings (bars+clinch), clinch_dial (gauge), delegate_momentum (lines), calendar_strip (calendar grid), ranking_board (portrait tiles ranked by delegates + per-candidate clinch state/date; response carries the rows as data). General: swing_bars (state Δ vs 2024), chamber_control (down-ballot D/R scorecard), seat_hemicycle (the 1200×630 parliament-arch CONTROL CARD — every seat a dot, majority tick, big D/R counts), decisive_seats (the 1200×630 closest-races board with margin-band ratings + FLIP tags).'}, 'cycle': {'type': 'integer', 'description': "Election cycle for seat_hemicycle / decisive_seats (defaults to the sim's cycle, else 2026) — drives the Senate class + governor calendar."}, 'level': {'enum': ['president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string', 'description': 'share_comparison only: statewide office; defaults to the saved scope. Both versions must match office, state, cycle and general-election stage.'}, 'party': {'enum': ['d', 'r'], 'type': 'string', 'description': "For the primary charts — which party's race (defaults to the sim's primary mode)."}, 'share': {'type': 'boolean', 'description': 'PUBLISH to a hostable URL: mints a share token and returns share.hosted_image_url / hosted_svg_url that resolve for ANYONE (cross-workspace, embeddable). Default false. Revoke with revoke_share(token).'}, 'state': {'type': 'string', 'description': 'State postal or FIPS. Required for share_comparison and state-leg seat_hemicycle/decisive_seats.'}, 'style': {'type': 'object', 'properties': {'ink': {'type': 'string', 'pattern': '^#[0-9a-fA-F]{6}$', 'description': 'Main text color, as six-digit hex.'}, 'font': {'enum': ['sans', 'serif', 'mono'], 'type': 'string', 'description': 'Portable font family. Custom fonts, URLs, and CSS are not accepted.'}, 'accent': {'type': 'string', 'pattern': '^#[0-9a-fA-F]{6}$', 'description': 'Heading and threshold color, as six-digit hex. Candidate colors stay with the scenario roster.'}, 'background': {'type': 'string', 'pattern': '^#[0-9a-fA-F]{6}$', 'description': 'Canvas color, as six-digit hex.'}}, 'description': 'Optional brand overrides for the supported themed charts. Does not remove attribution or change candidate colors or model data.', 'additionalProperties': False}, 'theme': {'enum': ['control', 'analyst', 'field', 'civic', 'accessible', 'broadcast', 'terrain', 'print'], 'type': 'string', 'description': 'Chart audience palette, using the map-theme registry. Supported by primary charts, swing_bars and chamber_control. Default control.'}, 'title': {'type': 'string', 'description': 'Optional eyebrow/title for the chart.'}, 'clinch': {'type': 'boolean', 'description': "ranking_board only — show each candidate's clinch line on the tiles (CLINCHES <state> · <date>, or how many delegates short). Default true; pass false for a name+delegates-only board. The response's rows[] carry the clinch data either way."}, 'format': {'enum': ['svg', 'png'], 'type': 'string', 'description': 'Image format. Default svg (png needs the resvg renderer; degrades to svg if absent).'}, 'office': {'enum': ['house', 'senate', 'governor', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'For seat_hemicycle / decisive_seats — which chamber (default house). state_senate/state_assembly also need state.'}, 'version_a': {'type': 'string', 'description': 'Difference comparison: exact saved version of A. Omit only when its latest version matches the live model.'}, 'version_b': {'type': 'string', 'description': 'Difference comparison: exact saved version of B. Omit only when its latest version matches the live model.'}, 'overlay_race': {'type': 'object', 'properties': {'state': {'type': 'string'}, 'office': {'type': 'string'}, 'district': {'type': 'string'}}, 'description': 'The single race to swap in from overlay_from_simulation_id: {office, state, district}. office must match the card\'s chamber; statewide offices need only state; house takes the district GEOID ("0604") or the bare number with its state; state chambers take the district external_id.', 'additionalProperties': False}, 'campaign_id_a': {'type': 'string', 'description': 'Optional campaign custody for A when the model belongs to multiple readable campaigns. Does not grant access.'}, 'campaign_id_b': {'type': 'string', 'description': 'Optional campaign custody for B when the model belongs to multiple readable campaigns. Does not grant access.'}, 'simulation_id': {'type': 'string', 'description': 'Scenario to render; for share_comparison this is A, or the single model with version_a/version_b.'}, 'highlight_race': {'type': 'object', 'properties': {'state': {'type': 'string'}, 'office': {'type': 'string'}, 'district': {'type': 'string'}}, 'description': 'Mark one race on the card (same shape as overlay_race): its dot wears an amber ring on seat_hemicycle, and decisive_seats always includes it on the board with its true closest-races rank.', 'additionalProperties': False}, 'share_ttl_days': {'type': 'number', 'description': 'Days the shared URL stays live (default 90, max 365). Only with share:true.'}, 'expected_hash_a': {'type': 'string', 'description': 'Optional expected immutable version hash for A; mismatches refuse.'}, 'expected_hash_b': {'type': 'string', 'description': 'Optional expected immutable version hash for B; mismatches refuse.'}, 'simulation_id_a': {'type': 'string', 'description': 'share_comparison only: A model, alternative to simulation_id. Conflicting aliases refuse.'}, 'simulation_id_b': {'type': 'string', 'description': 'share_comparison only: B model in the same contest. Omit for two explicit versions of A.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'compare_simulation_id': {'type': 'string', 'description': 'share_comparison only: alias for simulation_id_b.'}, 'context_simulation_id': {'type': 'string', 'description': "seat_hemicycle / decisive_seats only — compute the WHOLE chamber rollup from THIS scenario (a linked national/statewide view's scenario) instead of simulation_id. Pair with overlay_from_simulation_id + overlay_race to swap exactly one race's result in from a campaign's scenario: one seat changes hands, the counts move by that seat, nothing else. The two scenarios must model the same cycle and be general-election models — a disagreement is a typed refusal (context_cycle_mismatch / context_mode_mismatch), never a silent mix."}, 'overlay_from_simulation_id': {'type': 'string', 'description': "seat_hemicycle / decisive_seats only — the scenario that supplies the ONE overlaid race's modeled result. Travels with overlay_race; passing one without the other is refused (overlay_incomplete)."}}, 'additionalProperties': False}
render_view
A headless server-rendered IMAGE of the map — the rendered view a viewer sees, as SVG or PNG, WITHOUT a browser (tk_0b6d3501 P2). For a scenario + level (president | senate | house | governor | the execs) it draws the…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'asof': {'type': ['integer', 'null'], 'description': "PRIMARY sims — render the delegate banner/standings AS OF this calendar checkpoint (contests counted; the same asof roll_up_primary / render_chart take). Omit to honor the scenario's STORED playhead (set_primary_asof) so the served image matches the viewer's scoreboard; null = the full projected calendar. The county/precinct share-leader FILLS are the scenario's stored shares and do NOT move with asof — only the delegate banner does. The primary mode + party are auto-detected from the sim's mode (dem_primary_2028 / rep_primary_2028); there is no mode/party arg. Ignored for general-election renders (the response echoes the effective asof when it applied)."}, 'view': {'enum': ['result', 'swing', 'difference'], 'type': 'string', 'description': '"result" (default) = the outcome map; "swing" = colour by margin CHANGE vs the baseline (where the scenario MOVES the map). "difference" = margin(B)-margin(A), requires compare_simulation_id and one explicit state; supports saved general-election county/precinct maps, with a zero-centered in-frame legend. It refuses unallocated whole-race edits. Result/swing work at NATIONAL scope (president: every state by its swing), STATE scope (president county map AND the statewide-race local county/precinct maps), and CUSTOM maps.'}, 'grain': {'enum': ['county', 'precinct', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'When scoped to ONE state (state/geo_id/feature_id), the geographic grain to render: "county" (default) per-county; "precinct" per-precinct (finest, within-county) — both work at president level AND at the statewide-race levels (senate/governor/exec, which render that race\'s own overrides/fold, tk_3c0569e9b02541); or a DISTRICT layer (president level only) — "house" = U.S. congressional districts (us-cd119), "state_senate" = state-senate districts (us-sldu), "state_assembly" = state-house districts (us-sldl). Districts are fetched on-demand and filled by their vote baseline (House: county→CD presidential aggregation; state-leg: RoutPoint 2024 returns where covered, else presidential-lean) + the scenario\'s district overrides (set_performance at that level). A few states lack a layer and fall back to county.'}, 'level': {'enum': ['president', 'senate', 'house', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string', 'description': 'Which map to render. Default president. house = HOUSE CONTROL: states shaded by delegation majority, D/R seat tally, 218 banner (for one state\'s district map use grain:"house" with a state scope instead).'}, 'share': {'type': 'boolean', 'description': 'PUBLISH this map to a hostable URL: mints a share token and returns share.hosted_image_url / hosted_svg_url + a public page_url (/f/<token>) that resolve for ANYONE — cross-workspace, embeddable in an <img> or iframe. Default false (URLs are owner/public-scoped only). Anyone with the link sees the map; revoke with revoke_share(token).'}, 'state': {'type': 'string', 'description': 'Optional — scope the image to a state (postal "NC" or 2-digit FIPS). president → that state\'s per-county choropleth; senate/governor/exec → that RACE\'s LOCAL county map from its own overrides (5-digit county edits + its state override as uniform swing) over the labeled inherited-proxy baseline — never a presidential map substituted (tk_3c0569e9b02541). Other levels ring the state on the national map.'}, 'theme': {'type': 'string', 'description': 'MAP THEME preset for the rendered image (list_map_themes: control | analyst | field | civic | accessible | broadcast | terrain) — the SAME token resolution the live wall uses, so a civic-themed report map and the analyst on-screen map disagree only in paint, never in data. Omit = the classic dark card.'}, 'title': {'type': 'string', 'description': 'CUSTOM MAP: a title for the card (e.g. "Rust Belt swing"). Defaults to the state list (or the region group / region name).'}, 'format': {'enum': ['svg', 'png'], 'type': 'string', 'description': 'Image format. Default svg (png needs the resvg renderer on the host; degrades to svg if absent).'}, 'geo_id': {'type': 'string', 'description': 'Optional — a geo slug like "us-nc" to scope to that state.'}, 'layers': {'type': 'object', 'properties': {'highlights': {'type': 'boolean'}}, 'description': 'Draw saved highlight annotations on matching visible geography. Omit to honor set_view layers.highlights (default true); false hides them for this export only. Pins and notes are not rendered.', 'additionalProperties': False}, 'region': {'type': 'string', 'description': 'CUSTOM MAP — with region_group, render exactly ONE region in the group (its slug).'}, 'states': {'type': 'array', 'items': {'type': 'string'}, 'description': 'CUSTOM MAP (president): a list of states (postal "PA" or 2-digit FIPS) → a cropped county choropleth of just those states\' counties, in their real relative positions, zoomed to the region. Combine with features[]. e.g. ["PA","OH","MI"] for a Rust Belt map.'}, 'features': {'type': 'array', 'items': {'type': 'string'}, 'description': 'CUSTOM MAP (president): an explicit list of geo_ids to include — county FIPS (5-digit), state FIPS (2-digit), or "us-xx". Hand-pick any counties across states; the map crops to exactly them. Combine with states[].'}, 'version_a': {'type': 'string', 'description': 'Difference comparison: exact saved version of A. Omit only when its latest version matches the live model.'}, 'version_b': {'type': 'string', 'description': 'Difference comparison: exact saved version of B. Omit only when its latest version matches the live model.'}, 'feature_id': {'type': 'string', 'description': 'Optional — a state fips (37) or county/precinct id (37xxx) to scope to its state.'}, 'region_group': {'type': 'string', 'description': 'CUSTOM MAP — a saved workspace map region-group slug. Expands to its member counties or states; add region to render one named region. Ignored if states[] or features[] are passed.'}, 'campaign_id_a': {'type': 'string', 'description': 'Optional campaign custody for A when the model belongs to multiple readable campaigns. Does not grant access.'}, 'campaign_id_b': {'type': 'string', 'description': 'Optional campaign custody for B when the model belongs to multiple readable campaigns. Does not grant access.'}, 'simulation_id': {'type': 'string'}, 'share_ttl_days': {'type': 'number', 'description': 'Days the shared URL stays live (default 90, max 365). Only with share:true.'}, 'expected_hash_a': {'type': 'string', 'description': 'Optional expected immutable version hash for A; mismatches refuse.'}, 'expected_hash_b': {'type': 'string', 'description': 'Optional expected immutable version hash for B; mismatches refuse.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'comparison_layout': {'enum': ['difference', 'triptych'], 'type': 'string', 'description': 'Difference-only 1200x630 card: one B-minus-A map (default), or the same-grain A | B | B-minus-A maps with explicit legends.'}, 'difference_scale_pp': {'type': 'number', 'maximum': 200, 'description': 'Difference-only symmetric color extent: legend runs from negative this value through zero to positive this value. Omit to fit the largest absolute delta; out-of-scale values are disclosed as clamped.', 'exclusiveMinimum': 0}, 'compare_simulation_id': {'type': 'string', 'description': 'Compare B against simulation_id (A), using D-minus-R margin(B) minus margin(A). Requires one explicit state and county/precinct grain; both saved general-election models must share office/cycle/electorate and be readable.'}}, 'additionalProperties': False}
reset_overrides
Clear all manual overrides — the "reset to baseline" action. Pass level to reset just that level; omit to reset every level. include_precincts (default true) also clears precinct overrides.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer', 'custom'], 'type': 'string'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'The last-read updated_at token; custom model writes refuse stale edits.'}, 'include_precincts': {'type': 'boolean', 'default': True}}, 'additionalProperties': False}
resolve_candidate
WHO holds or runs for WHAT — turn a candidate/officeholder name into their seat + next race. Given a name (full, last-name, or a registry alias — "Lauren Boebert", "Boebert"), returns the person(s) who match with their…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'A candidate or officeholder name — full ("Lauren Boebert"), last-name ("Boebert"), or any registry alias. Matching folds free-typed names onto the canonical person.'}, 'cycle': {'type': 'integer', 'description': 'Optional — keep only matches whose next_race is in this cycle (e.g. 2026).'}, 'limit': {'type': 'integer', 'default': 8, 'maximum': 25, 'minimum': 1, 'description': 'Max people to return when a name is ambiguous (default 8).'}, 'party': {'type': 'string', 'description': 'Optional — keep only matches of this party (D/R/I), normalized by leading letter. For a stage/party-scoped picker.'}, 'office': {'type': 'string', 'description': 'Optional — keep only matches whose current OR next-race office matches (house, senate, governor, state_senate, state_assembly, …); the "us_" prefix is optional ("house" == "us_house").'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
resolve_geography
Turn a place name or shorthand into its canonical geo_id — resolve natural-language or structured location input. Handles "CA-03"/"NC-4" (congressional districts), bare state names/abbreviations, "<County> County…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['query'], 'properties': {'year': {'type': 'integer', 'description': 'Disambiguates post-redistricting boundaries; defaults to current cycle.'}, 'query': {'type': 'string', 'description': '"CA-03", "El Dorado County CA", "the 4th state senate district in California", "Pennsylvania"'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
resolve_identity
Read a reviewed public candidate identity and its exact registry, ballot and election-result aliases, per-race parties and linked evidence. source_id resolves an exact ID; name matches a complete reviewed name (case…
Read only Idempotent
Input schema
{'type': 'object', 'oneOf': [{'required': ['source_id']}, {'required': ['name']}, {'required': ['q']}], 'properties': {'q': {'type': 'string', 'maxLength': 256, 'minLength': 1, 'description': 'Name substring for discovery only. Results require selecting an exact source_id before binding.'}, 'name': {'type': 'string', 'maxLength': 256, 'minLength': 1, 'description': 'Complete reviewed name. A surname or similar spelling never automatically merges people.'}, 'limit': {'type': 'integer', 'default': 20, 'maximum': 50, 'minimum': 1, 'description': 'Maximum discovery matches, only with q.'}, 'race_id': {'type': 'string', 'maxLength': 256, 'minLength': 1, 'description': 'Optional exact source race for identity disambiguation. Does not choose a comparison race or infer cross-year continuity.'}, 'namespace': {'enum': ['registry', 'historical_source_candidate', 'tx_sos_ballot', 'routpoint_candidate', 'sitting_member'], 'type': 'string', 'description': 'Optional exact alias namespace; valid only with source_id.'}, 'source_id': {'type': 'string', 'maxLength': 256, 'minLength': 1, 'description': 'Exact reviewed registry or source-record alias. Numeric RoutPoint IDs remain strings; qualify with namespace and race_id when ambiguous.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
resolve_map_comment
Mark a map comment resolved (closed), like resolving a Google-Docs comment — or reopen it with resolved:false. Records who resolved it.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'comment_id'], 'properties': {'resolved': {'type': 'boolean', 'description': 'true = resolve (default), false = reopen.'}, 'comment_id': {'type': 'string'}, 'campaign_id': {'type': 'string', 'description': 'Campaign that owns the comment; omit only for a scenario-global comment.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
restore_version
Set the scenario's working state back to a prior version's payload, and return that complete per-precinct `state` (so the map redraws to the exact configuration) plus the hash chain. Append-only: this records a NEW…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id', 'version_id'], 'properties': {'version_id': {'type': 'string'}, 'scenario_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'The last-read updated_at token; custom model writes refuse stale edits.'}}, 'additionalProperties': False}
resume_setup
CUSTOMER SETUP — the authoritative state of a setup session after auth, checkout or reload: status, step, client type, setup_scope, geography, owner linkage. A signed-in caller claims an unowned session…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['setup_id'], 'properties': {'setup_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
revision_ladder
Revision ladder L2 as DATA (not a render): render-ready before/after delta so the CLIENT visualizes it. Two modes — VERSION: {scenario_id, version_a, version_b} returns per-geo/candidate/level rows (before, after,…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'grain': {'enum': ['county', 'precinct'], 'type': 'string', 'description': 'Two-sim canonical outcome rows (margin_a, margin_b, delta_pp, winners, ballots, flipped); uses exact saved version_a/version_b, or latest matching saved heads. Without grain, retains the input-difference ladder.'}, 'level': {'type': 'string', 'description': 'Two-sim mode: office/level to tally (e.g. president, senate, house, governor).'}, 'limit': {'type': 'integer', 'default': 500, 'maximum': 2000, 'minimum': 1, 'description': 'Maximum geo/candidate rows per page (default 500, maximum 2000); candidate totals and full counts are not paged.'}, 'state': {'type': 'string', 'description': 'With grain in two-sim mode, one explicit state postal code or FIPS.'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Continue with geo_page.next_offset; restart at zero if either live model context changes.'}, 'version_a': {'type': 'string', 'description': 'Version mode: the "before" version_id.'}, 'version_b': {'type': 'string', 'description': 'Version mode: the "after" version_id.'}, 'scenario_id': {'type': 'string', 'description': 'Version mode: the scenario whose two versions to compare.'}, 'campaign_id_a': {'type': 'string', 'description': 'Optional campaign custody for A when the model belongs to multiple readable campaigns. Does not grant access.'}, 'campaign_id_b': {'type': 'string', 'description': 'Optional campaign custody for B when the model belongs to multiple readable campaigns. Does not grant access.'}, 'expected_hash_a': {'type': 'string', 'description': 'Optional expected immutable version hash for A; mismatches refuse.'}, 'expected_hash_b': {'type': 'string', 'description': 'Optional expected immutable version hash for B; mismatches refuse.'}, 'simulation_id_a': {'type': 'string', 'description': 'Two-sim mode: the "before" simulation.'}, 'simulation_id_b': {'type': 'string', 'description': 'Two-sim mode: the "after" simulation.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
revoke_share
Revoke a previously-minted public share token. The /share/<token> URL stops resolving.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['token'], 'properties': {'token': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
roll_up_primary
The running delegate count — OR, for a race-scoped downballot sim, that race's own share rollup. DOWNBALLOT (tk_2110d54c1d0871): when the scenario is race-scoped to a non-presidential office (set_race_scope…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'asof': {'type': ['integer', 'null'], 'description': 'Optional. Contests counted; omit/null = full calendar.'}, 'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'Optional. Scope the read to ONE contest (postal/FIPS/name): returns a `state` block with that contest\'s calendar position, modeling grain, and delegate allocation — and when the state sits BEYOND this call\'s asof, the response says so EXPLICITLY (top-level excluded_by_asof:true + contest_index + current_asof, never a silent absence). The "is FL on the map?" one-call answer.'}, 'by_district': {'type': 'boolean', 'description': 'Optional (Democratic proportional only). Also return district_allocation: the higher-fidelity split where ~65% of pledged delegates are awarded PER congressional district with viability applied per-CD (the district pool spread across a state\'s CDs by 2024 Democratic vote strength via largest-remainder), and the remaining ~35% (at-large + PLEO) allocated from the statewide share. Per-CD shares layer any set_primary_precinct_shares modeling over the statewide baseline. Returns standings (with district_delegates/statewide_delegates per candidate), per-state by_cd breakdowns, a method_note + rounding_note, and — where a state has no CD baseline — a clear degrade flag (the delegation falls back to statewide allocation) instead of silently mis-allocating. IMPORTANT: this block is DIAGNOSTIC ONLY (authoritative:false). The top-level standings remain the authoritative count — the statewide-method allocation every other tool (narratives, publish, Monte Carlo, charts) reads — and the response carries authoritative:"statewide" to say so. Both methods allocate the identical number of delegates per state, but per-CD rounding + per-CD viability legitimately land a few delegates on different candidates than one statewide rounding; district_allocation.delta[] lists the per-candidate difference (district method minus authoritative statewide). Do not mix the two columns in one count.'}, 'simulation_id': {'type': 'string'}, 'include_states': {'type': 'boolean', 'description': 'Optional. Also return by_state[]: per voted contest — delegates each candidate won, plus eff_shares (the effective per-state candidate shares after the county/precinct rollup), modeled_by ("precinct"|"county"|"state"|null — which grain drove the state), modeled_count, and coverage_pct (grain-relative % of 2024 turnout modeled, or null). For must-win / anchor-state analysis and source/coverage display. When this call\'s asof cuts off states that HAVE durable modeling, the response also carries excluded_modeled_states[] + current_asof so those states are named, never silently missing from by_state.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/roll_up_primary/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'required': ['party', 'total_delegates', 'delegates_to_win', 'allocated', 'uncalled', 'contests_counted', 'contests_total', 'standings', 'context'], 'properties': {'rule': {'type': 'string'}, 'party': {'type': 'string'}, 'context': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'by_state': {'type': 'array', 'items': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'uncalled': {'type': 'number'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'allocated': {'type': 'number'}, 'standings': {'type': 'array', 'items': {'type': 'object', 'required': ['candidate_id', 'delegates'], 'properties': {'name': {'type': 'string'}, 'delegates': {'type': 'number'}, 'candidate_id': {'type': 'string'}}, 'additionalProperties': True}}, 'contests_total': {'type': 'integer', 'minimum': 0}, 'total_delegates': {'type': 'number'}, 'contests_counted': {'type': 'integer', 'minimum': 0}, 'delegates_to_win': {'type': 'number'}}, 'additionalProperties': True}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
roll_up_race
Roll up precincts to a race outcome under the current simulation. Sums baseline votes for all precincts inside the district boundary, applying overrides in precedence order: a per-precinct override wins, else…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'district_id'], 'properties': {'level': {'enum': ['custom', 'president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string'}, 'region': {'type': 'string', 'description': "Optional — with region_group, scope to exactly ONE region in the group (its slug), rolling up only that region's member counties."}, 'district_id': {'type': 'string', 'description': 'District external id (for level=president/senate/governor, the state). EM-056: accepts a resolve_geography handle in any format — the slug "us-pa", postal "PA", or FIPS "42" — and also reads geo_id/state as aliases.'}, 'region_group': {'type': 'string', 'description': 'Optional saved county-grain workspace map region-group slug. Returns one modeled race rollup per named region.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
Output schema
{'$id': 'https://www.electionsmcp.com/schemas/mcp/roll_up_race/v1', 'type': 'object', 'oneOf': [{'allOf': [{'type': 'object', 'required': ['error'], 'properties': {'error': {'type': 'string'}, 'result_status': {'enum': ['error', 'unavailable']}}, 'additionalProperties': True}]}, {'allOf': [{'not': {'required': ['error']}}, {'type': 'object', 'required': [], 'properties': {'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable']}}, 'additionalProperties': True}, {'type': 'object', 'oneOf': [{'type': 'object', 'required': ['votes', 'pct', 'winner', 'precincts_used'], 'properties': {'pct': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'votes': {'type': 'object', 'required': ['D', 'R', 'other', 'total'], 'properties': {'D': {'type': 'number'}, 'R': {'type': 'number'}, 'other': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'total': {'type': 'number'}}, 'additionalProperties': True}, 'winner': {'type': ['string', 'null']}, 'margin_pp': {'type': 'number'}, 'precincts_used': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}, {'type': 'object', 'required': ['group_by', 'total', 'regions', 'empty_regions', 'precincts_matched'], 'properties': {'total': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'regions': {'type': 'array', 'items': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}}, 'group_by': {'const': 'region_group'}, 'empty_regions': {'type': 'integer', 'minimum': 0}, 'precincts_matched': {'type': 'integer', 'minimum': 0}}, 'additionalProperties': True}], 'required': ['simulation_id', 'context', 'level', 'district_id', 'baseline_source', 'baseline_coverage'], 'properties': {'level': {'type': 'string'}, 'context': {'type': 'object', 'required': [], 'properties': {}, 'additionalProperties': True}, 'district_id': {'type': 'string'}, 'simulation_id': {'type': 'string'}, 'baseline_source': {'type': 'string'}, 'baseline_coverage': {'type': ['object', 'null'], 'additionalProperties': True}}}]}], '$schema': 'http://json-schema.org/draft-07/schema#', 'required': ['contract_version', 'result_status', 'workspace_id', 'affected', 'delta', 'latency_ms', 'category'], 'properties': {'delta': {'type': ['object', 'null'], 'additionalProperties': True}, 'affected': {'type': ['object', 'null'], 'additionalProperties': True}, 'category': {'type': 'string'}, 'latency_ms': {'type': 'integer', 'minimum': 0}, 'workspace_id': {'type': 'string'}, 'result_status': {'enum': ['success', 'empty', 'partial', 'unavailable', 'error']}, 'contract_version': {'const': 1}}, 'description': 'Versioned MCP result. success/empty describe completed reads; partial retains explicit missing coverage or another search page; unavailable describes a missing dependency. error/unavailable with an error code also set MCP isError. Existing provenance and context fields remain authoritative.', 'additionalProperties': True}
roll_up_state_races
Roll up every user-modeled race at one office level within a state, returning current modeled winners and margins from the canonical scenarios.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'state'], 'properties': {'level': {'enum': ['house', 'state_senate', 'state_assembly'], 'type': 'string'}, 'state': {'type': 'string', 'description': '2-letter or FIPS.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
save_calendar_scenario
Save a NAMED primary-calendar ordering as a first-class, diffable artifact. The 2028 Democratic calendar order is undetermined, so the ordering is itself a strategic choice: it does not change any candidate's TOTAL…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'A unique name for this ordering in your workspace (re-saving the same name updates it).'}, 'note': {'type': 'string', 'description': 'Optional freeform note (the strategic rationale).'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Which party's calendar this orders. Default D."}, 'ordering': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Contests in chronological order (postal/FIPS), e.g. ["IA","NH","MI","SC"]. Omitted calendar states are appended in default order.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'from_simulation_id': {'type': 'string', 'description': "Optional — capture this simulation's current user-defined Dem calendar as the ordering (instead of the ordering arg)."}}, 'additionalProperties': False}
scenario_handoff_bundle
One consolidated, machine-readable audit + handoff packet for a scenario, so a teammate or a future AI session can resume without reconstructing context from many calls. AGGREGATES existing read tools into one payload:…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'mode': {'enum': ['full', 'summary'], 'type': 'string', 'default': 'full'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
search_candidates
BROWSE the canonical candidate registry WITHOUT a name — the nameless companion to resolve_candidate (which requires a name). Filter the registry of canonical people by party, office, and/or a name substring:…
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'q': {'type': 'string', 'description': 'Optional — case-insensitive substring on the candidate name or any alias (typeahead).'}, 'limit': {'type': 'integer', 'default': 50, 'maximum': 200, 'minimum': 1, 'description': 'Max results (default 50). `total` reports the full match count; `truncated:true` when the list was trimmed.'}, 'party': {'type': 'string', 'description': 'Optional — only this party (D/R/I/L/G), normalized by leading letter.'}, 'office': {'type': 'string', 'description': 'Optional — match the registry office label. Keywords president / senate / house / governor are normalized; anything else is a case-insensitive substring on the label. The "us_" prefix is ignored.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
senate_control
Compute Senate control for a cycle using the real class calendar. Only one class (~33 seats) is on the ballot per cycle — the rest carry over at their current party. Pass the simulation_id + cycle: the up-this-cycle…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'cycle': {'type': 'integer', 'default': 2028, 'maximum': 2040, 'minimum': 2024}, 'prior_results': {'type': 'object', 'description': 'OPTIONAL multi-cycle carryover. Map a PRIOR-cycle Senate result onto the target cycle\'s carryover baseline: each key is "cycle:state:senate[:class]" (e.g. "2026:ME:senate") and the value is the assumed winning party "D" | "R" | "I". A seat NOT on the target cycle\'s ballot but decided in a supplied prior cycle then carries over at the SUPPLIED party instead of its current-hold party. Keys are validated against the real class calendar — party in D/R/I, a known seat, a genuine carryover set by the CORRECT prior election of that class; a key that is ON the target ballot, an unknown seat, or the wrong/stale prior cycle is REJECTED and surfaced under prior_results.warnings (never silently applied). Omit for the standard single-cycle baseline (byte-identical to before).', 'additionalProperties': {'enum': ['D', 'R', 'I'], 'type': 'string'}}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
senate_path_to_majority
Calculate a deterministic Senate path to majority from the active user-controlled scenario's modeled margins, carryover assumptions, protected seats, and target control rule.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'race_ratings_basis'], 'properties': {'cycle': {'type': 'integer', 'default': 2028, 'maximum': 2040, 'minimum': 2024, 'description': 'Election cycle. Determines which Senate class (~34 seats) is on the ballot; the rest carry over.'}, 'target_party': {'enum': ['D', 'R'], 'type': 'string', 'default': 'D', 'description': 'The party trying to reach a majority. D includes its independent caucus.'}, 'max_path_size': {'type': 'integer', 'maximum': 34, 'minimum': 1, 'description': 'Cap on the number of flips a reported path may contain. If the shortest path needs more flips than this, it is still returned but flagged exceeds_max_path_size.'}, 'simulation_id': {'type': 'string', 'description': 'Required only when race_ratings_basis:"custom" — the scenario whose modeled senate margins drive classification and difficulty.'}, 'exclude_states': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Up-seats (state abbrs) assumed LOST by the target party — removed from the winnable pool (a target-held one becomes a loss that raises the flip count).'}, 'protected_seats': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Up-seats (state abbrs) the target party is ASSUMED to win regardless of the basis — locked wins. Removes them from the flip requirement and flags them as load-bearing assumptions.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'race_ratings_basis': {'enum': ['custom'], 'type': 'string', 'description': "Use the active scenario's modeled Senate margins."}, 'target_control_mode': {'enum': ['50_with_vp', '51_outright'], 'type': 'string', 'default': '50_with_vp', 'description': '50_with_vp = 50 seats governed via the vice-presidential tiebreak (assumes target holds the VP); 51_outright = 51 seats, no VP needed.'}, 'starting_carryover_overrides': {'type': 'object', 'description': 'Reassign carryover (not-up-this-cycle) seats before solving, e.g. {"ME":"D"} to assume Maine\'s prior-cycle seat flipped D. Key by state abbr, optionally class-qualified ("ME:II"); value is "D" | "R" | "I". The response reports exactly which seat+class each override moved and its effect on the flip count.', 'additionalProperties': {'enum': ['D', 'R', 'I'], 'type': 'string'}}}, 'additionalProperties': False}
set_ballot_order
BALLOT DESIGN — record each candidate's printed ballot POSITION (and an optional per-candidate confusion/roll-off assumption) for a simulation+level roster, so same-name and crowded races can be disambiguated. This is…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'positions'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'replace': {'type': 'boolean', 'description': 'When true, clear ballot_position/ballot_confusion_pct on any roster candidate NOT named in positions. Default false (leave others untouched).'}, 'positions': {'type': 'array', 'items': {'type': 'object', 'required': ['candidate_id'], 'properties': {'position': {'type': 'integer', 'maximum': 10000, 'minimum': 1, 'description': "Printed ballot position (1 = first line). Defaults to this entry's 1-based place in the list if omitted."}, 'candidate_id': {'type': 'string', 'description': 'A candidate id on this simulation+level roster (see list_candidates).'}, 'confusion_pct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': 'Optional assumed confusion/roll-off share (0–100) tied to this ballot line — e.g. votes a second same-name candidate siphons. DATA only; not auto-applied to the tally.'}}, 'additionalProperties': False}, 'minItems': 1}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_candidates
Replace the entire candidate roster for a simulation+level in one call (add / edit / remove / reorder). Each candidate: {id?, name, party, color?, incumbent?}; ids auto-assigned if omitted. Use this to set the real…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'candidates'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer', 'custom'], 'type': 'string'}, 'candidates': {'type': 'array', 'items': {'type': 'object', 'required': ['name'], 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'color': {'type': 'string', 'pattern': '^#[0-9a-fA-F]{6}$'}, 'party': {'type': ['string', 'null']}, 'incumbent': {'type': 'boolean'}}, 'additionalProperties': False}, 'minItems': 0}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'The last-read updated_at token; custom model writes refuse stale edits.'}}, 'additionalProperties': False}
set_compare_paths
Generate a two-path comparison that the browser renders side-by-side. Stores two named delegate PATHS (per-state candidate allocations) on the sim as Path A and Path B; when the user opens the sim in the simulator, the…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'a', 'b'], 'properties': {'a': {'type': 'object', 'required': ['shares'], 'properties': {'label': {'type': 'string'}, 'shares': {'type': 'object'}}, 'description': 'Path A: { label, shares }. shares maps state → { candidate_id: pct }.', 'additionalProperties': False}, 'b': {'type': 'object', 'required': ['shares'], 'properties': {'label': {'type': 'string'}, 'shares': {'type': 'object'}}, 'description': 'Path B, same shape as A.', 'additionalProperties': False}, 'kind': {'enum': ['dem_primary_2028', 'rep_primary_2028'], 'type': 'string', 'default': 'dem_primary_2028'}, 'apply_path': {'enum': ['a'], 'type': 'string', 'description': 'Explicit opt-in mutation: mirror Path A onto the live primary shares (+ stamp the primary mode and, if given, the roster) so the open map starts on Path A. Omit it to write only the compare artifact and preserve the current model version. A changed result creates a pre-apply checkpoint followed by one exact post-edit model version; an identical apply mints neither.'}, 'candidates': {'type': 'array', 'items': {'type': 'object'}, 'description': 'Optional roster override [{id,name,color}] carried on the compare artifact (labels/colors for the compare renderer). The LIVE roster is only replaced under apply_path:"a". Omit to use the sim\'s field.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_cycle
Set the election cycle modeled by the active scenario. This updates the canonical scenario and any open application view bound to it.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'cycle'], 'properties': {'cycle': {'enum': [2024, 2026, 2028, 2030], 'type': 'integer', 'description': 'Supported election cycles.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_feature_percentages
Override the vote percentages on a single feature. Percentages keyed by candidate_id. Residual = "Other".
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'level', 'feature_id', 'percentages'], 'properties': {'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string'}, 'feature_id': {'type': 'string', 'description': 'A feature id AT THIS LEVEL — president = county FIPS (5-digit), house/state-leg = district external_id, senate/governor/exec = a state (FIPS "37", postal "NC", or "us-nc" slug — all accepted, normalized server-side). Get valid ids from list_features (returns both FIPS id and postal abbr). An id from the wrong granularity (e.g. a state at president level) is rejected with unknown_feature (+did_you_mean when resolvable); for precinct overrides use set_precinct_pcts.'}, 'percentages': {'type': 'object', 'additionalProperties': {'type': 'number', 'maximum': 100, 'minimum': 0}}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'Optional optimistic-concurrency token: the scenario updated_at you last read. If the scenario changed since, the write is refused with version_conflict + the current token instead of overwriting concurrent edits.'}}, 'additionalProperties': False}
set_geo_knowledge
Write your workspace CUSTOM overlay for a geography — campaign-specific notes, target shares, turf intel, local relationships, assumptions — layered ON TOP of (and able to override) the global canonical layer read by…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['geo_id', 'level', 'fields'], 'properties': {'layer': {'enum': ['custom'], 'type': 'string', 'description': 'Only "custom" is writable (default). The global layer is system-curated.'}, 'level': {'enum': ['state', 'county', 'precinct'], 'type': 'string'}, 'fields': {'type': 'object', 'description': 'The custom fields to store/merge for this geography (e.g. {target_share:34, note:"strong labor turf", registration:"closed"}). Merged into the existing overlay; pass a field = null to drop it.'}, 'geo_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_mode
Set presidential modeling mode to general, 2028 Democratic primary, or 2028 Republican primary. Existing candidate rosters and user changes are preserved; use set_primary_candidates to define the prospective field…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'mode'], 'properties': {'mode': {'enum': ['general', 'dem_primary_2028', 'rep_primary_2028', 'dem_primary', 'rep_primary'], 'type': 'string', 'description': 'general | dem_primary_2028 | rep_primary_2028 (the loose "dem_primary"/"rep_primary" are accepted and canonicalized).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_performance
Set a candidate's vote share, such as the Democratic candidate to 54%, in one specific county, district, state, or precinct (the general-election override). Routes a county/state/district geo_id to a feature override…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id', 'geo_id', 'shares'], 'properties': {'level': {'enum': ['custom', 'president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'EM-136: explicit office for the override. A bare state geo (us-pa) otherwise defaults to senate — pass level to target president or governor instead (president is stored as a state-level aggregate that roll_up_race and get_view honor). For a district geo it must match the geo grain. tk_3c0569e9b02541: a COUNTY geo (us-me-county-23001) accepts any STATEWIDE office — level:"senate"/"governor"/exec stores the county edit in THAT race\'s store, folding into its state rollup with precinct > county > state > baseline precedence (default without level stays president). A PRECINCT geo (us-me-vtd-…) with level tags the edit\'s office so it folds into that race\'s statewide total (same tag set_precinct_pcts writes).'}, 'geo_id': {'type': 'string'}, 'margin': {'type': 'number', 'description': 'Shorthand for two-candidate D−R margin in points; sets D/R shares around 50.'}, 'shares': {'type': 'object', 'description': 'candidate_id → share. Accepts 0–1 or 0–100.', 'additionalProperties': {'type': 'number'}}, 'turnout': {'type': 'number', 'description': '0–1 expected turnout (stored as metadata on precinct overrides).'}, 'rebalance': {'enum': ['undecided', 'proportional'], 'type': 'string', 'default': 'undecided'}, 'scenario_id': {'type': 'string', 'description': 'The simulation_id (scenario_id alias until the scenario model lands).'}, 'total_votes': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Explicit vote volume for a custom campaign city or reviewed precinct. Use level:"custom" and geo_id from get_campaign_vote_data. A precinct requires its own total; source-election turnout is never copied automatically.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'Optional optimistic-concurrency token: the scenario updated_at you last read. If the scenario changed since, the write is refused with version_conflict + the current token instead of overwriting concurrent edits.'}}, 'additionalProperties': False}
set_precinct_pcts
Set a precinct-level override in a simulation. Pass the candidate-id → pct map (e.g. {D: 52.5, R: 46.0}). Overrides the modeled result for this precinct, which then rolls up into every race the precinct is part of…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'precinct_id', 'percentages'], 'properties': {'level': {'enum': ['senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly', 'president'], 'type': 'string', 'description': 'The office this edit models — folds the precinct into that race\'s state rollup (precinct > county > state > baseline). Its per-override baseline/modeled/contribution_pp shows in get_manual_edits; the local map renders via get_view/render_view(level, state, grain:"precinct").'}, 'percentages': {'type': 'object', 'description': 'Map of candidate id → pct (0-100). Need not sum to 100; "Other" residual is preserved.'}, 'precinct_id': {'type': 'string', 'description': 'The precinct external_id ("23001-ME-101") OR its canonical geo_id ("us-me-vtd-23001-ME-101") — both accepted (tk_3c0569e9b02541), normalized to one canonical key.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'expected_version': {'type': 'string', 'description': 'Optional optimistic-concurrency token: the scenario updated_at you last read. If the scenario changed since, the write is refused with version_conflict + the current token instead of overwriting concurrent edits.'}}, 'additionalProperties': False}
set_primary_asof
Move the calendar playhead — the point in the primary calendar "as of" which to view the race on the map/chart. Pass an integer (number of contests counted, 0 = before the first contest) or null for the full calendar —…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'asof': {'type': ['integer', 'null'], 'description': 'Contests counted (0..calendar length), or null = full calendar. Ignored when contest/contest_index is given.'}, 'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Which party's calendar resolves contest/contest_index (default: the sim's own primary party from its mode)."}, 'contest': {'type': 'string', 'description': 'Jump the playhead TO this contest — state postal ("FL"), 2-digit FIPS ("12"), or full name ("Florida"). asof becomes that contest\'s 1-based calendar index, so the contest itself is counted.'}, 'contest_index': {'type': 'integer', 'description': '1-based calendar ordinal to jump to (the order list_primary_calendar returns). asof becomes this value — the contest at this index is counted.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_candidates
Define the candidate field for a party's presidential primary on this simulation (the GOP/Dem contenders). Persisted on the sim so the browser and AI share one roster. Shares set via set_primary_shares reference these…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'candidates'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'candidates': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string', 'description': 'Optional stable id (e.g. "newsom"). Auto-minted as c_<n> when omitted.'}, 'name': {'type': 'string'}, 'color': {'type': 'string', 'description': 'Optional hex color; omitted → a distinct auto-assigned palette color.'}, 'party': {'type': 'string'}, 'ideology': {'type': 'string', 'description': 'Optional ideology lane.'}, 'home_state': {'type': 'string', 'description': 'Optional home-state postal/FIPS.'}, 'incumbency': {'type': 'string', 'description': 'Optional incumbency status.'}}}, 'description': "Array of contenders: [{id?, name, party?, color?, home_state?, incumbency?, ideology?}]. Replaces the party's primary roster. Omitted colors are auto-assigned distinct palette hues."}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_county_shares
Model a party's presidential primary at COUNTY level: set one county's candidate vote shares within a state's primary. The state's effective share is the TURNOUT-WEIGHTED aggregate of its modeled counties (weighted by…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'state', 'county_fips', 'shares'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'State FIPS ("06") or 2-letter abbr ("CA").'}, 'shares': {'type': 'object', 'description': 'Map of candidate_id → percentage (0-100) in this county, e.g. {"harris": 55, "newsom": 30}. Must reference set_primary_candidates ids.'}, 'county_fips': {'type': 'string', 'description': '5-digit county FIPS within the state (e.g. "06037" for Los Angeles County, CA).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_demo_levers
Set a candidate's GLOBAL DEMOGRAPHIC DIALS in a primary — how many points to shift them among a voter group across the whole district/state. levers = { uniform, college, immig, highHome, lowHome, hiUnemp } in…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'candidate_id', 'levers'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string', 'description': "Which party's primary field. For a top-two (nonpartisan) primary, pass D as the storage bucket."}, 'levers': {'type': 'object', 'properties': {'immig': {'type': 'number', 'description': 'In immigrant-heavy precincts (ACS foreign-born share).'}, 'college': {'type': 'number', 'description': 'In college-educated precincts (ACS bachelors+ share).'}, 'hiUnemp': {'type': 'number', 'description': 'In high-unemployment precincts (> 6%).'}, 'lowHome': {'type': 'number', 'description': 'In cheap-housing precincts (median home < $200k).'}, 'uniform': {'type': 'number', 'description': 'Everywhere (every precinct, full strength).'}, 'highHome': {'type': 'number', 'description': 'In expensive-housing precincts (median home > $500k).'}}, 'description': 'Points to shift this candidate per voter group, at full demographic intensity. Any omitted axis = 0. Each clamped to ±30.', 'additionalProperties': False}, 'candidate_id': {'type': 'string', 'description': 'The candidate id from the field roster (e.g. P1, or a registry/custom id).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_grain_pref
Pin which modeling grain DRIVES a state in a party's presidential primary — i.e. which level feeds that state's delegate allocation. "auto" (default) = the finest grain modeled wins (precinct > county > the flat…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'state', 'pref'], 'properties': {'pref': {'enum': ['auto', 'state', 'county', 'precinct'], 'type': 'string', 'description': 'Which grain drives this state. auto = finest modeled wins.'}, 'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'State FIPS ("06") or 2-letter abbr ("CA").'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_precinct_shares
Model a party's presidential primary at PRECINCT level — the finest grain. Set one precinct's candidate vote shares; the state's effective share becomes the TURNOUT-WEIGHTED aggregate of its modeled precincts (each…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party', 'precinct_id', 'shares'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'State FIPS ("06") or 2-letter abbr ("CA") — must match the precinct\'s state.'}, 'shares': {'type': 'object', 'description': 'Map of candidate_id → percentage (0-100) in this precinct, e.g. {"buttigieg": 48, "harris": 33}. Must reference set_primary_candidates ids.'}, 'precinct_id': {'type': 'string', 'description': 'Precinct external_id (begins with the 2-digit state FIPS), e.g. from target_precincts.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_primary_shares
Set a party's presidential-primary vote shares — one state, or MANY states in a single call. SINGLE STATE: pass `state` + `shares` (unchanged behavior; echoes the full running roll_up). BATCH: pass `states` = { "SC":…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'party'], 'properties': {'party': {'enum': ['D', 'R'], 'type': 'string'}, 'state': {'type': 'string', 'description': 'SINGLE-STATE mode: State FIPS ("19") or 2-letter abbr ("IA"). Provide `state`+`shares` OR `states`, not both.'}, 'shares': {'type': 'object', 'description': 'SINGLE-STATE mode: Map of candidate_id → percentage (0-100), e.g. {"vance": 42, "desantis": 30}. Must reference set_primary_candidates ids. Empty ({}) un-models the state.'}, 'states': {'type': 'object', 'description': 'BATCH mode: Map of state (FIPS or 2-letter abbr) → its {candidate_id: pct} shares, e.g. {"SC":{"newsom":31,"harris":24},"NH":{...}}. Writes all states in one atomic call; an invalid state fails the whole batch (nothing is written). Empty ({}) for a state un-models it.'}, 'simulation_id': {'type': 'string'}, 'include_rollup': {'type': 'boolean', 'description': 'BATCH mode only: also return the full delegate roll_up alongside the default trimmed `delta` summary. Ignored in single-state mode (which always echoes the full roll_up).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_race_scope
Bind the canonical scenario to one race/campaign so its map, tally, candidates, War Room context, operations, outputs, and MCP actions share the same race identity.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'cycle': {'type': 'integer', 'default': 2028, 'maximum': 2100, 'minimum': 1900}, 'level': {'enum': ['president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'DEPRECATED alias for `office` (kept for back-compat). Prefer `office`.'}, 'stage': {'enum': ['general', 'd_primary', 'r_primary'], 'type': 'string', 'default': 'general'}, 'office': {'enum': ['president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'The office (seat) this race is for. This is the canonical parameter name; the older `level` is still accepted as an alias.'}, 'rebind': {'type': 'boolean', 'default': False, 'description': 'Deliberately re-district a campaign already bound to a DIFFERENT geography. Without it, re-scoping a bound sim is rejected (scope_locked) — a campaign is tied to the district it was created in.'}, 'candidate': {'type': 'string', 'description': 'A candidate/officeholder name ("Lauren Boebert") — resolved via resolve_candidate to their office + geography + cycle, so you scope their race in ONE call and they are auto-added to the roster as the incumbent. Ignored if geography_id is also given. If the name is in no source (never guessed) the call errors — pass office + geography_id instead.'}, 'candidates': {'type': 'array', 'description': "Optional array of real candidates running this race: [{id, name, party, color, incumbent?}]. Overwrites the office's candidate list. If omitted, keeps existing candidates."}, 'geography_id': {'type': 'string', 'description': 'Accepts the canonical resolve_geography slug at every office — president "us" / "US"; senate & governor "us-pa", "PA", or FIPS "42"; house "us-ny-cd-17", "NY-17", or the FIPS+CD external_id "3617". State-leg takes its district external_id from list_features. Omit when you pass `candidate`.'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_swings
Persist the swing-slider state so a scenario built by hand in the browser (uniform + demographic share swings, the swing target, and the demographic region scope) survives reload. Opaque blob, mirrored to/from the UI.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id', 'swings'], 'properties': {'swings': {'type': 'object', 'additionalProperties': True}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
set_turnout
Set the turnout (mobilization) model. PRESIDENT (default, unchanged): each dial is a percentage-point boost toward toward_candidate_id in counties over an ACS threshold (college = >20% BA share, immig = >15%…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'immig': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'level': {'enum': ['president', 'senate', 'governor', 'house', 'state_senate', 'state_assembly', 'attorney_general', 'secretary_of_state', 'treasurer'], 'type': 'string', 'default': 'president', 'description': 'president (default) = the classic ACS-threshold dials below. Any other level = the race-scoped ballots lever (turnout_change_pct + cohort).'}, 'source': {'type': 'string', 'maxLength': 300, 'description': "Where this user-authored assumption came from (user statement, field report, or source citation) — stored on the lever's audit entry."}, 'college': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'geo_ids': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 500, 'description': 'Explicit geography cohort — 5-digit county FIPS on statewide levels (e.g. "23005" = Cumberland ME), district external ids on house/state-leg.'}, 'hiUnemp': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'lowHome': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'counties': {'type': 'array', 'items': {'type': 'string'}, 'maxItems': 500, 'description': 'Alias of geo_ids for county cohorts.'}, 'highHome': {'type': 'number', 'maximum': 50, 'minimum': -50}, 'criterion': {'type': 'object', 'required': ['field', 'op', 'value'], 'properties': {'op': {'enum': ['gte', 'lte', 'gt', 'lt'], 'type': 'string'}, 'field': {'enum': ['pct_bachelors', 'pct_foreign_born', 'median_home', 'mhi', 'population', 'unemp_pct', 'median_age', 'owner_occ_pct'], 'type': 'string'}, 'value': {'type': 'number'}}, 'description': 'ACS-style county matcher (statewide levels): e.g. {field:"population", op:"lt", value:30000} = rural counties. Filters WITHIN geo_ids when both are passed; scope a bare criterion with state_fips.', 'additionalProperties': False}, 'assumption': {'type': 'string', 'maxLength': 600, 'description': 'The modeling assumption in plain words (e.g. "youth demobilization scenario") — stored on the lever\'s audit entry.'}, 'state_fips': {'type': 'string', 'description': '2-digit state FIPS to scope a criterion cohort to one state (e.g. "23" = Maine).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'turnout_change_pct': {'type': 'number', 'maximum': 300, 'minimum': -90, 'description': 'Race-scoped levels only: percent change to BALLOTS cast in the matched geography (-12 = 12% fewer, +8 = 8% more). Composes multiplicatively with prior levers; the factor is clamped to [0.05, 5].'}, 'toward_candidate_id': {'type': 'string', 'default': 'D'}}, 'additionalProperties': False}
set_view
Set the active scenario view and selected map context: race stage, calendar playhead, geography grain, result source, selected feature, camera, map theme, and rail. The same persisted view state and deep link are used…
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'asof': {'type': ['integer', 'null'], 'minimum': 0, 'description': "The primary calendar playhead — contests counted in the race-so-far (the number set_primary_asof takes). null = full calendar. Writes sim.primary.asof (the store the viewer's scoreboard/map run at), so this one DOES change the sim document. Primary sims only (a general sim answers with an asof_ignored warning)."}, 'rail': {'enum': ['select', 'notes', 'strategy', 'none'], 'type': 'string', 'description': 'Which right-rail panel the viewer should have open.'}, 'zoom': {'type': 'number', 'maximum': 20, 'minimum': 0, 'description': "Optional camera zoom; omit to fit the geo's bounds."}, 'cycle': {'type': 'integer', 'maximum': 2040, 'minimum': 2024}, 'level': {'enum': ['custom', 'president', 'senate', 'governor', 'attorney_general', 'secretary_of_state', 'treasurer', 'house', 'state_senate', 'state_assembly'], 'type': 'string', 'description': 'The map/level the view should show.'}, 'stage': {'enum': ['general', 'd_primary', 'r_primary', 'top_two'], 'type': 'string', 'description': "The race stage the viewer should see. Persisted on view_state + broadcast live; a primary-mode sim's own mode remains the identity truth (this is the VIEW)."}, 'state': {'type': 'string', 'description': 'Postal code or 2-digit FIPS to scope to (pass empty string to clear to the national view).'}, 'layers': {'type': 'object', 'description': 'View toggles such as precincts/highlights plus the canonical "actuals:pres_2024" baseline layer.', 'additionalProperties': {'type': ['boolean', 'null']}}, 'source': {'enum': ['auto', 'state', 'county', 'precinct', 'flat'], 'type': 'string', 'description': "The per-state Outcome SOURCE control (which grain governs the shown outcome). Stored on view_state; the sim's own grain_pref pin stays set_primary_grain_pref's job."}, 'contest': {'type': 'string', 'description': 'Playhead targeting by contest instead of a number: a state postal code ("FL"), 2-digit FIPS, or full name — the playhead jumps to INCLUDE that contest (same semantics as set_primary_asof).'}, 'map_grain': {'enum': ['states', 'counties', 'precincts', 'state', 'county', 'precinct'], 'type': 'string', 'description': 'The Map View grain toggle: states | counties | precincts (singular accepted, stored plural).'}, 'map_theme': {'type': 'string', 'description': 'Pin a MAP THEME audience preset on this view (list_map_themes has the registry: control | analyst | field | civic | accessible | broadcast | terrain). The open viewer restyles live; "none" clears the pin. Colors only — data, winners and margins never change.'}, 'selected_geo': {'type': 'object', 'required': ['feature_id'], 'properties': {'level': {'enum': ['custom', 'state', 'county', 'district', 'precinct'], 'type': 'string'}, 'feature_id': {'type': 'string'}}, 'description': 'The selected feature on the map ({level, feature_id} — e.g. {level:"county", feature_id:"12086"} for Miami-Dade). Pass feature_id:"" to clear the selection.', 'additionalProperties': False}, 'camera_geo_id': {'type': 'string', 'description': 'Optional geo to frame the camera on (defaults to the scoped state). 2-digit state / 5-digit county / district GEOID / precinct id.'}, 'contest_index': {'type': 'integer', 'minimum': 1, 'description': 'Playhead targeting by 1-based calendar ordinal (list_primary_calendar order).'}, 'simulation_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
share_simulation
Mint a public, read-only link to the exact canonical scenario/version. Authenticate for durable workspace ownership; revoke_share disables the link.
Destructive
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'sections': {'type': 'array', 'items': {'enum': ['race_result', 'map', 'impact', 'notes', 'widgets'], 'type': 'string'}, 'description': 'Optional public-share section allowlist. Single-race shares remain race-scoped even when impact is requested.', 'uniqueItems': True}, 'ttl_days': {'type': 'integer', 'default': 30, 'maximum': 365, 'minimum': 1}, 'campaign_id': {'type': 'string', 'description': 'Optional campaign that contains this simulation. The share is authorized against that campaign and its frozen context/manifest retain the campaign id.'}, 'simulation_id': {'type': 'string'}, 'include_deltas': {'type': 'boolean', 'default': False, 'description': 'Include modeled margin/share deltas from the canonical baseline for this exact race.'}, 'include_impact': {'type': 'boolean', 'default': False, 'description': 'Include national impact only for an unscoped national model. Ignored for a single-race or primary scope.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
start_setup
CUSTOMER SETUP — create a durable server-side setup session from an acquisition choice: client_type (team size/use) plus setup_scope (race|county|district|state|multi), optional geography (state/county_fips/party), and…
Destructive
Input schema
{'type': 'object', 'properties': {'cycle': {'type': 'integer', 'maximum': 2200, 'minimum': 1900, 'description': 'Required explicitly for custom campaigns, including odd years. Listed models support 2024, 2026, 2028 and 2030.'}, 'party': {'type': 'string'}, 'stage': {'enum': ['general', 'd_primary', 'r_primary'], 'type': 'string', 'default': 'general'}, 'state': {'type': 'string'}, 'office': {'type': 'string', 'description': 'The race office: president | senate | house | governor | state_senate | state_assembly.'}, 'district': {'type': 'string', 'description': 'District GEOID or validated alias for districted offices (e.g. 3403, NJ-03, or AL for an at-large state).'}, 'contest_id': {'type': 'string', 'description': 'Exact canonical contest identity. Alternatively pass office/state/district/cycle/stage.'}, 'utm_medium': {'type': 'string'}, 'utm_source': {'type': 'string'}, 'client_type': {'type': 'string'}, 'county_fips': {'type': 'string'}, 'setup_scope': {'enum': ['race', 'county', 'district', 'state', 'multi', 'custom'], 'type': 'string', 'description': 'The deliberately chosen initial map scope. Required by current onboarding; optional for legacy callers.'}, 'utm_campaign': {'type': 'string'}, 'boundary_name': {'type': 'string', 'maxLength': 160, 'minLength': 2, 'description': 'Explicit custom jurisdiction name.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}, 'custom_office_label': {'type': 'string', 'maxLength': 100, 'minLength': 2, 'description': 'Explicit custom office label; required before the operational campaign can be completed.'}}, 'additionalProperties': False}
start_subscription
BILLING — begin a paid subscription. Returns {checkout_url}: a Stripe-hosted Checkout page the USER opens in a browser to enter payment — no card details are ever handled by this server or the agent. Requires a…
Destructive Open world
Input schema
{'type': 'object', 'properties': {'plan': {'enum': ['personal', 'team'], 'type': 'string', 'description': 'Which plan to subscribe to (default personal).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
target_list
CAMPAIGN OPERATIONS — read or reorder the active scenario's shared War Room target posts. Targets keep their stable post ids, rank, text, and selected region context.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'reorder': {'type': 'array', 'items': {'type': 'string'}, 'description': "Campaign mode — the open target post ids in their NEW order (every open target exactly once). Rewrites each post's payload.rank to its 1-based position and returns the reordered list. Needs a writing role; targets are manager/field work."}, 'campaign_id': {'type': 'string', 'description': 'Campaign mode — the campaign whose War Room holds the targets. The scenario must be filed under it. Omit only for the scenario-global room.'}, 'simulation_id': {'type': 'string', 'description': 'CAMPAIGN MODE — read this scenario\'s curated ranked target list (the open "target" War Room posts) instead of the certified-returns ranking.'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
target_precincts
Return structured precinct model rows: precinct_id, name, county, county_fips, baseline_share, modeled_share, ballots_est, overridden, and gap_to_goal. The response does not include demographic columns or demographic…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'limit': {'type': 'integer', 'default': 500, 'maximum': 10000, 'minimum': 1}, 'filter': {'type': 'object', 'description': 'Precinct property → condition map within the requested geography. Properties: external_id, GEOID, name, state, county, county_fips, shape_id, votes_dem, votes_rep, votes_total, pct_dem_lead, official_boundary, lat, lng, population, mhi, median_home, pct_bachelors, pct_foreign_born, unemp_pct, median_age, owner_occ_pct, modeled_margin_pp, modeled_pct_dem_lead, flipped, overridden. A bare scalar means exact equality; an array means membership. Object operators: gt, gte, lt, lte, in, not_in. Comparisons take finite numbers; in/not_in take arrays of scalars. Conditions are ANDed. pct_dem_lead is a baseline two-party share lead in -1..1. Scenario-scoped target_precincts, aggregate_precincts and apply_swing_to_query also accept modeled_margin_pp (D minus R over ALL modeled ballots, percentage points), modeled_pct_dem_lead (same margin / 100), modeled_share.CANDIDATE_ID (0..1 all-ballot share), flipped (winner differs from baseline, including ties) and overridden (saved precinct or county share override). These require a supported general statewide scenario with an allocated local model; missing shares never match numeric comparisons. Example: {external_id:{in:["48009-11"]},votes_total:{gte:500}}. Unknown properties/operators and malformed conditions are rejected before matching or writing.'}, 'geo_id': {'type': 'string', 'description': 'District or state geography — accepts the resolve_geography slug ("us-pa"), postal ("PA"), or FIPS ("42") (EM-056). Defaults to the simulation\'s race_scope geography.'}, 'margin': {'type': 'number', 'default': 1, 'description': 'plurality: win by at least this many votes.'}, 'offset': {'type': 'integer', 'default': 0, 'minimum': 0, 'description': 'Page start; pass next.offset from the prior result with the same scope and filters.'}, 'context': {'type': 'string', 'description': 'Free-text constraints, echoed back (e.g. "field ops in Orange and Durham only").'}, 'goal_mode': {'enum': ['plurality', 'majority', 'share'], 'type': 'string', 'default': 'plurality', 'description': 'plurality = beat the leading opponent (default); majority = 50.01% share; share = explicit target_pct.'}, 'target_pct': {'type': 'number', 'default': 0.5001}, 'scenario_id': {'type': 'string', 'description': 'The scenario/simulation handle (EM-056: simulation_id is accepted as an alias).'}, 'candidate_id': {'type': 'string', 'default': 'D'}, 'rolloff_rate': {'type': 'number', 'maximum': 1.5, 'minimum': 0.05, 'description': 'Explicit roll-off rate (see compute_vote_goal).'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
tipping_point
Identify the tipping-point race and nearby high-leverage races in the active user-controlled scenario, using its modeled margins and canonical version context.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['simulation_id'], 'properties': {'cycle': {'type': 'integer', 'maximum': 2040, 'minimum': 2024, 'description': 'Cycle (default 2028 president/house, 2026 senate).'}, 'level': {'enum': ['president', 'senate', 'house'], 'type': 'string', 'description': 'Which chamber to triage. Default president. "house" triages all 435 seats to the 218-seat majority line.'}, 'simulation_id': {'type': 'string', 'description': "Optional. Triage this scenario's modeled margins instead of the static 2024 baseline; un-modeled races fall back to baseline."}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
update_scenario
Edit a Scenario's name / description / tags. Appends a metadata version to the chain.
Destructive Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'name': {'type': 'string'}, 'tags': {'type': 'array', 'items': {'type': 'string'}}, 'description': {'type': 'string'}, 'scenario_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
verify_audit
WITNESS AUDIT (EM-116) — re-verify the immutable, content-hashed audit chain of a scenario's committed versions (commit_version is the append-only hash-stamped write). Recomputes each version's hash from its stored…
Read only Idempotent
Input schema
{'type': 'object', 'required': ['scenario_id'], 'properties': {'scenario_id': {'type': 'string'}, 'workspace_scope': {'type': 'string', 'pattern': '^[uw]-[a-z0-9](?:[a-z0-9-]{0,61})$', 'maxLength': 64, 'minLength': 3, 'description': 'Optional workspace for THIS call: use an exact personal/team ID from list_workspaces. Repeat on each call; it does not change the connection default. Must agree with MCP metadata and the effective HTTP workspace selector (header, otherwise connector URL). OAuth connections can only use their granted workspace. Membership and campaign permissions still apply.'}}, 'additionalProperties': False}
Added
target_list
Sept. 28, 2026, 2:40 a.m.
Added
data_provenance
Sept. 28, 2026, 2:40 a.m.
Added
clear_race_scope
Sept. 28, 2026, 2:40 a.m.
Added
set_race_scope
Sept. 28, 2026, 2:40 a.m.
Added
primary_batch_edit
Sept. 28, 2026, 2:40 a.m.
Added
analyze_primary_inflections
Sept. 28, 2026, 2:40 a.m.
Added
optimize_calendar
Sept. 28, 2026, 2:40 a.m.
Added
apply_calendar_scenario
Sept. 28, 2026, 2:40 a.m.
Added
diff_calendar_scenarios
Sept. 28, 2026, 2:40 a.m.
Added
list_calendar_scenarios
Sept. 28, 2026, 2:40 a.m.
Added
save_calendar_scenario
Sept. 28, 2026, 2:40 a.m.
Added
list_geo_knowledge
Sept. 28, 2026, 2:40 a.m.
Added
set_geo_knowledge
Sept. 28, 2026, 2:40 a.m.
Added
get_geo_knowledge
Sept. 28, 2026, 2:40 a.m.
Added
clear_dem_calendar
Sept. 28, 2026, 2:40 a.m.
Added
define_dem_calendar
Sept. 28, 2026, 2:40 a.m.
Added
candidate_path_explainer
Sept. 28, 2026, 2:40 a.m.
Added
answer_assumption
Sept. 28, 2026, 2:40 a.m.
Added
check_workspace_consistency
Sept. 28, 2026, 2:40 a.m.
Added
primary_state_effective
Sept. 28, 2026, 2:40 a.m.
Added
roll_up_primary
Sept. 28, 2026, 2:40 a.m.
Added
set_compare_paths
Sept. 28, 2026, 2:40 a.m.
Added
set_primary_demo_levers
Sept. 28, 2026, 2:40 a.m.
Added
set_primary_grain_pref
Sept. 28, 2026, 2:40 a.m.
Added
set_primary_asof
Sept. 28, 2026, 2:40 a.m.
Added
clear_primary_shares
Sept. 28, 2026, 2:40 a.m.
Added
bulk_set_primary_shares
Sept. 28, 2026, 2:40 a.m.
Added
apply_primary_cohort
Sept. 28, 2026, 2:40 a.m.
Added
set_primary_precinct_shares
Sept. 28, 2026, 2:40 a.m.
Added
set_primary_county_shares
Sept. 28, 2026, 2:40 a.m.