Metadata-Version: 2.5
Name: crowdos-mcp
Version: 1.0.1
Summary: Model Context Protocol server for CrowdOS — simulated focus groups as agent-callable tools, relayed to the hosted CrowdOS MCP endpoint.
Project-URL: Homepage, https://crowdos.ai
Project-URL: Documentation, https://crowdos.ai/mcp
Author-email: CrowdOS <hello@motifmotion.sg>
License: MIT
Keywords: ai-agents,claude,claude-desktop,crowdos,focus-group,mcp
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.0.0
Description-Content-Type: text/markdown

# CrowdOS MCP Server

<!-- mcp-name: ai.crowdos/mcp -->

Simulated focus groups as agent-callable tools. Connects AI agents
(Claude Desktop, Cursor, Cline, LangGraph, CrewAI, and any other
[Model Context Protocol](https://modelcontextprotocol.io) host) to
[CrowdOS](https://crowdos.ai), so they can run simulated public-opinion
research with a single tool call.

**Every plan can use it** — Free, Pro and Max — at that plan's limits on
the web. Enterprise accounts get every tool.

## What this gives you

```
> Run a focus group on whether companies should mandate 4-day weeks.
   Use 200 people from the us_general_population preset.

[tool: run_focus_group]
{
  "id": "ad4b3736-...",
  "sentiment_summary": {
    "positive_pct": 71.5, "negative_pct": 18.0, "neutral_pct": 10.5,
    "positive": 143, "negative": 36, "neutral": 21
  },
  "total_responses": 200,
  "billing": { "credits_charged": 200 }
}
```

## Two ways to connect

**Hosted (no install).** Add `https://api.crowdos.ai/mcp` as a **remote
MCP server** in any client that supports them (claude.ai connectors,
Cursor, agent frameworks). OAuth-capable clients sign in and approve on
first connect; the grant shows up as a revocable key under
Account → MCP keys. Header-based clients pass
`Authorization: Bearer crowd_...`.

**This package (stdio, for desktop hosts).** Since 1.0.0 the package is a
thin relay to that same hosted endpoint: it holds no tools of its own, so
the tools, limits and checks your agent sees are exactly the ones your
key has there, and a new tool reaches you without an upgrade.

```bash
pip install crowdos-mcp
```

Then create an MCP key at <https://crowdos.ai/account/api-keys> (any
plan can).

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json`
(macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "crowdos": {
      "command": "crowdos-mcp",
      "env": {
        "CROWDOS_API_KEY": "crowd_..."
      }
    }
  }
}
```

Restart Claude Desktop; the CrowdOS tools appear in the tool picker.

### Cursor / Cline

Same shape in their MCP-server settings: command `crowdos-mcp`, env
`CROWDOS_API_KEY`.

## Tools, and who gets them

| Tool | What it does | Plans |
|---|---|---|
| `run_focus_group` | Simulated poll on a topic — sentiment totals | Every plan |
| `run_debate` | Multi-round simulated debate — convergence + key arguments | Every plan |
| `compare_options` | Simulated A/B test on text options — leaderboard with first choices, the choice share (each option's mean stated chance of being chosen) and per-option scores + winner | Every plan |
| `screen_creatives` | Screening Room: 1-4 videos or images the panel watches, from public links — ranking or solo verdict, synthesis memo, expert reports | Every plan |
| `test_ads` | Ads Labo: 1-4 ad creatives in the feed (Facebook, Instagram feed, Reels, Stories), from public links — predicted click-through rate with a 95% interval, stop-scroll and brand recall, or which version the panel would click | Every plan |
| `test_pricing` | Van Westendorp / Gabor-Granger pricing study | Pro, Max, Enterprise |
| `rank_items` | MaxDiff (best-worst scaling) on 4-200 items | Pro, Max, Enterprise |
| `pretest_questions` | Pretest 1-40 draft survey questions before fielding them | Enterprise |
| `estimate_reach` | Preview how broad a `custom_audience` filter is (free) | Every plan |
| `preview_cost` | Credits + seconds before running, and notes on a draft brief (free) | Every plan |
| `list_demographic_presets` | The audience templates | Every plan |
| `get_simulation` | Fetch a study you ran | Every plan |
| `cancel_simulation` | Stop a running study (returns the credits it reserved) | Every plan |
| `list_simulations` | The studies you ran, newest first, with the dashboard's summary (paged) | Every plan |
| `ask_followup` | A follow-up question on a completed vote or debate (its moderator) or Deep Review (its analyst chat), priced as on the web: 10 free per study, then the follow-up price (a Deep Review: 3 free) | Every plan |
| `share_study` | The study's public share link, as the web app's Share button makes it | Every plan |
| `get_report_link` | The study's page in the web app, where its PDF report downloads | Every plan |
| `validate_study` | Check a study's sentiment split against a real survey's: grade, parity, error in points (free) | Every plan |
| `record_outcome` | Record what happened in the real world after a study (free) | Every plan |
| `get_credits` | Credits left, the plan, who pays, and an organization's credits this month (free) | Every plan |
| `crowd_sample` | Browse the public crowd (sanitized) | Every plan |
| `list_panels` / `get_panel` / `delete_panel` | Saved panels — the same respondents across runs | Enterprise |

`test_pricing` and `rank_items` are Pro and Max studies, as in the web
app. They run at the sizes the web app offers: 50 to 200 respondents for
pricing and 100 to 400 for MaxDiff.

The study tools (`list_simulations` to `get_credits`) do what the web
app does with a study you ran. `ask_followup` works where the web app
offers a follow-up chat, on votes and debates (`run_focus_group`,
`run_debate`) and Screening Room Deep Reviews; on any other study it
returns `not_supported` and charges nothing. It costs what the web
charges; on Free, Pro and Max its answers, like your results, come as
totals: they describe the panel and its groups and do not name or quote
individual respondents. A `sim_id` that is not yours is `not_found`, as
for `get_simulation`.

Your limits follow your plan: buy Pro or Max, or join an organization
on one, and your existing key or connector gets the new limits within
about 30 seconds, as the web app does.

## Limits by plan

| | Free | Pro | Max | Enterprise |
|---|---|---|---|---|
| Respondents per study | 20 | 500 | 1,000 | 750 (Pro) / 2,000 (Max) |
| `compare_options` options | 3 | 5 | 10 | 5 (Pro) / 10 (Max) |
| `screen_creatives` creatives | 2 | 3 | 4 | 3 (Pro) / 4 (Max) |
| Screening Room panel | the tier's: 35 / 150 / 400 | same | same | the tier's, or a size you choose above its minimum |
| `test_ads` creatives · panel | 1-4 · 100 / 200 / 400 / 1,000 | same | same | 1-4 · any size from 20 to 1,000 |
| Requests per minute | 5 | 30 | 120 | per plan |
| Monthly ceiling | none: your credits | none: your credits | none: your credits | per plan or agreement |
| Results | totals | totals | totals | totals, or respondent-level with the Custom API add-on |

On Free, Pro and Max the tools also take the web's 17 answer languages
and `image_url` (a public link to an image the panel considers), and the
saved-panel arguments are Enterprise-only. `screen_creatives` takes each
creative as a public https link straight to the file (PNG/JPG/WEBP/GIF up
to 10 MB, MP4/MOV/WebM/AVI/MKV/M4V up to 100 MB); the server fetches it
before anything is charged, so a bad link costs nothing. `test_ads` takes
its creatives the same way, with the ad copy and placement as `campaign`. The
hosted endpoint checks every call before it runs (an off-plan call comes
back as `not_on_your_plan` or `over_plan_cap`, naming the limit to retry
with), and the API checks it again.

Studies use credits from your CrowdOS balance, the same as on the web
app; every run returns `billing.credits_charged`. Buy credit packs at
<https://crowdos.ai/account/billing>.

## Recommended flow

1. **`list_demographic_presets`** — if the user didn't pick an audience,
   propose one.
2. **`estimate_reach`** (free) — when using `custom_audience`. A `small`
   audience is **not** a blocked one: the panel is still delivered at the
   size you ask for, with every respondent matching the filter. Pass
   several related interest tags (they are OR-matched) rather than one.
3. **`preview_cost`** — the credits and seconds before committing.
4. **Confirm with the user**, then run.
5. **After the study** — `ask_followup` for questions about it,
   `share_study` / `get_report_link` to pass it on, `validate_study` and
   `record_outcome` once you know what happened. `get_credits` shows the
   balance any time.

Run tools block 5-120 s depending on panel size, and stream progress:
when your host sends a `progressToken` (the default), it shows
"47/200 respondents" live. If a call fails after the study launched, the
error carries `sim_id` and `recoverable: true` — call `get_simulation`
in 30-60 s rather than re-running, which would launch and bill a second
study.

## Errors

Failures come back as a typed envelope (`isError` set on the MCP
result). The `error` field is one of:

| `error` | When | Agent action |
|---|---|---|
| `auth_error` | 401 / 403 — a missing, revoked or disabled key | Get a fresh key |
| `not_on_your_plan` | The tool or argument isn't on this account's plan | Use what the plan offers, or upgrade |
| `over_plan_cap` | Panel larger than the plan's limit | Retry with the limit in the message |
| `validation_error` | A bad request (or one caught before sending) | Fix the request |
| `insufficient_funds` | Not enough credits | Buy a pack at `top_up_url` |
| `spend_paused` | Spending on the account is paused (e.g. an organization's monthly minimum is unpaid) | Tell the user; the `message` says who resumes it. Topping up won't help |
| `not_found` | A `sim_id` / `panel_id` that is missing or not yours | Check the id |
| `not_supported` | `ask_followup` on a study with no follow-up chat (anything but a vote, a debate or a Deep Review); nothing is charged | Read the results with `get_simulation` |
| `rate_limited` | 429 | Wait `retry_after` seconds |
| `quota_exceeded` | The monthly ceiling of an Enterprise account, or of an organization that pays for your studies, is reached | Wait for the 1st, or ask the account's admin |
| `simulation_failed` | The study failed | Inspect `sim_id`; try a smaller run |
| `stream_disconnected` / `timeout` | The connection dropped after launch | `get_simulation(sim_id)` later — do not re-run |
| `server_error` / `request_failed` | 5xx, a 409 while the study is busy (`ask_followup` while other questions on it are being answered), or the endpoint unreachable | Retry with backoff |
| `configuration_error` | `CROWDOS_API_KEY` unset | Fix the host config |

## Configuration

| Env var | Default | Required |
|---|---|---|
| `CROWDOS_API_KEY` | — | yes |
| `CROWDOS_MCP_URL` | `https://api.crowdos.ai/mcp` | no |
| `CROWDOS_API_BASE_URL` | — | no (older name: `<base>/mcp` is used when set) |

Both endpoint variables must be `https://` URLs (plain `http://` only for
`localhost`, `127.0.0.1` or `::1`): your key travels in every request's
headers, so the relay refuses an endpoint that would send it unencrypted.

## Versioning

Semver. 1.0.0 made the package a relay, so the tool surface is now the
hosted endpoint's and follows the API's own deploys; the package itself
changes only when the relay does.

> **Releasing:** tag a commit already on `main` —
> `git tag mcp-v<version> && git push origin mcp-v<version>` — and
> `.github/workflows/publish-mcp.yml` builds and publishes to PyPI over
> Trusted Publishing. The run stops before building if the commit is not
> on `main`, if the tag, `pyproject.toml` and `__init__.py` disagree, if
> the tests fail, or if the built server does not start on the installed
> SDK.

### Changelog

- **1.0.1** — the relay refuses an endpoint that is not `https://`
  (plain `http://` stays allowed for a local API), so a typo in
  `CROWDOS_MCP_URL` can no longer send the key in clear text.
- **1.0.0** — the package relays to `https://api.crowdos.ai/mcp`
  instead of calling the REST API itself: tools, limits and checks come
  from the hosted endpoint for your key's account. Every plan can use
  it (the REST API is for Enterprise accounts since Oct 10, 2026).
  Progress notifications and the `sim_id` on a dropped stream are
  relayed. New `CROWDOS_MCP_URL`.
- **0.12.x** — the last releases that called the REST API directly.

## License

MIT.

## Issues / questions

Email <hello@motifmotion.sg>. Setup guide: <https://crowdos.ai/mcp>.
