openapi: 3.0.1
info:
  title: MCP Server API
  description: |
    The Alloy MCP Server API enables you to create and manage MCP (Model Context Protocol) servers that provide secure, controlled access to platform integrations for AI assistants.

    ## Key Features
    - Dynamic tool discovery and execution
    - Fine-grained access restrictions
    - JWT-based user isolation
    - Self-sufficient token URLs
    - Support for 21+ platform connectors
  version: "2.0"
  contact:
    name: Alloy Support
    email: support@runalloy.com
    url: https://runalloy.com
servers:
  - url: https://mcp.runalloy.com
    description: Production server
  - url: http://localhost:3000
    description: Local development server
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT or API Key
      description: Use either an Alloy API key or JWT token
  schemas:
    ServerRestrictions:
      type: object
      properties:
        connectors:
          type: object
          properties:
            mode:
              type: string
              enum: [allowlist, blocklist]
            allowedIds:
              type: array
              items:
                type: string
            blockedIds:
              type: array
              items:
                type: string
        actions:
          type: object
          properties:
            mode:
              type: string
              enum: [allowlist, blocklist]
            allowedActions:
              type: array
              items:
                type: string
            blockedActions:
              type: array
              items:
                type: string
        users:
          type: object
          properties:
            mode:
              type: string
              enum: [allowlist, blocklist]
            allowedIds:
              type: array
              items:
                type: string
            blockedIds:
              type: array
              items:
                type: string
    Server:
      type: object
      properties:
        serverId:
          type: string
          description: Unique server identifier
        name:
          type: string
          description: Server name
        description:
          type: string
          description: Server description
        url:
          type: string
          description: Base URL for API-authenticated access
        accessUrl:
          type: string
          description: Self-sufficient URL with embedded token
        restrictions:
          $ref: '#/components/schemas/ServerRestrictions'
        hasRestrictions:
          type: boolean
          description: Whether server has active restrictions
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    MCPRequest:
      type: object
      required:
        - jsonrpc
        - method
        - id
      properties:
        jsonrpc:
          type: string
          enum: ["2.0"]
        method:
          type: string
          enum: [tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get]
        params:
          type: object
        id:
          type: string
    MCPResponse:
      type: object
      properties:
        jsonrpc:
          type: string
          enum: ["2.0"]
        result:
          type: object
        error:
          type: object
          properties:
            code:
              type: integer
            message:
              type: string
        id:
          type: string
    Tool:
      type: object
      properties:
        name:
          type: string
          description: Tool identifier
        description:
          type: string
          description: Human-readable description
        inputSchema:
          type: object
          description: JSON Schema for tool parameters
tags:
  - name: Server Management
    description: Create and manage MCP servers
  - name: MCP Protocol
    description: Execute MCP protocol operations
  - name: Tools
    description: Discover and execute tools
  - name: Resources
    description: Access server resources
  - name: Prompts
    description: Access prompt templates
paths:
  /api/servers:
    post:
      tags:
        - Server Management
      summary: Create a new MCP server
      description: Creates a new MCP server with specified configuration and restrictions
      operationId: create-server
      security:
        - bearerAuth: []
      parameters:
        - name: x-alloy-userid
          in: header
          description: User ID for server ownership (optional with API key)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
                  description: Server name (1-100 characters)
                  minLength: 1
                  maxLength: 100
                description:
                  type: string
                  description: Server description
                customInstructions:
                  type: string
                  description: Custom instructions for AI assistants (beta)
                tokenExpiresInDays:
                  type: integer
                  description: Token expiration in days (1-365)
                  minimum: 1
                  maximum: 365
                restrictions:
                  $ref: '#/components/schemas/ServerRestrictions'
              example:
                name: "Production Server"
                description: "Main production MCP server with restricted access"
                tokenExpiresInDays: 90
                restrictions:
                  connectors:
                    mode: "allowlist"
                    allowedIds: ["slack", "notion", "hubspot"]
      responses:
        '201':
          description: Server created successfully
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Server'
                  - type: object
                    properties:
                      accessToken:
                        type: string
                        description: Access token (only returned on creation)
              example:
                serverId: "production-server-a1b2c3d4"
                name: "Production Server"
                description: "Main production MCP server"
                url: "https://mcp.runalloy.com/mcp/production-server-a1b2c3d4"
                accessUrl: "https://mcp.runalloy.com/mcp/production-server-a1b2c3d4/mcp_token_xyz789"
                accessToken: "mcp_token_xyz789"
                restrictions:
                  connectors:
                    mode: "allowlist"
                    allowedIds: ["slack", "notion", "hubspot"]
                createdAt: "2024-01-01T00:00:00Z"
                updatedAt: "2024-01-01T00:00:00Z"
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
              example:
                error: "Invalid payload"
        '401':
          description: Unauthorized
        '409':
          description: Server name already exists
    get:
      tags:
        - Server Management
      summary: List all servers
      description: Returns a list of all servers for the authenticated user
      operationId: list-servers
      security:
        - bearerAuth: []
      parameters:
        - name: x-alloy-userid
          in: header
          description: User ID to filter servers (optional with API key)
          schema:
            type: string
      responses:
        '200':
          description: List of servers
          content:
            application/json:
              schema:
                type: object
                properties:
                  servers:
                    type: array
                    items:
                      $ref: '#/components/schemas/Server'
                  count:
                    type: integer
                    description: Total number of servers
              example:
                servers:
                  - serverId: "production-server-a1b2c3d4"
                    name: "Production Server"
                    description: "Main production MCP server"
                    url: "https://mcp.runalloy.com/mcp/production-server-a1b2c3d4"
                    accessUrl: "https://mcp.runalloy.com/mcp/production-server-a1b2c3d4/mcp_token_xyz789"
                    createdAt: "2024-01-01T00:00:00Z"
                count: 15
        '401':
          description: Unauthorized
  /api/servers/{serverId}:
    get:
      tags:
        - Server Management
      summary: Get server details
      description: Returns detailed information about a specific server
      operationId: get-server
      security:
        - bearerAuth: []
      parameters:
        - name: serverId
          in: path
          required: true
          description: Server ID
          schema:
            type: string
        - name: x-alloy-userid
          in: header
          description: User ID (optional with API key)
          schema:
            type: string
      responses:
        '200':
          description: Server details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Server'
        '401':
          description: Unauthorized
        '404':
          description: Server not found
    put:
      tags:
        - Server Management
      summary: Update server configuration
      description: Updates server name, description, instructions, or restrictions
      operationId: update-server
      security:
        - bearerAuth: []
      parameters:
        - name: serverId
          in: path
          required: true
          description: Server ID
          schema:
            type: string
        - name: x-alloy-userid
          in: header
          description: User ID (optional with API key)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 100
                description:
                  type: string
                restrictions:
                  $ref: '#/components/schemas/ServerRestrictions'
      responses:
        '200':
          description: Server updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Server'
        '400':
          description: Invalid request
        '401':
          description: Unauthorized
        '404':
          description: Server not found
    delete:
      tags:
        - Server Management
      summary: Delete server
      description: Permanently deletes a server and all associated data
      operationId: delete-server
      security:
        - bearerAuth: []
      parameters:
        - name: serverId
          in: path
          required: true
          description: Server ID
          schema:
            type: string
        - name: x-alloy-userid
          in: header
          description: User ID (optional with API key)
          schema:
            type: string
      responses:
        '200':
          description: Server deleted successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Server deleted"
                  serverId:
                    type: string
                    example: "production-server-a1b2c3d4"
        '401':
          description: Unauthorized
        '404':
          description: Server not found
  /mcp/{serverId}/{accessToken}:
    post:
      tags:
        - MCP Protocol
      summary: Execute MCP request (Token URL)
      description: |
        Execute MCP protocol operations using a self-sufficient token URL.
        No additional authentication headers required.
      operationId: execute-mcp-token
      parameters:
        - name: serverId
          in: path
          required: true
          description: Server ID
          schema:
            type: string
        - name: accessToken
          in: path
          required: true
          description: Access token
          schema:
            type: string
        - name: Content-Type
          in: header
          description: Request content type
          required: true
          schema:
            type: string
            default: "application/json"
        - name: Accept
          in: header
          description: Response format - must include text/event-stream for MCP
          required: true
          schema:
            type: string
            default: "application/json, text/event-stream"
        - name: x-alloy-user-token
          in: header
          description: JWT token for user isolation (optional)
          schema:
            type: string
        - name: x-alloy-userid
          in: header
          description: Override user ID (optional)
          schema:
            type: string
        - name: x-credential-id
          in: header
          description: Specific credential to use (optional)
          schema:
            type: string
        - name: x-redirect-uri
          in: header
          description: OAuth redirect URI for credential creation (optional)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCPRequest'
            examples:
              listTools:
                summary: List available tools
                value:
                  jsonrpc: "2.0"
                  method: "tools/list"
                  id: "1"
              executeAction:
                summary: Execute an action
                value:
                  jsonrpc: "2.0"
                  method: "tools/call"
                  params:
                    name: "execute_action_alloy"
                    arguments:
                      connectorId: "slack"
                      actionId: "chat_postMessage"
                      parameters:
                        channel: "#general"
                        text: "Hello from MCP!"
                  id: "1"
      responses:
        '200':
          description: MCP response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCPResponse'
              examples:
                toolsList:
                  summary: Tools list response
                  value:
                    jsonrpc: "2.0"
                    result:
                      tools:
                        - name: "list_connectors_alloy"
                          description: "List available platform connectors"
                          inputSchema:
                            type: "object"
                            properties:
                              category:
                                type: "string"
                                description: "Filter by category"
                    id: "1"
        '400':
          description: Invalid request
        '401':
          description: Invalid or expired token
        '429':
          description: Rate limit exceeded
  /mcp/{serverId}:
    post:
      tags:
        - MCP Protocol
      summary: Execute MCP request (API Key)
      description: |
        Execute MCP protocol operations using API key authentication.
        Requires authentication headers.
      operationId: execute-mcp-api
      security:
        - bearerAuth: []
      parameters:
        - name: serverId
          in: path
          required: true
          description: Server ID
          schema:
            type: string
        - name: Content-Type
          in: header
          description: Request content type
          required: true
          schema:
            type: string
            default: "application/json"
        - name: Accept
          in: header
          description: Response format - must include text/event-stream for MCP
          required: true
          schema:
            type: string
            default: "application/json, text/event-stream"
        - name: x-alloy-userid
          in: header
          required: true
          description: User ID
          schema:
            type: string
        - name: x-alloy-user-token
          in: header
          description: JWT token for user isolation (optional)
          schema:
            type: string
        - name: x-credential-id
          in: header
          description: Specific credential to use (optional)
          schema:
            type: string
        - name: x-redirect-uri
          in: header
          description: OAuth redirect URI for credential creation (optional)
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MCPRequest'
      responses:
        '200':
          description: MCP response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MCPResponse'
        '400':
          description: Invalid request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden - restrictions apply
        '429':
          description: Rate limit exceeded
  /health:
    get:
      tags:
        - Health
      summary: Health check
      description: Returns the health status of the MCP server
      operationId: health-check
      responses:
        '200':
          description: Server is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [healthy]
                  timestamp:
                    type: string
                    format: date-time
              example:
                status: "healthy"
                timestamp: "2024-01-01T00:00:00Z"
security:
  - bearerAuth: []
