Skip to content

MCP Tools API

!!! info "TL;DR" HTTP+JSON endpoint for AI agents. Execute MCP tools to manage surveys, query responses, trigger workflows. Requires agent API key authentication. Errors use RFC 7807 Problem Details (application/problem+json).

Execute Tool

Call an MCP tool. The request and success bodies are plain JSON (not JSON-RPC); errors are RFC 7807 Problem Details.

POST /api/mcp/tools

Authentication: Required (agent API key)

Request Format:

{
  "tool": "create_survey",
  "arguments": {
    "title": "Q1 Product Feedback",
    "questions": [...]
  }
}

Response Format (Success — HTTP 200):

The tool's return value is wrapped in result, with the correlation request_id (format mcp_<uuid>):

{
  "result": {
    "survey_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "draft",
    "url": "https://canviq.app/surveys/550e8400-e29b-41d4-a716-446655440000"
  },
  "request_id": "mcp_2b1a9c7e-0f3d-4a8e-9b21-6e2c4d8f1a30"
}

Response Format (Error — RFC 7807):

Error responses use Content-Type: application/problem+json and the RFC 7807 shape { type, title, status, detail } plus a request_id for correlation. The HTTP status code reflects the failure category:

Status type slug When
404 not-found Survey/resource not found (or not owned by the agent)
422 validation-error Invalid arguments (missing/unknown params, bad input)
500 internal-error Unexpected infrastructure failure (the tool threw)

An expected failure (404/422) means the tool returned a structured { error, code } result; 500 means the tool threw. The failure category is carried by the HTTP status and the type slug — there is no separate code field in the wire body. (Internally a tool may set a code discriminator of not_found or validation on its return to pin the status; this is not echoed in the response.)

A 404 example:

{
  "type": "https://canviq.app/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Survey 550e8400-e29b-41d4-a716-446655440000 not found",
  "request_id": "mcp_2b1a9c7e-0f3d-4a8e-9b21-6e2c4d8f1a30"
}

A 422 validation example (details lists field-level problems when available):

{
  "type": "https://canviq.app/errors/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "Invalid tool arguments.",
  "request_id": "mcp_2b1a9c7e-0f3d-4a8e-9b21-6e2c4d8f1a30"
}

Error Codes

Errors are returned as RFC 7807 Problem Details (Content-Type: application/problem+json). The HTTP status code is the primary signal; the type slug (appended to https://canviq.app/errors/) names the category.

Status type slug Meaning
401 authentication-required No API key provided
401 invalid-api-key API key invalid, expired, or revoked
403 insufficient-scope Key lacks the required scope for the tool
404 not-found Tool or target resource not found
413 payload-too-large Request body exceeds the 1 MB limit
422 validation-error Invalid request body or tool arguments
429 rate-limited Too many requests (see Retry-After)
500 internal-error Unexpected server error (the tool threw)
503 service-unavailable Audit log write failed; request not committed

Authentication

Include the agent API key in the Authorization header:

curl -X POST https://canviq.app/api/mcp/tools \
  -H "Authorization: Bearer pk_live_your-agent-api-key" \
  -H "Content-Type: application/json" \
  -d '{"tool": "list_surveys", "arguments": {}}'

This must be a key generated from the Agent Management page (/admin/settings/agents). An SDK key or a key created via the generic API Keys wizard shares the same pk_live_/pk_test_ prefix but has no agent attached to it, and this endpoint rejects it with 401 invalid-api-key. See AI Agents → Authentication → Key types for the full key-type breakdown.

The server verifies:

  1. API key is valid and not expired
  2. Agent has required scopes for the tool
  3. Agent hasn't exceeded rate limits

If any check fails, the request is rejected with an appropriate error code.

Rate Limiting

Rate limits are enforced per agent. See the Rate Limits page for details.

Rate limit headers are included in every response:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1675123456

Example: Create Survey

Full example of creating a survey via the MCP API:

curl -X POST https://canviq.app/api/mcp/tools \
  -H "Authorization: Bearer pk_live_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "create_survey",
    "arguments": {
      "title": "Q1 Product Feedback",
      "description": "Help us improve",
      "questions": [
        {
          "type": "nps",
          "text": "How likely are you to recommend us?",
          "required": true
        },
        {
          "type": "text",
          "text": "What can we improve?",
          "required": false
        }
      ],
      "settings": {
        "allow_multiple_responses": false
      }
    }
  }'

Response:

{
  "result": {
    "survey_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "draft",
    "url": "https://canviq.app/surveys/550e8400-e29b-41d4-a716-446655440000"
  },
  "request_id": "mcp_2b1a9c7e-0f3d-4a8e-9b21-6e2c4d8f1a30"
}

Planned Features

The following capabilities are on the roadmap but not yet implemented. Do not attempt to use these endpoints in production agents.

  • Tool discovery (tools/list) — a GET /api/mcp/tools or JSON-RPC tools/list method that returns the full tool registry with schemas.
  • Natural Language Mode — sending mode: natural_language with a plain English prompt instead of a structured { tool, arguments } body.
  • SSE Streaming (/api/mcp/stream/...) — server-sent event streams for long-running tool executions.
  • Subscribe (POST /api/mcp/subscribe) — realtime event subscriptions for survey responses and lifecycle changes.

These sections will be documented here when the endpoints ship.

What's Next