@userintuition-ai/mcp
v0.6.0
Published
MCP server for User Intuition — ask real people what they think
Maintainers
Readme
User Intuition MCP Server (Node)
An MCP (Model Context Protocol) server that exposes the User Intuition research platform to AI agents. Two domains live behind the same server:
- Human Signal — create and manage paid panel studies that ask real people what they think (Streamable HTTP surface)
- Research Platform — build & run live interview studies, recruit participants from the panel, analyze transcripts, generate reports (stdio surface)
Supports stdio (CLI) and Streamable HTTP transports. Stdio is the default and recommended for desktop clients; Streamable HTTP is for ChatGPT and other web clients.
Claude Desktop / Cursor / Claude Code / VS Code
↓ (MCP over stdio)
MCP Server (this project)
↓ (REST HTTP + Bearer token)
User Intuition Backend API
ChatGPT
↓ (MCP over Streamable HTTP + OAuth)
MCP Server (--transport streamable-http)
↓ (REST HTTP + Clerk JWT)
User Intuition Backend APIQuick Start
1. Get an API Key
Sign up at app.userintuition.ai and generate an API key from Settings > API Keys.
2. Connect Your Client
Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"userintuition": {
"command": "npx",
"args": ["-y", "@userintuition-ai/mcp"],
"env": {
"USERINTUITION_API_KEY": "ui_sk_your_key_here"
}
}
}
}Cursor — .cursor/mcp.json:
{
"mcpServers": {
"userintuition": {
"command": "npx",
"args": ["-y", "@userintuition-ai/mcp"],
"env": {
"USERINTUITION_API_KEY": "ui_sk_your_key_here"
}
}
}
}Claude Code:
claude mcp add userintuition -- npx -y @userintuition-ai/mcpThen set USERINTUITION_API_KEY in your environment.
VS Code — .vscode/settings.json:
{
"mcp.servers": {
"userintuition": {
"command": "npx",
"args": ["-y", "@userintuition-ai/mcp"],
"env": {
"USERINTUITION_API_KEY": "ui_sk_your_key_here"
}
}
}
}Tools
The server registers 29 tools + 4 prompt tools (stdio); the Streamable HTTP surface exposes the 5 Human Signal tools.
Studies (14)
| Tool | Description |
|------|-------------|
| list_studies | List your studies |
| get_study | Fetch a single study (always call BEFORE update_study) |
| create_study | Create a new study |
| update_study | PATCH a study (screener_questions REPLACES the full list) |
| delete_study | Soft-delete a study |
| stop_panels | Cancel all active panel surveys for a study |
| upload_concept_link | Add a concept-test external link (dedups by label) |
| delete_concept_link | Remove a concept-test link by id |
| list_available_panel_questions | Catalog of standard panel screener questions ({id, name}; call BEFORE adding panel screeners) |
| get_panel_question | Fetch one panel question WITH its answer options (needed to disqualify on a specific answer) |
| list_available_languages | Supported voice/interview ISO language codes |
| list_available_modes | Voice / chat / video mode catalog |
| list_study_types | Catalog of study types (Win/Loss, Churn, NPS+CSAT, Onboarding, Brand Health, etc.) with per-user recommended_slug |
| get_study_type | Fetch a single study-type row by slug, including full prompt fields |
Participants (6)
| Tool | Description |
|------|-------------|
| list_invites | List participants, filterable by study/email/sent/search |
| get_invite | Fetch a single invite |
| create_invite | Create a single invite (sends email unless issilent=true) |
| update_invite | Update mutable invite fields |
| delete_invite | Soft-delete an invite |
| send_reward | Send a reward to a participant |
Interviews (6)
| Tool | Description |
|------|-------------|
| list_calls | List interview calls, filterable by study/participant/status/quality |
| get_call | Fetch one call (includes transcript, messages, recording_url, analysis) |
| update_call | Update mutable fields (e.g. is_visible, success_evaluation) |
| delete_call | Soft-delete a call |
| get_call_usage_stats | Aggregate call counts/durations over a date range |
| generate_report | Trigger study-level report generation |
Voice & Reports (2)
| Tool | Description |
|------|-------------|
| list_voices | Catalog of available interviewer voices |
| get_study_report | Latest analysis report for a study |
Panel (1)
| Tool | Description |
|------|-------------|
| create_panel | Provision a panel survey for a study to recruit participants |
Study-Creation Playbook
The server's instructions field carries a multi-paragraph playbook so MCP clients (Claude Desktop, ChatGPT, etc.) inherit the same discipline the in-app chat experience enforces. Highlights:
- Read before write: always
get_studybeforeupdate_study; ditto invites and calls.screener_questionsREPLACES the full list, so reading first is mandatory. - Panel vs custom screeners: panel questions (
is_panel_question=true+qualification_idfromlist_available_panel_questions) and custom questions coexist — preserve both kinds. - No consent screeners: never add "Do you consent to being recorded?" / "Are you willing to participate?" — consent is handled outside screeners.
- No auto-screeners on create:
create_studyshould never auto-generate screeners. Only add them when the user explicitly asks (viaupdate_study). - Mode = flags, not a column:
enable_chat/enable_video_recording. Both false = voice (default). - Language:
voice_config.language= ISO code fromlist_available_languages. - Deletes are soft:
delete_study/delete_invite/delete_callsetdeleted_atand may be restorable from the dashboard.
Tool annotations (destructiveHint, idempotentHint, etc.) are documented per-tool in tool-hint-justifications.json.
Prompts
The server also exposes 4 MCP prompt tools that load the canonical moderator-guide templates from the backend on demand. Clients surface these as slash commands or auto-load them into context. Use them before calling create_study so the generated system_prompt matches the structure the in-app dashboard produces.
| Prompt | When to use |
|---|---|
| get_study_planning_prompt | Standard voice study (default) |
| get_chat_planning_prompt | Chat-mode study (enable_chat=true) |
| get_concept_test_planning_prompt | Concept-test voice study (is_concept_test=true) |
| get_concept_test_chat_planning_prompt | Concept-test + chat-mode (both flags true) |
Each prompt fetches GET /api/assistants/reference/study-planning-prompt?name=... at resolve time, so updates to the backend templates propagate without redeploying this server.
Installation
Zero-install (recommended)
npx -y @userintuition-ai/mcpGlobal install
npm install -g @userintuition-ai/mcp
userintuition-mcpFrom source
git clone <repo-url>
cd userintuition-mcpserver-ts
npm install
npm run build
node dist/index.jsConfiguration
Stdio Mode (default)
| Variable | Required | Description |
|----------|----------|-------------|
| USERINTUITION_API_KEY | Yes | Your API key (ui_sk_...) |
| BACKEND_URL | No | Backend API URL (defaults to https://api.userintuition.ai) |
| APP_URL | No | Dashboard URL used to build deep links returned with create_study (defaults to https://app.userintuition.ai) |
HTTP Mode (for ChatGPT)
Run with --transport streamable-http:
node dist/index.js --transport streamable-http| Variable | Required | Description |
|----------|----------|-------------|
| CLERK_PUBLISHABLE_KEY | Yes | Clerk publishable key |
| CLERK_SECRET_KEY | Yes | Clerk secret key |
| CLERK_CLIENT_ID | Yes | Clerk OAuth application client ID |
| CLERK_FRONTEND_API_URL | Yes | Clerk frontend API URL |
| REDIS_URL | No | Redis URL (falls back to in-memory) |
| SERVER_URL | No | Public URL of this server |
| HOST | No | Listen host (default 0.0.0.0) |
| PORT | No | Listen port (default 8000) |
ChatGPT Setup
- Settings > Apps & Connectors > Advanced > Enable Developer Mode
- Settings > Connectors > Create:
- Name: User Intuition
- MCP Server URL:
https://<your-deployed-url>/mcp - Authentication: OAuth (auto-discovered)
Running Locally
# Stdio mode (default)
npm run dev
# HTTP mode
npm run dev:http
# Production builds
npm run build
npm start # stdio
npm run start:http # HTTPInspecting with MCP Inspector
MCP Inspector lets you browse tools and test them interactively.
Stdio mode:
USERINTUITION_API_KEY=ui_sk_your_key_here npx @modelcontextprotocol/inspector node dist/index.jsHTTP mode:
npm run start:http
npx @modelcontextprotocol/inspector --url http://localhost:8000/mcpDeployment
Docker (HTTP mode)
docker build -t userintuition-mcp .
docker run -p 8000:8000 --env-file .env userintuition-mcpSet SERVER_URL to your public HTTPS URL. Deploy to Railway, Render, Fly.io, or any container platform.
Testing
npm install
npm test
npm run test:coverageProject Structure
├── src/
│ ├── index.ts # CLI entry point (transport selection)
│ ├── server.ts # McpServer factory + study-creation playbook instructions
│ ├── tools.ts # Thin re-export of tools/index.ts
│ ├── client.ts # Thin re-export of clients/
│ ├── auth.ts # Clerk OAuth provider (HTTP only)
│ ├── auth-context.ts # AsyncLocalStorage for token forwarding
│ ├── http.ts # Express app with OAuth + /mcp
│ ├── store.ts # Token storage (InMemory + Redis)
│ ├── config.ts # Environment variable settings
│ ├── tools/
│ │ ├── index.ts # registerTools(mcp) — transport-gated aggregator
│ │ ├── _shared.ts # getToken, textResult, errorResult
│ │ ├── human-signal.ts # 5 paid-panel tools (streamable-http only)
│ │ ├── research.ts # studies/invites/calls tools (stdio)
│ │ ├── voice.ts # voice + report tools (stdio)
│ │ ├── intelligence-hub.ts # file-search/session/studio tools (not exposed)
│ │ ├── integrations.ts # panel tool (stdio)
│ │ ├── account.ts # transactions/plans/coupon/referrals tools (not exposed)
│ │ └── account-context.ts # org/profile/feedback tools (not exposed)
│ └── clients/
│ ├── _base.ts # fetchJson, HttpStatusError, authHeaders
│ ├── human-signal.ts # HumanSignalClient
│ ├── research.ts # ResearchClient
│ ├── voice.ts # VoiceClient
│ ├── intelligence-hub.ts # IntelligenceHubClient
│ ├── integrations.ts # IntegrationsClient + panel provider client
│ ├── account.ts # AccountClient
│ └── account-context.ts # AccountContextClient
├── tests/ # vitest + msw, one file per domain
├── tool-hint-justifications.json
├── package.json
├── tsconfig.json
├── vitest.config.ts
└── Dockerfile