{
  "markdown": "<div align=\"center\">\n  <h1>@cyanheads/survey-mcp-server</h1>\n  <p><b>Transform LLMs into intelligent interviewers. A production-grade MCP server for conducting dynamic, conversational surveys with structured data collection. Features skip logic, session resume, multi-tenancy, and pluggable storage backends.</b></p>\n</div>\n\n<div align=\"center\">\n\n[![Version](https://img.shields.io/badge/Version-1.0.6-blue.svg?style=flat-square)](./CHANGELOG.md) [![MCP Spec](https://img.shields.io/badge/MCP%20Spec-2025--06--18-8A2BE2.svg?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-06-18/changelog.mdx) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.20.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Status](https://img.shields.io/badge/Status-In%20Development-yellow.svg?style=flat-square)](https://github.com/cyanheads/survey-mcp-server/issues) [![TypeScript](https://img.shields.io/badge/TypeScript-^5.9.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3.0-blueviolet.svg?style=flat-square)](https://bun.sh/) [![Code Coverage](https://img.shields.io/badge/Coverage-67.82%25-yellow.svg?style=flat-square)](./coverage/index.html)\n\n</div>\n\n---\n\n## 🛠️ Tools Overview\n\nThis server provides eight powerful tools for managing the complete survey lifecycle with LLM-driven interactions:\n\n| Tool Name                 | Description                                                                                                   |\n| :------------------------ | :------------------------------------------------------------------------------------------------------------ |\n| `survey_list_available`   | Discover available surveys in the definitions directory.                                                      |\n| `survey_start_session`    | Initialize a new session with complete survey context, all questions, and initial suggested questions.        |\n| `survey_get_question`     | Refresh a specific question's eligibility status after state changes (useful for conditional logic).          |\n| `survey_submit_response`  | Record participant answers with validation, scoring, returning updated progress and next suggested questions. |\n| `survey_get_progress`     | Check completion status, current score, remaining required/optional questions, and completion eligibility.    |\n| `survey_complete_session` | Finalize a completed session with final score summary (requires all required questions answered).             |\n| `survey_export_results`   | Export session data in CSV or JSON format with optional filtering by status, date range, etc.                 |\n| `survey_resume_session`   | Resume an incomplete session, restoring full context including answered questions and progress.               |\n\n### `survey_list_available`\n\n**Discover available surveys** loaded from your survey definitions directory.\n\n**Key Features:**\n\n- Lists all surveys discovered via recursive directory scan of `SURVEY_DEFINITIONS_PATH`\n- Returns survey metadata: ID, title, description, estimated duration, and question count\n- Optional tenant filtering for multi-tenant deployments\n\n**Example Use Cases:**\n\n- \"Show me all available surveys\"\n- \"What surveys can participants take?\"\n- \"List surveys for tenant X\"\n\n---\n\n### `survey_start_session`\n\n**Initialize a new survey session** with complete context for LLM-driven conversations.\n\n**Key Features:**\n\n- Creates new session with unique session ID and participant tracking\n- Loads complete survey definition with all questions upfront\n- Returns initial suggested questions based on survey settings (configurable min/max, defaults to 3-5) based on eligibility (unconditional questions first, required before optional)\n- Each question includes `currentlyEligible` flag and `eligibilityReason` for transparency\n- Provides `guidanceForLLM` field with conversational instructions\n- Supports session metadata for tracking source, user agent, etc.\n\n**Example Use Cases:**\n\n- \"Start the customer satisfaction survey for participant ABC123\"\n- \"Begin a new session for the Q1 feedback survey\"\n- \"Initialize survey session with metadata: source=web, userAgent=Claude\"\n\n---\n\n### `survey_get_question`\n\n**Refresh a question's eligibility** and details after session state changes.\n\n**Key Features:**\n\n- Returns current eligibility status based on latest session state\n- Provides eligibility reason (e.g., \"Conditional logic satisfied\", \"Always available\")\n- Indicates if question was already answered\n- Useful for checking if conditional questions became available after previous answers\n\n**Example Use Cases:**\n\n- \"Has question q2 become available yet?\"\n- \"Check if the follow-up question is now eligible\"\n- \"Refresh question details after the participant answered the dependency\"\n\n---\n\n### `survey_submit_response`\n\n**Record participant answers** with validation and get dynamic response guidance.\n\n**Key Features:**\n\n- Validates responses against question constraints (min/max length, patterns, required fields, etc.)\n- Calculates and returns score for response (if scoring is enabled on question options)\n- Returns validation errors with specific, actionable feedback\n- Updates session progress (percentage complete, questions answered, time remaining estimate, current score)\n- Returns `updatedEligibility` array showing newly available conditional questions\n- Provides refreshed `nextSuggestedQuestions` based on new state (count configurable per survey)\n- Includes `guidanceForLLM` with context-aware instructions\n\n**Example Use Cases:**\n\n- \"Submit answer 'very-satisfied' for question q1\"\n- \"Record the participant's email: user@example.com\"\n- \"Save free-form response with validation\"\n\n---\n\n### `survey_get_progress`\n\n**Check session status** and completion eligibility.\n\n**Key Features:**\n\n- Returns completion status: `in-progress`, `completed`, `abandoned`\n- Progress metrics: total questions, answered count, required remaining, percentage complete, current score\n- Lists all unanswered required questions (with eligibility status)\n- Lists all unanswered optional questions (with eligibility status)\n- `canComplete` boolean indicating if session can be finalized\n- `completionBlockers` array explaining what's preventing completion\n\n**Example Use Cases:**\n\n- \"How much of the survey is complete?\"\n- \"What required questions are still unanswered?\"\n- \"Can we complete the survey now?\"\n\n---\n\n### `survey_complete_session`\n\n**Finalize a completed session** when all required questions have been answered.\n\n**Key Features:**\n\n- Validates that all required questions (including conditionally required) are answered\n- Updates session status to `completed` and sets `completedAt` timestamp\n- Returns summary with total questions answered, session duration, and final score (if scoring enabled)\n- Prevents duplicate completion\n\n**Example Use Cases:**\n\n- \"Complete the survey session\"\n- \"Finalize session sess_abc123\"\n- \"Mark the survey as finished\"\n\n---\n\n### `survey_export_results`\n\n**Export session data** for analysis and reporting.\n\n**Key Features:**\n\n- Export in CSV or JSON format\n- Filter by survey ID, status, date range, and custom criteria\n- Returns formatted data with record count and generation timestamp\n- CSV format includes one row per session with flattened question responses\n- JSON format preserves full session structure\n\n**Example Use Cases:**\n\n- \"Export all completed responses for survey customer-satisfaction-q1-2025 as CSV\"\n- \"Get JSON export of sessions completed in January 2025\"\n- \"Export in-progress sessions for analysis\"\n\n---\n\n### `survey_resume_session`\n\n**Resume an incomplete session** with full context restoration.\n\n**Key Features:**\n\n- Restores complete survey context and session state\n- Returns all previously answered questions with responses\n- Provides refreshed `nextSuggestedQuestions` for remaining questions (count configurable per survey)\n- Shows elapsed time since last activity\n- Current progress summary (percentage, remaining questions, current score)\n- Includes `guidanceForLLM` with welcome-back messaging suggestions\n\n**Example Use Cases:**\n\n- \"Resume session sess_abc123\"\n- \"Continue the survey where the participant left off\"\n- \"Restore session state for participant to finish later\"\n\n## ✨ Features\n\nThis server is built on the [`mcp-ts-template`](https://github.com/cyanheads/mcp-ts-template) and inherits its rich feature set:\n\n- **Declarative Tools**: Define capabilities in single, self-contained files. The framework handles registration, validation, and execution.\n- **Robust Error Handling**: A unified `McpError` system ensures consistent, structured error responses.\n- **Pluggable Authentication**: Secure your server with zero-fuss support for `none`, `jwt`, or `oauth` modes.\n- **Abstracted Storage**: Swap storage backends (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2`) without changing business logic.\n- **Full-Stack Observability**: Deep insights with structured logging (Pino) and optional, auto-instrumented OpenTelemetry for traces and metrics.\n- **Dependency Injection**: Built with `tsyringe` for a clean, decoupled, and testable architecture.\n- **Edge-Ready**: Write code once and run it seamlessly on your local machine or at the edge on Cloudflare Workers.\n\nPlus, specialized features for **Survey Management**:\n\n- **LLM-Driven Surveys**: Tools provide rich context (progress, next suggested questions, validation results, scores) to guide natural conversation flow.\n- **Hybrid Flow Control**: Guided mode with configurable suggested questions (defaults to 3-5) + flexible ordering based on conversation context.\n- **Scoring System**: Support for quizzes and assessments with optional score fields on question options. Automatic score calculation and accumulation per session.\n- **Advanced Conditional Logic**: Support for simple skip logic and complex `AND`/`OR` multi-condition branching with eligibility tracking.\n- **JSON-Based Survey Definitions**: Define surveys in simple JSON files with recursive directory scanning.\n- **Multiple Question Types**: `free-form`, `multiple-choice`, `multiple-select`, `rating-scale`, `email`, `number`, `boolean`, and advanced types like `date`, `datetime`, `time`, and `matrix` grids.\n- **Validation Engine**: Min/max length, patterns, required fields, custom constraints, and date/time rules with extensible validator map pattern.\n- **Session Resume**: Built-in state management allows participants to pause and continue later.\n- **Help Text**: A `helpText` field on questions provides LLMs with context and guidance for asking questions naturally.\n- **Pagination Support**: Scalable data retrieval with configurable pagination for session queries and exports.\n\n## 🚀 Getting Started\n\n### MCP Client Settings/Configuration\n\nAdd the following to your MCP Client configuration file (e.g., `cline_mcp_settings.json`).\n\n```json\n{\n  \"mcpServers\": {\n    \"survey-mcp-server\": {\n      \"command\": \"bunx\",\n      \"args\": [\"@cyanheads/survey-mcp-server@latest\"],\n      \"env\": {\n        \"MCP_LOG_LEVEL\": \"info\",\n        \"SURVEY_DEFINITIONS_PATH\": \"./survey-definitions\",\n        \"SURVEY_RESPONSES_PATH\": \"./survey-responses\"\n      }\n    }\n  }\n}\n```\n\n### Prerequisites\n\n- [Bun v1.2.0](https://bun.sh/) or higher.\n\n### Installation\n\n1.  **Clone the repository:**\n\n```sh\ngit clone https://github.com/cyanheads/survey-mcp-server.git\n```\n\n2.  **Navigate into the directory:**\n\n```sh\ncd survey-mcp-server\n```\n\n3.  **Install dependencies:**\n\n```sh\nbun install\n```\n\n4.  **Explore example surveys:**\n    The `survey-definitions/` directory contains example JSON files demonstrating various question types and features. Use these as a starting point for creating your own surveys.\n\n## 🛠️ Core Capabilities: Survey Tools\n\nThis server equips AI agents with specialized tools to conduct dynamic, conversational surveys while maintaining structured data collection.\n\n### Example Interaction Flow\n\n```\n1. LLM calls survey_start_session\n   → Receives full survey context, all questions, and first 3-5 suggested questions\n\n2. LLM asks questions naturally in conversation\n   → Follows suggestions but can adapt order based on context\n   → Uses natural language while ensuring survey questions are covered\n\n3. For each answer, LLM calls survey_submit_response\n   → Receives validation feedback (re-prompts if needed)\n   → Gets score for response (if scoring enabled): \"+5 points (Total: 45)\"\n   → Gets progress update (50% complete, 2 of 4 questions answered)\n   → Refreshed suggestions with newly eligible conditional questions\n\n4. LLM can check survey_get_progress anytime\n   → Knows exactly what's required vs optional\n   → Understands what remains before completion is possible\n\n5. When all required questions answered, LLM calls survey_complete_session\n   → Session finalized with timestamp, summary, and final score\n   → Ready for export via survey_export_results\n```\n\n📖 **[View detailed specification and examples →](./docs/survey-mcp-server-spec.md)**\n\n## ⚙️ Configuration\n\nAll configuration is centralized and validated at startup in `src/config/index.ts`. Key environment variables in your `.env` file include:\n\n| Variable                  | Description                                                                    | Default                |\n| :------------------------ | :----------------------------------------------------------------------------- | :--------------------- |\n| `SURVEY_DEFINITIONS_PATH` | Path to directory containing survey JSON files (recursive scan).               | `./survey-definitions` |\n| `SURVEY_RESPONSES_PATH`   | Path to directory for storing session responses (filesystem mode).             | `./survey-responses`   |\n| `MCP_TRANSPORT_TYPE`      | The transport to use: `stdio` or `http`.                                       | `http`                 |\n| `MCP_HTTP_PORT`           | The port for the HTTP server.                                                  | `3019`                 |\n| `MCP_AUTH_MODE`           | Authentication mode: `none`, `jwt`, or `oauth`.                                | `none`                 |\n| `STORAGE_PROVIDER_TYPE`   | Storage backend: `in-memory`, `filesystem`, `supabase`, `cloudflare-kv`, `r2`. | `in-memory`            |\n| `OTEL_ENABLED`            | Set to `true` to enable OpenTelemetry.                                         | `false`                |\n| `LOG_LEVEL`               | The minimum level for logging (`debug`, `info`, `warn`, `error`).              | `info`                 |\n| `MCP_AUTH_SECRET_KEY`     | **Required for `jwt` auth.** A 32+ character secret key.                       | `(none)`               |\n| `OAUTH_ISSUER_URL`        | **Required for `oauth` auth.** URL of the OIDC provider.                       | `(none)`               |\n\n## ▶️ Running the Server\n\n### Local Development\n\n- **Build and run the production version**:\n\n  ```sh\n  # One-time build\n  bun rebuild\n\n  # Run the built server\n  bun start:http\n  # or\n  bun start:stdio\n  ```\n\n- **Run checks and tests**:\n  ```sh\n  bun devcheck # Lints, formats, type-checks, and more\n  bun test # Runs the test suite\n  ```\n\n### Cloudflare Workers\n\n1.  **Build the Worker bundle**:\n\n```sh\nbun build:worker\n```\n\n2.  **Run locally with Wrangler**:\n\n```sh\nbun deploy:dev\n```\n\n3.  **Deploy to Cloudflare**:\n    ```sh\n    bun deploy:prod\n    ```\n\n## 📂 Project Structure\n\n| Directory                   | Purpose & Contents                                                                  |\n| :-------------------------- | :---------------------------------------------------------------------------------- |\n| `survey-definitions/`       | **Survey definitions** (JSON files). Nested directories supported for organization. |\n| `survey-responses/`         | **Session responses** (when using `filesystem` provider). Organized by tenant ID.   |\n| `src/mcp-server/tools`      | **Survey tool definitions** (`survey-*.tool.ts`). 8 tools for complete lifecycle.   |\n| `src/mcp-server/resources`  | Resource definitions for survey metadata and discovery.                             |\n| `src/services/survey/`      | Survey service with filesystem provider for loading definitions.                    |\n| `src/mcp-server/transports` | Implementations for HTTP and STDIO transports, including auth middleware.           |\n| `src/storage`               | `StorageService` abstraction and all storage provider implementations.              |\n| `src/container`             | Dependency injection container registrations and tokens.                            |\n| `src/utils`                 | Core utilities for logging, error handling, performance, and security.              |\n| `src/config`                | Environment variable parsing and validation with Zod.                               |\n| `tests/`                    | Unit and integration tests, mirroring the `src/` directory structure.               |\n| `docs/`                     | Detailed specifications and guides (see `survey-mcp-server-spec.md`).               |\n\n## 🧑‍💻 Agent Development Guide\n\nFor strict rules when using this server with an AI agent, refer to the **`.clinerules`** file (or `AGENTS.md`) in this repository. Key principles include:\n\n- **Logic Throws, Handlers Catch**: Never use `try/catch` in your tool `logic`. Throw an `McpError` instead.\n- **Pass the Context**: Always pass the `RequestContext` object through your call stack for logging and tracing.\n- **Use the Barrel Exports**: Register new tools and resources only in the `index.ts` barrel files within their respective `definitions` directories.\n\n## 🤝 Contributing\n\nIssues and pull requests are welcome! If you plan to contribute, please run the local checks and tests before submitting your PR.\n\n```sh\nbun run devcheck\nbun test\n```\n\n## 📜 License\n\nThis project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.\n",
  "bytes": 18038,
  "sha": "058684ce238939b98f710b9f4cb49adabdc0ea4fb4481ed924ec06513b4836f7",
  "repo_slug": "cyanheads/survey-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_cyanheads_survey_mcp_server_9c520b7a/readme"
}