Skip to main content
Glama
sunsiyuan

humansurvey-mcp

by sunsiyuan

HumanSurvey

网站: humansurvey.co · 文档: humansurvey.co/docs · 常见问题: humansurvey.co/faq

human-survey MCP server

为 AI 智能体提供的反馈收集基础设施。

HumanSurvey 让执行长期任务的智能体能够从人群中收集结构化反馈:

Agent is doing a job
  → needs structured feedback from a group
  → creates survey from JSON schema
  → shares /s/{id} URL with respondents
  → humans respond over hours or days
  → agent retrieves structured JSON results and acts on them

这是什么?

HumanSurvey 是一个极简的 API 和 MCP 服务器,专注于单一任务:让智能体从人类群体中收集结构化反馈,并获取机器可用的结果。

它专为以下场景设计:

  • 运行活动管理、产品发布或社区工作流的 AI 智能体,需要对群体进行调查

  • 构建智能体产品的开发者,需要轻量级的反馈收集原语

它不适用于:

  • 调查仪表板

  • 可视化表单构建器

  • 模板库

  • 电子邮件营销活动

  • 分析/报告 UI

Related MCP server: veyra-forms

功能特性

  • JSON 模式输入 — 结构化、精确,且可直接由机器生成

  • MCP 服务器 — 直接从 Claude Code 创建调查并读取结果

  • 极简 API 接口 — 经过身份验证的创建者路由,公开的受访者提交

  • 四种语义问题类型 — choice(选择)、text(文本)、scale(量表)、matrix(矩阵)

  • 条件逻辑 — Markdown 和 JSON 模式中的 showIf

  • 明确的生命周期 — 关闭调查、过期设置和最大响应限制

产品原则

  • 语义优先于视觉:HumanSurvey 拥有一个小型的协议,而不是一堆特定于 UI 的字段类型。

  • AI 优先的 I/O:智能体编写调查,智能体消费结果;人类处于中间环节。

  • 一切皆 API:创建者功能必须通过经过身份验证的 HTTP 和 MCP 提供。

  • 窄范围胜出:如果某个功能主要服务于人类调查操作员,那么它可能不属于这里。

支持的问题类型

  • single_choice(单选)

  • multi_choice(多选)

  • text(文本)

  • scale(量表)

  • matrix(矩阵)

Markdown 语法

# Survey Title

**Description:** Instructions for the respondent.

## Section Name

**Q1. Your question here?**

- ☐ Option A
- ☐ Option B
- ☐ Option C

**Q2. Multi-select question?** (select all that apply)

- ☐ Choice 1
- ☐ Choice 2
- ☐ Choice 3

**Q3. Open-ended question:**

> _______________

| # | Item | Rating |
|---|------|--------|
| 1 | Item A | ☐Good ☐OK ☐Bad |
| 2 | Item B | ☐Good ☐OK ☐Bad |

量表问题:

**Q4. How severe is this issue?**

[scale 1-5 min-label="Low" max-label="Critical"]

条件逻辑:

**Q1. Did the deploy fail?**

- ☐ Yes
- ☐ No

**Q2. Which step failed?**

> show if: Q1 = "Yes"

> _______________________________________________

快速入门

在 Claude Code 中使用

添加到你的 Claude Code 配置 (~/.claude.json) 中:

{
  "mcpServers": {
    "survey": {
      "command": "npx",
      "args": ["-y", "humansurvey-mcp"],
      "env": {
        "HUMANSURVEY_API_KEY": "hs_sk_your_key_here"
      }
    }
  }
}

然后在 Claude Code 中:

> Create a post-event feedback survey with a 1-5 rating, open text, and a yes/no question

可用工具:

  • create_key — 自行配置 API 密钥;无需人工设置

  • create_survey — 从 JSON 模式创建;可选 max_responses、expires_at、webhook_url

  • get_results — 汇总结果 + 原始响应

  • list_surveys — 列出你的密钥拥有的调查

  • close_survey — 立即关闭调查

使用 HTTP API

curl -X POST https://www.humansurvey.co/api/keys \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my claude agent",
    "email": "you@example.com",
    "wallet_address": "eip155:8453:0xabc..."
  }'

所有字段均为可选。wallet_address 使用 CAIP-10 格式 — 未来将用于智能体原生支付。

然后创建一个调查:

curl -X POST https://www.humansurvey.co/api/surveys \
  -H "Authorization: Bearer hs_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "schema": {
      "title": "Post-Event Feedback",
      "sections": [{
        "questions": [
          { "type": "scale", "label": "How would you rate the event?", "min": 1, "max": 5 },
          { "type": "text", "label": "What should we improve?" }
        ]
      }]
    }
  }'

响应:

{
  "survey_url": "/s/abc123",
  "question_count": 1
}

读取结果:

curl https://www.humansurvey.co/api/surveys/abc123/responses \
  -H "Authorization: Bearer hs_sk_..."

公开资源

  • 文档页面:https://www.humansurvey.co/docs

  • OpenAPI:https://www.humansurvey.co/api/openapi.json

  • AI 索引:https://www.humansurvey.co/llms.txt

技术栈

组件

技术

框架

Next.js (App Router)

数据库

Neon (无服务器 Postgres)

解析器

remark (unified 生态系统)

前端

React + Tailwind CSS

MCP 服务器

@modelcontextprotocol/sdk

部署

Vercel

项目结构

├── apps/web/          # Next.js app (API + frontend)
├── packages/parser/   # Markdown → Survey JSON parser
├── packages/mcp-server/ # MCP server for Claude Code
└── docs/              # Architecture docs

贡献

在提交 PR 之前,请阅读 CONTRIBUTING.md。最重要的规则是保持范围克制:新的 UI 变体、分析仪表板和人类操作员功能通常不在本项目的范围内。

开发

pnpm install
pnpm dev              # Start Next.js dev server
pnpm --filter @mts/parser test
pnpm build            # Build all packages

许可证

MIT

Available Tools

5 tools
close_surveyClose SurveyA

Permanently close a survey so it no longer accepts new responses. Use this when you have enough responses or the data collection window has passed. Returns the final response count. Closing is irreversible via MCP — use PATCH /api/surveys/{id} to re-open.

ParametersJSON Schema
NameRequiredDescriptionDefault
survey_idYesThe survey ID to close

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses permanence ('Permanently close', 'irreversible via MCP') and return value ('Returns the final response count'). With no annotations, this covers key behavioral traits, though auth or side effects are not mentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: first states purpose, second adds usage context and alternative. Front-loaded and no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one param and no output schema, the description covers purpose, when to use, irreversibility, and return value fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter survey_id, with 100% schema coverage. The description doesn't add extra meaning beyond the schema's 'The survey ID to close', but this is sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'close' and the resource 'survey' with the effect of no longer accepting new responses. This distinguishes it from siblings like create_survey, list_surveys, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Use this when you have enough responses or the data collection window has passed.' Also provides an alternative for re-opening via PATCH, guiding when not to use it irreversibly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_keyCreate API KeyA

Create a new HumanSurvey API key. Call this before any other tool if HUMANSURVEY_API_KEY is not set. Returns a key — store it as HUMANSURVEY_API_KEY in your MCP config. The key cannot be retrieved again after creation.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoA label for this key, e.g. the project or agent name.
emailNoContact email of the human owner. Used for billing and usage notifications in the future.
wallet_addressNoOptional wallet address in CAIP-10 format (e.g. "eip155:8453:0xabc..." for Base, "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:ABC..." for Solana). Will be used for agent-native payments in the future.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses that the key 'cannot be retrieved again after creation', a critical behavioral trait. No annotations exist, so the description carries the full burden; it is informative but could mention auth or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences with no wasted words: first defines purpose, second gives usage context, third reveals a critical constraint. Front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple create-key tool with no output schema, the description adequately covers the action, prerequisite, and key irreversibility. Could mention return format or failure cases for full completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all parameters. The description adds no parameter-level details beyond the schema, meeting the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states 'Create a new HumanSurvey API key', a specific verb+resource. Sibling tools are about surveys, so this tool is distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Call this before any other tool if HUMANSURVEY_API_KEY is not set', giving clear when-to-use context. Does not list alternatives, but siblings are unrelated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_surveyCreate SurveyA

Use this when an agent task involves collecting structured feedback or data from a group of people. Common cases: post-event attendee feedback, product satisfaction after a launch, team health checks, customer ratings after support resolution. The schema parameter is fully typed — follow the field types rather than guessing. Returns a survey_url to share with respondents and a survey_id to pass to get_results later. The survey accepts responses immediately and stays open until you close it or it expires. Embedding: append "?embed=1" to the returned survey_url to render inside an on any host site (onboarding/lead-capture flows). The embedded form posts events to window.parent with source: "humansurvey" — type "loaded", "resize" (with height), and "submitted" (with responseId and answers). See https://www.humansurvey.co/llms.txt for the full embed contract.

ParametersJSON Schema
NameRequiredDescriptionDefault
schemaYesSurvey definition. Each question is a discriminated union keyed by type: single_choice, multi_choice, text, scale, or matrix. Use the typed fields below — do not send free-form JSON.
max_responsesNoOptional. Close the survey automatically after this many responses.
expires_atNoOptional. ISO 8601 datetime — close the survey automatically at this time (e.g. "2026-04-14T00:00:00Z").
webhook_urlNoOptional. URL to POST to once when the survey closes. Payload: { survey_id, status: "closed", closed_reason: "manual" | "max_responses", response_count, closed_at }. Fires when you call close_survey or when max_responses is reached. Does not fire when expires_at elapses.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Discloses that surveys accept responses immediately, remain open until closed or expired, and explains embed behavior (?embed=1) with window.parent events. Also notes webhook limitations (does not fire on expiration). This goes beyond basic expectations for a creation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear front-loading: 'Use this when...' followed by examples, then schema guidance, then return values, then embed details. Each sentence serves a purpose. Slightly lengthy but not redundant; could be tightened without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description fully explains return values (survey_url, survey_id) and how to use them. Covers lifecycle (immediate acceptance, expiration, closing), embed functionality, and webhook behavior. This provides a complete mental model for the agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions on each field, including nested objects and conditional logic (showIf). The description adds minor value: advises to follow field types and mentions returns (survey_url, survey_id). But the schema already explains parameters thoroughly, so the description adds little beyond baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool's purpose: creating surveys for collecting structured feedback from groups. Provides specific examples like post-event feedback, product satisfaction, team health checks. The verb 'create' and resource 'survey' are unambiguous, and the description distinguishes it from sibling tools (close_survey, etc.) through context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use: 'when an agent task involves collecting structured feedback or data from a group of people.' Lists common use cases. However, it doesn't explicitly mention when not to use this tool or name alternatives (like using get_results for retrieving responses). The guidance is strong but lacks exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resultsGet ResultsA

Retrieve aggregated results for a survey. Shows survey status (open/closed), total response count, and per-question results: choice tallies with percentages, scale mean/median/distribution, and recent text responses. If the survey is still open, call again later to check for new responses — the output will tell you. Use close_survey when you have enough responses.

ParametersJSON Schema
NameRequiredDescriptionDefault
survey_idYesThe survey ID from the create_survey output (last segment of the survey_url, e.g. "abc123efgh45")

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses that the output indicates if survey is open and suggests re-calling. Since no annotations exist, the description compensates well, though it could explicitly state the tool is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, well-structured, and front-loaded with the core purpose. Every sentence adds value without waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description thoroughly covers the return content (status, counts, per-question details) and provides context for re-calling. Completeness is high for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with an already detailed description of survey_id. The description adds no extra meaning beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies the verb 'retrieve' and resource 'aggregated results for a survey', listing specific output details (status, counts, per-question results). It clearly differentiates from siblings like close_survey.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly advises to call again if survey is open and recommends using close_survey when enough responses are collected, providing clear when-to-use and alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_surveysList SurveysA

List all surveys created with the current API key, ordered newest first. Use this to find a survey_id you need for get_results or close_survey, or to check which surveys are still open.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses ordering and scope (surveys with current API key) but no annotations exist. For a simple read-only list, this is sufficient; no destructive actions are implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with action, no waste. Efficient and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output-schema tool, description covers purpose, ordering, and use cases. Complexity is low, and description is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters, so baseline 4 applies. Description adds no parameter info as none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool lists all surveys created with the current API key, ordered newest first, and distinguishes it from sibling tools like get_results and close_survey.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use: to find a survey_id for get_results or close_survey, or check open surveys. Does not specify when not to use, but context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.2
    • Addedcreate_key
    • Changedcreate_survey5 fields changed
      • removedInput schema / properties / schema / additionalProperties
        Removed value: -{}
      • changedInput schema / properties / schema / description
        Previous value: -"Survey as a JSON schema object: { title: string, sections: [{ questions: [{ type, label, ...}] }] }. Question types: single_choice (needs options), multi_choice (needs options), text, scale (needs min/max, range ≤ 11), matrix (needs rows + columns). Add showIf: { questionId, operator: \"eq\"|\"neq\"|\"contains\"|\"answered\", value } to any question for conditional logic."New value: +"Survey definition. Each question is a discriminated union keyed by type: single_choice, multi_choice, text, scale, or matrix. Use the typed fields below — do not send free-form JSON."
      • addedInput schema / properties / schema / properties
        Added value: +{
        +  "description": {
        +    "description": "Optional intro text shown on the welcome screen.",
        +    "type": "string"
        +  },
        +  "sections": {
        +    "description": "Survey sections, each with questions. Use a single section for simple surveys.",
        +    "items": {
        +      "properties": {
        +        "description": {
        +          "description": "Optional section description.",
        +          "type": "string"
        +        },
        +        "questions": {
        +          "description": "Questions in this section.",
        +          "items": {
        +            "oneOf": [
        +              {
        +                "properties": {
        +                  "description": {
        +                    "description": "Optional helper text shown under the question label.",
        +                    "type": "string"
        +                  },
        +                  "label": {
        +                    "description": "Question text shown to the respondent.",
        +                    "type": "string"
        +                  },
        +                  "options": {
        +                    "description": "Options the respondent chooses exactly one of.",
        +                    "items": {
        +                      "properties": {
        +                        "hasTextInput": {
        +                          "description": "Set true for an \"Other: ___\" option that lets the respondent type a free-text value.",
        +                          "type": "boolean"
        +                        },
        +                        "label": {
        +                          "description": "Option text shown to the respondent.",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "label"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "required": {
        +                    "description": "Whether an answer is required. Defaults to false.",
        +                    "type": "boolean"
        +                  },
        +                  "showIf": {
        +                    "description": "Only show this question if the condition on an earlier question is met.",
        +                    "properties": {
        +                      "operator": {
        +                        "description": "eq = referenced answer equals value; neq = not equal; contains = multi_choice selection includes value; answered = respondent gave any answer.",
        +                        "enum": [
        +                          "eq",
        +                          "neq",
        +                          "contains",
        +                          "answered"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "questionId": {
        +                        "description": "ID of the earlier question to check. IDs are assigned in order of appearance as q_0, q_1, q_2, ... across all sections. Must reference a question before the one where showIf is set.",
        +                        "type": "string"
        +                      },
        +                      "value": {
        +                        "description": "Option ID (opt_0, opt_1, ...) for eq/neq/contains — numbered per-question in option order. Omit for the answered operator.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "questionId",
        +                      "operator"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": {
        +                    "const": "single_choice",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "label",
        +                  "options"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "description": {
        +                    "description": "Optional helper text shown under the question label.",
        +                    "type": "string"
        +                  },
        +                  "label": {
        +                    "description": "Question text shown to the respondent.",
        +                    "type": "string"
        +                  },
        +                  "options": {
        +                    "description": "Options the respondent can pick one or more of.",
        +                    "items": {
        +                      "properties": {
        +                        "hasTextInput": {
        +                          "description": "Set true for an \"Other: ___\" option that lets the respondent type a free-text value.",
        +                          "type": "boolean"
        +                        },
        +                        "label": {
        +                          "description": "Option text shown to the respondent.",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "label"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "required": {
        +                    "description": "Whether an answer is required. Defaults to false.",
        +                    "type": "boolean"
        +                  },
        +                  "showIf": {
        +                    "description": "Only show this question if the condition on an earlier question is met.",
        +                    "properties": {
        +                      "operator": {
        +                        "description": "eq = referenced answer equals value; neq = not equal; contains = multi_choice selection includes value; answered = respondent gave any answer.",
        +                        "enum": [
        +                          "eq",
        +                          "neq",
        +                          "contains",
        +                          "answered"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "questionId": {
        +                        "description": "ID of the earlier question to check. IDs are assigned in order of appearance as q_0, q_1, q_2, ... across all sections. Must reference a question before the one where showIf is set.",
        +                        "type": "string"
        +                      },
        +                      "value": {
        +                        "description": "Option ID (opt_0, opt_1, ...) for eq/neq/contains — numbered per-question in option order. Omit for the answered operator.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "questionId",
        +                      "operator"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": {
        +                    "const": "multi_choice",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "label",
        +                  "options"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "description": {
        +                    "description": "Optional helper text shown under the question label.",
        +                    "type": "string"
        +                  },
        +                  "label": {
        +                    "description": "Question text shown to the respondent.",
        +                    "type": "string"
        +                  },
        +                  "required": {
        +                    "description": "Whether an answer is required. Defaults to false.",
        +                    "type": "boolean"
        +                  },
        +                  "showIf": {
        +                    "description": "Only show this question if the condition on an earlier question is met.",
        +                    "properties": {
        +                      "operator": {
        +                        "description": "eq = referenced answer equals value; neq = not equal; contains = multi_choice selection includes value; answered = respondent gave any answer.",
        +                        "enum": [
        +                          "eq",
        +                          "neq",
        +                          "contains",
        +                          "answered"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "questionId": {
        +                        "description": "ID of the earlier question to check. IDs are assigned in order of appearance as q_0, q_1, q_2, ... across all sections. Must reference a question before the one where showIf is set.",
        +                        "type": "string"
        +                      },
        +                      "value": {
        +                        "description": "Option ID (opt_0, opt_1, ...) for eq/neq/contains — numbered per-question in option order. Omit for the answered operator.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "questionId",
        +                      "operator"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": {
        +                    "const": "text",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "label"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "description": {
        +                    "description": "Optional helper text shown under the question label.",
        +                    "type": "string"
        +                  },
        +                  "label": {
        +                    "description": "Question text shown to the respondent.",
        +                    "type": "string"
        +                  },
        +                  "max": {
        +                    "description": "Highest scale value. The range (max - min + 1) must be ≤ 11.",
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  },
        +                  "maxLabel": {
        +                    "description": "Label shown at the max end, e.g. \"Very likely\".",
        +                    "type": "string"
        +                  },
        +                  "min": {
        +                    "description": "Lowest scale value (usually 0 or 1).",
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  },
        +                  "minLabel": {
        +                    "description": "Label shown at the min end, e.g. \"Not likely\".",
        +                    "type": "string"
        +                  },
        +                  "required": {
        +                    "description": "Whether an answer is required. Defaults to false.",
        +                    "type": "boolean"
        +                  },
        +                  "showIf": {
        +                    "description": "Only show this question if the condition on an earlier question is met.",
        +                    "properties": {
        +                      "operator": {
        +                        "description": "eq = referenced answer equals value; neq = not equal; contains = multi_choice selection includes value; answered = respondent gave any answer.",
        +                        "enum": [
        +                          "eq",
        +                          "neq",
        +                          "contains",
        +                          "answered"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "questionId": {
        +                        "description": "ID of the earlier question to check. IDs are assigned in order of appearance as q_0, q_1, q_2, ... across all sections. Must reference a question before the one where showIf is set.",
        +                        "type": "string"
        +                      },
        +                      "value": {
        +                        "description": "Option ID (opt_0, opt_1, ...) for eq/neq/contains — numbered per-question in option order. Omit for the answered operator.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "questionId",
        +                      "operator"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": {
        +                    "const": "scale",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "label",
        +                  "min",
        +                  "max"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "columns": {
        +                    "description": "Columns of the matrix — each column defines the options used for every row.",
        +                    "items": {
        +                      "properties": {
        +                        "label": {
        +                          "description": "Column label.",
        +                          "type": "string"
        +                        },
        +                        "options": {
        +                          "description": "Options shown in each cell of this column. Every row uses the same column options.",
        +                          "items": {
        +                            "properties": {
        +                              "hasTextInput": {
        +                                "description": "Set true for an \"Other: ___\" option that lets the respondent type a free-text value.",
        +                                "type": "boolean"
        +                              },
        +                              "label": {
        +                                "description": "Option text shown to the respondent.",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "label"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          "minItems": 1,
        +                          "type": "array"
        +                        }
        +                      },
        +                      "required": [
        +                        "label",
        +                        "options"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "description": {
        +                    "description": "Optional helper text shown under the question label.",
        +                    "type": "string"
        +                  },
        +                  "label": {
        +                    "description": "Question text shown to the respondent.",
        +                    "type": "string"
        +                  },
        +                  "required": {
        +                    "description": "Whether an answer is required. Defaults to false.",
        +                    "type": "boolean"
        +                  },
        +                  "rows": {
        +                    "description": "Rows of the matrix — usually items or criteria being evaluated.",
        +                    "items": {
        +                      "properties": {
        +                        "label": {
        +                          "description": "Row label — usually an item or criterion being evaluated.",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "label"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "minItems": 1,
        +                    "type": "array"
        +                  },
        +                  "showIf": {
        +                    "description": "Only show this question if the condition on an earlier question is met.",
        +                    "properties": {
        +                      "operator": {
        +                        "description": "eq = referenced answer equals value; neq = not equal; contains = multi_choice selection includes value; answered = respondent gave any answer.",
        +                        "enum": [
        +                          "eq",
        +                          "neq",
        +                          "contains",
        +                          "answered"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "questionId": {
        +                        "description": "ID of the earlier question to check. IDs are assigned in order of appearance as q_0, q_1, q_2, ... across all sections. Must reference a question before the one where showIf is set.",
        +                        "type": "string"
        +                      },
        +                      "value": {
        +                        "description": "Option ID (opt_0, opt_1, ...) for eq/neq/contains — numbered per-question in option order. Omit for the answered operator.",
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "questionId",
        +                      "operator"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": {
        +                    "const": "matrix",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "type",
        +                  "label",
        +                  "rows",
        +                  "columns"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "minItems": 1,
        +          "type": "array"
        +        },
        +        "title": {
        +          "description": "Optional section heading.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "questions"
        +      ],
        +      "type": "object"
        +    },
        +    "minItems": 1,
        +    "type": "array"
        +  },
        +  "title": {
        +    "description": "Survey title shown to respondents on the welcome screen.",
        +    "type": "string"
        +  }
        +}
      • removedInput schema / properties / schema / propertyNames
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / schema / required
        Added value: +[
        +  "title",
        +  "sections"
        +]
  2. 4 tool updatesv0.1.0
    • First observedclose_survey
    • First observedcreate_survey
    • First observedget_results
    • First observedlist_surveys

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a distinct, non-overlapping purpose: creating API keys, creating surveys, listing surveys, retrieving results, and closing surveys. No ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (create_key, create_survey, list_surveys, get_results, close_survey), making them predictable and easy to distinguish.

Tool Count5/5

With 5 tools, the server is well-scoped for managing surveys. Each tool serves a necessary function without unnecessary bloat, fitting within the ideal range of 3-15 tools.

Completeness3/5

Covers core survey lifecycle (create, list, results, close) but lacks update and delete operations. While re-opening is possible via API, it's not exposed as a tool, creating a notable gap.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Collects user feedback with text and image support through an Electron app, allowing AI tools to gather and process user input with customizable prompts and multiple response options.
    1
    9 npm
    2
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to recruit real humans for evaluation tasks like surveys, A/B tests, and ratings on text, images, audio, and video, returning aggregated results directly into the conversation.
    13
    7
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Interactive feedback server for AI-assisted development with Web UI and desktop app support, enabling user feedback collection after AI tasks.
    2
    MIT