Skip to main content

Overview

The anonymous MCP endpoint provides API key-based authentication for MCP tool calls, allowing execution without OAuth setup. This is ideal for:
  • Self-hosted deployments
  • CI/CD integrations
  • Automated workflows
  • Service-to-service communication

Endpoint

POST https://your-deployment.convex.site/mcp/anonymous?workspaceId=<WORKSPACE_ID>
Legacy endpoints also supported:
  • POST /v1/mcp/anonymous
  • GET /mcp/anonymous (for MCP protocol negotiation)
  • DELETE /mcp/anonymous (for session cleanup)

Authentication

API keys can be provided in two ways:
curl -X POST "https://your-deployment.convex.site/mcp/anonymous?workspaceId=ws_123" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","id":1,"params":{"name":"execute","arguments":{"code":"return 1+1"}}}'

Requirements

1

Generate API Key

Create an API key from the Executor web UI:
  1. Navigate to Settings → API Keys
  2. Click “Generate New Key”
  3. Copy the key (shown only once)
  4. Store securely in your environment
2

Get Workspace ID

Find your workspace ID in the web UI:
  • Settings → Workspace → Workspace ID
  • Or extract from URL: https://app.executor.sh/workspace/<WORKSPACE_ID>
3

Include in Query Parameter

The workspaceId query parameter is required for all anonymous endpoint requests.

Security

API keys provide full workspace access. Treat them like passwords:
  • Store in environment variables or secrets managers
  • Never commit to version control
  • Rotate regularly
  • Use separate keys per environment/service

Key Verification

The endpoint verifies:
  1. API key signature - Uses MCP API key signing configured on server
  2. Workspace match - API key must be issued for the requested workspace
  3. Account access - Account associated with key must have workspace access
  4. Anonymous provider - Currently restricted to anonymous accounts only

Error Responses

400 Bad Request
Missing workspaceId query parameter
401 Unauthorized
Missing or invalid API key
403 Forbidden
  • API key does not match requested workspace
  • Account lacks workspace access
  • API key auth not enabled for account type
503 Service Unavailable
MCP API key signing not configured on server

MCP Protocol

The anonymous endpoint implements the full MCP (Model Context Protocol) specification:

Supported Methods

List all available tools in the workspace
{
  "jsonrpc": "2.0",
  "method": "tools/list",
  "id": 1
}
Execute a tool (typically execute for code execution)
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "id": 1,
  "params": {
    "name": "execute",
    "arguments": {
      "code": "return tools.catalog.namespaces({})"
    }
  }
}
Initialize MCP session and negotiate capabilities
{
  "jsonrpc": "2.0",
  "method": "initialize",
  "id": 1,
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {},
    "clientInfo": {
      "name": "my-client",
      "version": "1.0.0"
    }
  }
}

Session Management

Sessions are automatically managed:
  • Automatic creation - New anonymous workspace/account context created per request if needed
  • Session IDs - Include sessionId in execute arguments to group related tasks
  • Ephemeral state - Each request uses fresh or session-scoped context
  • No cleanup required - Sessions expire automatically
Session ID Example
{
  "name": "execute",
  "arguments": {
    "code": "return tools.fs.read({ path: '/data.json' })",
    "sessionId": "my-batch-job-001"
  }
}

Complete Example

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';

const API_KEY = process.env.EXECUTOR_API_KEY;
const WORKSPACE_ID = process.env.EXECUTOR_WORKSPACE_ID;
const BASE_URL = 'https://your-deployment.convex.site';

const client = new Client({
  name: 'my-service',
  version: '1.0.0'
}, {
  capabilities: {}
});

const transport = new WebSocketClientTransport(
  new URL(`/mcp/anonymous?workspaceId=${WORKSPACE_ID}`, BASE_URL),
  {
    headers: {
      'Authorization': `Bearer ${API_KEY}`
    }
  }
);

await client.connect(transport);

// Execute code
const result = await client.callTool('execute', {
  code: 'return await tools.github.repos.get({ owner: "octocat", repo: "hello-world" })',
  timeoutMs: 30000
});

console.log(result);

Configuration

Server-side configuration (environment variables):
.env
# Required for anonymous endpoint
EXECUTOR_MCP_API_KEY_SECRET=<secret_for_signing_keys>

# Optional: disable OAuth requirement
EXECUTOR_DEPLOYMENT_MODE=self-hosted
# or
EXECUTOR_ENFORCE_MCP_AUTH=false

Comparison with OAuth Endpoint

Feature/mcp/anonymous/mcp
AuthenticationAPI KeyWorkOS OAuth
Setup ComplexityLowMedium
User ContextAnonymousAuthenticated user
Use CaseService integrationUser-facing applications
Workspace IDRequired in queryRequired in query
Rate LimitsPer workspacePer user/workspace

Rate Limits

Same rate limits as the authenticated endpoint:
  • Default: 100 requests per minute per workspace
  • Configurable in workspace settings
  • Returns HTTP 429 when exceeded

Build docs developers (and LLMs) love