# User Studies MCP

Run synthetic user studies from an agent. All participant responses are synthetic hypotheses, not real customer evidence.

## Endpoint

- Hosted: `https://userstudies.ai/api/mcp` (Streamable HTTP, MCP SDK 2.0.0)
- Local dev: `http://127.0.0.1:8780/api/mcp`

## Auth (direct Bearer, not OAuth)

1. Open `https://userstudies.ai/agents.html` in your browser.
2. Click Generate agent token. This binds your current anonymous browser owner to the token.
3. Token lasts 30 days, revocable. Generating again replaces the previous token.
4. Send `Authorization: Bearer <token>` on every MCP and HTTP fallback request. Your MCP client must support a configurable Authorization header.
5. No global shared token. Never put tokens in downloadable files.

## Skill vs MCP registration

- Installing the skill (`GET /skills/userstudies/SKILL.md`) teaches the agent when and how to call studies. It does not connect anything.
- MCP registration connects the agent to `/api/mcp` with the Bearer token above. Both steps are required.

## Tools (names are exact)

### start_study

Start an async study. Returns a study handle; poll `get_study` for results.

```json
{
  "mode": "interview | desirability | browser_task",
  "persona": "target-customer description (required)",
  "question": "research question (interview requires question or problem)",
  "url": "https URL (browser_task, required)",
  "task": "task for simulated participants (browser_task, required)",
  "participantCount": "1-5, default 1",
  "turns": "1-12, default 6 (interview)",
  "problem": "optional context",
  "promise": "optional concept (introduced late in interview)",
  "product": "optional concept",
  "stimuli": "[{id, label, text?, image?}] 1-8 items, desirability requires it. image must be an inline data URL (PNG/JPEG/WebP, <=1MB each). No remote URLs.",
  "proposition": "optional follow-up proposition (desirability)",
  "intendedAttributes": "optional string[<=20]",
  "idempotencyKey": "required; reuse returns the same study"
}
```

### get_study

```json
{ "studyId": "required", "detail": "summary | transcript | evidence (default summary)", "participantId": "optional", "cursor": "integer >=0, default 0", "limit": "1-100, default 20" }
```

Use `summary` for status plus findings, `transcript` for interview turns or browser events, and `evidence` for desirability responses/SVG visuals or browser latest frames/outcomes. Browser transcript/evidence cursors are event sequence IDs, not offsets; follow nextCursor even if a participant filter yields an empty page. Historical frame events are available in both transcript and evidence pages. The first evidence page also includes up to two current snapshots per participant (latest frame and outcome), in addition to the bounded event page.

### stop_study

```json
{ "studyId": "required" }
```

Stops the run and preserves completed work.

## Modes

- interview: end-to-end adaptive interview (default 6 turns), isolated personas. Discovery first; promise/product introduced as a hypothetical concept late.
- desirability: initial reaction first (up to 5 balanced words per stimulus, proposition withheld), then proposition follow-up. Results include per-stimulus word counts plus an SVG visual. Counts describe synthetic selections only; never report prevalence or demand.
- browser_task: uses the existing durable task-run infrastructure. Qwen generates the synthetic persona and step captions; Jev chooses observed browser actions. Evidence includes real frames, synthetic cursor targets, and synthetic before/after narration. A separate final-page judgment checks Jev's completion claim. Treat both the participant and judgment as simulated evidence.

## HTTP fallback

Same bodies and Bearer header:

```bash
curl -X POST https://userstudies.ai/api/studies/start \
  -H "Authorization: Bearer $AGENT_TOKEN" -H "Content-Type: application/json" \
  -d '{"mode":"interview","persona":"freelance designer","question":"How do you collect client feedback?","participantCount":1,"turns":6,"idempotencyKey":"demo-001"}'

curl -X POST https://userstudies.ai/api/studies/get \
  -H "Authorization: Bearer $AGENT_TOKEN" -H "Content-Type: application/json" \
  -d '{"studyId":"<id>","detail":"summary"}'

curl -X POST https://userstudies.ai/api/studies/stop \
  -H "Authorization: Bearer $AGENT_TOKEN" -H "Content-Type: application/json" \
  -d '{"studyId":"<id>"}'
```

## Data handling

- Storage: local SQLite / hosted Postgres. Browser-task models: Jev/TypeSafe and Qwen/Cerebras through the hosted execution-scoped gateway. Interview and desirability models remain on OpenRouter. Hosted browser sessions remain isolated Modal sandboxes.
- Qwen receives bounded visible page text and control values to narrate and judge steps. Use test accounts and avoid sensitive form data or private pages.
- No new retention promise. Every result is labeled SYNTHETIC / simulated_reactions.

## Verified compatibility

- Official TypeScript SDK 2.0.0 implements MCP 2026-07-28 through its request-scoped HTTP handler. The SDK supplies stateless compatibility with 2025-era clients. Both modern and legacy client discovery/calls are tested locally; see repository verification evidence for the final test results.
- Pending primary verification: production deployment, native browser WebMCP compatibility. Registration and shared HTTP dispatch are covered by an isolated browser-API fixture; this is not a native-browser compatibility claim.

## Install the skill

Download `/skills/userstudies/SKILL.md` using the link on `/agents.html`. Put it in a folder named `userstudies` in your agent client's supported skills directory. This is plain UTF-8 Markdown and requires no installation script. Preserve any existing skill before replacing it.

For a client supporting remote MCP URL plus headers, configure the endpoint and token separately:

```json
{"url":"https://userstudies.ai/api/mcp","headers":{"Authorization":"Bearer <your-private-token>"}}
```

This is the connection object, not a universal client configuration file. Use your client's documented MCP settings; no active client configuration is modified by downloading the skill. OAuth-only clients are not supported by this direct-token integration.

## Runtime and deployment

This change is local-ready until explicitly deployed. Render must serve the new static files from `frontend/`; the existing `/api/*` rewrite carries MCP and study calls to the hosted coordinator. If a reverse proxy forwards its upstream hostname, explicitly configure that hostname in `STUDY_ALLOWED_HOSTS`; do not accept arbitrary forwarded host headers. The public hostname and actual clients must be verified after release.

Research jobs run with two local execution slots and a ten-minute deadline. They preserve partial responses on failure/stop. Hosted research uses the existing hourly participant admission budget. Queued work is durable; expired running leases are interrupted, never replayed as fresh paid runs. Browser jobs retain their existing sandbox time limits. Browser screenshot URLs require owner authentication; MCP evidence provides references rather than making private images public.

Research requests are capped at 150 moderator/participant/analysis calls per study, in addition to the existing profile-generation request. Oversized designs/turn combinations are rejected before execution. Aggregate inline image data URLs must fit within 6,000,000 characters; each image also retains its 1,000,000-byte decoded limit.
