> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zyeta.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Service API

> API reference for managing MCP servers, connections, and OAuth authentication flows

The MCP Service provides endpoints for discovering available MCP servers, managing OAuth connections, and handling MCP instances. It integrates with Composio for OAuth flows and manages the complete lifecycle of MCP server connections.

## MCP System Overview

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Frontend
    participant MCPService
    participant Composio
    participant MCPServer

    User->>Frontend: Browse MCP Servers
    Frontend->>MCPService: GET /list_servers
    MCPService-->>Frontend: List of available servers

    User->>Frontend: Connect to Gmail
    Frontend->>MCPService: POST /connect_account
    MCPService->>Composio: Create connected account
    Composio-->>MCPService: OAuth redirect URL
    MCPService-->>Frontend: {redirect_url}

    Frontend->>User: Redirect to OAuth
    User->>MCPServer: Grant permissions
    MCPServer->>Composio: OAuth callback
    Composio->>MCPService: GET /callback
    MCPService->>Composio: Create MCP instance
    MCPService-->>Frontend: Redirect with success

    Frontend->>MCPService: POST /generate_url
    MCPService->>Composio: Generate MCP URL
    Composio-->>MCPService: MCP connection URL
    MCPService-->>Frontend: {mcp_url}
```

## Authentication

All endpoints require a valid Bearer token in the Authorization header and appropriate RBAC permissions.

**Required Permissions:**

* `mcp:read` - Read MCP servers and instances
* `mcp:write` - Connect accounts and manage instances

## Base URL

```
/api/mcp
```

## MCP Server Discovery

### List All MCP Servers

Retrieve all available MCP servers in the platform.

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET "{{baseUrl}}/api/mcp/list_servers" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/list_servers"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN"
  }

  response = requests.get(url, headers=headers)
  servers = response.json()

  # Display available servers
  for server in servers["servers"]:
      print(f"{server['name']} - {server['toolkit_name']}")
  ```

  ```typescript TypeScript theme={null}
  interface MCPServer {
    id: string;
    name: string;
    toolkit_name: string;
    toolkit_slug: string;
    toolkit_logo: string | null;
    created_at: string;
    server_instance_count: number;
  }

  const listMCPServers = async (): Promise<MCPServer[]> => {
    const response = await fetch('{{baseUrl}}/api/mcp/list_servers', {
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
      },
    });

    const data = await response.json();
    return data.servers;
  };

  // Usage
  const servers = await listMCPServers();
  console.log(`Found ${servers.length} MCP servers`);
  ```

  ```go Go theme={null}
  package main

  import (
      "encoding/json"
      "fmt"
      "net/http"
  )

  type MCPServer struct {
      ID                  string  `json:"id"`
      Name                string  `json:"name"`
      ToolkitName         string  `json:"toolkit_name"`
      ToolkitSlug         string  `json:"toolkit_slug"`
      ToolkitLogo         *string `json:"toolkit_logo"`
      CreatedAt           string  `json:"created_at"`
      ServerInstanceCount int     `json:"server_instance_count"`
  }

  type ServerListResponse struct {
      Servers []MCPServer `json:"servers"`
  }

  func listMCPServers(baseURL, token string) ([]MCPServer, error) {
      url := fmt.Sprintf("%s/api/mcp/list_servers", baseURL)

      req, _ := http.NewRequest("GET", url, nil)
      req.Header.Set("Authorization", "Bearer "+token)

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          return nil, err
      }
      defer resp.Body.Close()

      var result ServerListResponse
      json.NewDecoder(resp.Body).Decode(&result)

      return result.Servers, nil
  }

  func main() {
      servers, _ := listMCPServers("{{baseUrl}}", "YOUR_TOKEN")
      fmt.Printf("Found %d MCP servers\n", len(servers))
  }
  ```

  ```json Response theme={null}
  {
    "servers": [
      {
        "id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
        "name": "Gmail",
        "toolkit_name": "Gmail",
        "toolkit_slug": "gmail",
        "toolkit_logo": "https://logo.clearbit.com/gmail.com",
        "created_at": "2024-01-10T08:00:00Z",
        "server_instance_count": 1250
      },
      {
        "id": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7",
        "name": "Slack",
        "toolkit_name": "Slack",
        "toolkit_slug": "slack",
        "toolkit_logo": "https://logo.clearbit.com/slack.com",
        "created_at": "2024-01-10T08:00:00Z",
        "server_instance_count": 980
      },
      {
        "id": "c3d4e5f6-g7h8-9i0j-1k2l-m3n4o5p6q7r8",
        "name": "GitHub",
        "toolkit_name": "GitHub",
        "toolkit_slug": "github",
        "toolkit_logo": "https://logo.clearbit.com/github.com",
        "created_at": "2024-01-10T08:00:00Z",
        "server_instance_count": 2100
      }
    ]
  }
  ```
</CodeGroup>

**Endpoint:** `GET /api/mcp/list_servers`

**Response Fields:**

| Field                             | Type   | Description                |
| --------------------------------- | ------ | -------------------------- |
| `servers`                         | array  | List of MCP server objects |
| `servers[].id`                    | string | Server UUID                |
| `servers[].name`                  | string | Server display name        |
| `servers[].toolkit_name`          | string | Official toolkit name      |
| `servers[].toolkit_slug`          | string | URL-safe identifier        |
| `servers[].toolkit_logo`          | string | Logo URL (nullable)        |
| `servers[].created_at`            | string | ISO 8601 timestamp         |
| `servers[].server_instance_count` | number | Total user instances       |

### Get Server with Tools

Retrieve detailed information about an MCP server including all available tools.

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET "{{baseUrl}}/api/mcp/server_with_tools?server_id=a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/server_with_tools"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN"
  }
  params = {
      "server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6"
  }

  response = requests.get(url, headers=headers, params=params)
  server_details = response.json()

  print(f"Server: {server_details['name']}")
  print(f"Available Tools: {len(server_details['tools'])}")

  for tool in server_details['tools']:
      print(f"  - {tool['name']}: {tool['description']}")
  ```

  ```typescript TypeScript theme={null}
  interface MCPTool {
    name: string;
    slug: string;
    description: string;
    toolkit: string;
  }

  interface MCPServerWithTools {
    id: string;
    name: string;
    toolkit_name: string;
    toolkit_slug: string;
    toolkit_logo: string | null;
    created_at: string;
    server_instance_count: number;
    tools: MCPTool[];
  }

  const getServerWithTools = async (serverId: string): Promise<MCPServerWithTools> => {
    const response = await fetch(
      `{{baseUrl}}/api/mcp/server_with_tools?server_id=${serverId}`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN',
        },
      }
    );

    return await response.json();
  };

  // Usage
  const serverDetails = await getServerWithTools('server-uuid');
  console.log(`${serverDetails.name} has ${serverDetails.tools.length} tools`);
  ```

  ```json Response theme={null}
  {
    "id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
    "name": "Gmail",
    "toolkit_name": "Gmail",
    "toolkit_slug": "gmail",
    "toolkit_logo": "https://logo.clearbit.com/gmail.com",
    "created_at": "2024-01-10T08:00:00Z",
    "server_instance_count": 1250,
    "tools": [
      {
        "name": "List Messages",
        "slug": "gmail_list_messages",
        "description": "List messages from Gmail inbox with optional filters",
        "toolkit": "Gmail"
      },
      {
        "name": "Send Message",
        "slug": "gmail_send_message",
        "description": "Send an email message via Gmail",
        "toolkit": "Gmail"
      },
      {
        "name": "Search Messages",
        "slug": "gmail_search_messages",
        "description": "Search for messages using Gmail query syntax",
        "toolkit": "Gmail"
      },
      {
        "name": "Get Message",
        "slug": "gmail_get_message",
        "description": "Retrieve a specific message by ID",
        "toolkit": "Gmail"
      },
      {
        "name": "Delete Message",
        "slug": "gmail_delete_message",
        "description": "Move a message to trash",
        "toolkit": "Gmail"
      }
    ]
  }
  ```
</CodeGroup>

**Endpoint:** `GET /api/mcp/server_with_tools`

**Query Parameters:**

| Parameter   | Required | Type   | Description     |
| ----------- | -------- | ------ | --------------- |
| `server_id` | Yes      | string | MCP server UUID |

## Connection Management

### Connect Account (Start OAuth)

Initiate OAuth flow to connect an MCP server to the user's account.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "{{baseUrl}}/api/mcp/connect_account" \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
      "flow_type": "chat"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/connect_account"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  data = {
      "server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
      "flow_type": "chat"  # Optional: chat, settings, etc.
  }

  response = requests.post(url, headers=headers, json=data)
  result = response.json()

  # Redirect user to OAuth page
  print(f"Redirect URL: {result['redirect_url']}")
  print(f"Connected Account ID: {result['id']}")
  ```

  ```typescript TypeScript theme={null}
  interface ConnectAccountRequest {
    server_id: string;
    flow_type?: string;
  }

  interface ConnectAccountResponse {
    id: string;
    status: string;
    redirect_url: string;
    connectionData: Record<string, any>;
  }

  const connectMCPAccount = async (
    serverId: string,
    flowType?: string
  ): Promise<ConnectAccountResponse> => {
    const response = await fetch('{{baseUrl}}/api/mcp/connect_account', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        server_id: serverId,
        flow_type: flowType,
      }),
    });

    return await response.json();
  };

  // Usage
  const result = await connectMCPAccount('server-uuid', 'chat');

  // Redirect user to OAuth
  window.location.href = result.redirect_url;
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  type ConnectAccountRequest struct {
      ServerID string  `json:"server_id"`
      FlowType *string `json:"flow_type,omitempty"`
  }

  type ConnectAccountResponse struct {
      ID             string                 `json:"id"`
      Status         string                 `json:"status"`
      RedirectURL    string                 `json:"redirect_url"`
      ConnectionData map[string]interface{} `json:"connectionData"`
  }

  func connectAccount(baseURL, token, serverID string) (*ConnectAccountResponse, error) {
      url := fmt.Sprintf("%s/api/mcp/connect_account", baseURL)

      flowType := "chat"
      reqBody := ConnectAccountRequest{
          ServerID: serverID,
          FlowType: &flowType,
      }

      jsonData, _ := json.Marshal(reqBody)
      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer "+token)
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          return nil, err
      }
      defer resp.Body.Close()

      var result ConnectAccountResponse
      json.NewDecoder(resp.Body).Decode(&result)

      return &result, nil
  }

  func main() {
      result, _ := connectAccount("{{baseUrl}}", "YOUR_TOKEN", "server-uuid")
      fmt.Printf("Redirect to: %s\n", result.RedirectURL)
  }
  ```

  ```json Response theme={null}
  {
    "id": "conn_abc123xyz",
    "status": "pending",
    "redirect_url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&scope=...",
    "connectionData": {
      "authConfig": "gmail_oauth",
      "expectedParams": []
    }
  }
  ```
</CodeGroup>

**Endpoint:** `POST /api/mcp/connect_account`

**Request Body:**

| Field       | Type   | Required | Description                             |
| ----------- | ------ | -------- | --------------------------------------- |
| `server_id` | string | Yes      | MCP server UUID to connect              |
| `flow_type` | string | No       | Flow context (e.g., "chat", "settings") |

**Response Fields:**

| Field            | Type   | Description                           |
| ---------------- | ------ | ------------------------------------- |
| `id`             | string | Connected account ID from Composio    |
| `status`         | string | Connection status (usually "pending") |
| `redirect_url`   | string | OAuth URL to redirect user to         |
| `connectionData` | object | Additional connection metadata        |

**Flow:**

1. Call this endpoint with server\_id
2. Redirect user to `redirect_url`
3. User completes OAuth on external service
4. External service redirects back to callback
5. System automatically creates MCP instance
6. User redirected to frontend with success

### OAuth Callback Handler

Internal endpoint that handles OAuth callbacks from external services.

**Endpoint:** `GET /api/mcp/callback`

**Query Parameters:**

| Parameter        | Required | Type   | Description           |
| ---------------- | -------- | ------ | --------------------- |
| `mcp_server_id`  | Yes      | string | Server UUID           |
| `mcp_session_id` | Yes      | string | Session instance ID   |
| `flow_type`      | No       | string | Original flow context |

**Behavior:**

1. Validates OAuth callback
2. Updates session status to "active"
3. Auto-creates MCP instance via Composio
4. Redirects to frontend with parameters

**Frontend Redirect Format:**

```
{frontend_url}/mcp/callback?mcp_server_id={server_id}&mcp_session_id={session_id}&flow_type={flow}
```

<Accordion title="Note: This endpoint is called by OAuth providers, not by clients directly">
  The callback endpoint is configured in the OAuth application settings and is automatically invoked by the external service after user authorization. Clients should not call this endpoint directly.
</Accordion>

### Generate MCP URL

Generate the MCP connection URL for an active session.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "{{baseUrl}}/api/mcp/generate_url" \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
      "session_id": "session-uuid"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/generate_url"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  data = {
      "server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
      "session_id": "session-uuid"
  }

  response = requests.post(url, headers=headers, json=data)
  result = response.json()

  print(f"MCP URL: {result['mcp_url']}")
  # Use this URL in MCP Playground to connect to the server
  ```

  ```typescript TypeScript theme={null}
  interface GenerateURLRequest {
    server_id: string;
    session_id: string;
  }

  interface GenerateURLResponse {
    mcp_url: string;
    status: string;
  }

  const generateMCPUrl = async (
    serverId: string,
    sessionId: string
  ): Promise<string> => {
    const response = await fetch('{{baseUrl}}/api/mcp/generate_url', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        server_id: serverId,
        session_id: sessionId,
      }),
    });

    const data = await response.json();
    return data.mcp_url;
  };

  // Usage
  const mcpUrl = await generateMCPUrl('server-uuid', 'session-uuid');
  // Use mcpUrl in MCP Playground
  ```

  ```json Response theme={null}
  {
    "mcp_url": "https://mcp.composio.dev/api/mcp/v1/server-slug?user_id=instance-id&auth=token",
    "status": "success"
  }
  ```
</CodeGroup>

**Endpoint:** `POST /api/mcp/generate_url`

**Request Body:**

| Field        | Type   | Required | Description                              |
| ------------ | ------ | -------- | ---------------------------------------- |
| `server_id`  | string | Yes      | MCP server UUID                          |
| `session_id` | string | Yes      | MCP session UUID (from connect\_account) |

**Response:**

| Field     | Type   | Description             |
| --------- | ------ | ----------------------- |
| `mcp_url` | string | Full MCP connection URL |
| `status`  | string | Generation status       |

**Usage:**
The generated URL is used internally by the MCP Playground to establish connections with MCP servers.

## Instance Management

### List User Instances

Retrieve all MCP instances (connections) for the authenticated user's organization.

<CodeGroup>
  ```bash curl theme={null}
  curl -X GET "{{baseUrl}}/api/mcp/list_instances?org_id=your-org-id&status=active" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/list_instances"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN"
  }
  params = {
      "org_id": "your-org-id",
      "status": "active"  # Optional: active, pending, inactive
  }

  response = requests.get(url, headers=headers, params=params)
  instances = response.json()

  for instance in instances:
      print(f"{instance['name'] or 'Unnamed'} - {instance['status']}")
  ```

  ```typescript TypeScript theme={null}
  type MCPSessionStatus = 'active' | 'pending' | 'inactive';

  interface MCPInstance {
    id: string;
    status: string;
    mcp_server_id: string;
    name: string | null;
    created_at: string;
  }

  const listMCPInstances = async (
    orgId: string,
    status?: MCPSessionStatus
  ): Promise<MCPInstance[]> => {
    const params = new URLSearchParams({ org_id: orgId });
    if (status) params.append('status', status);

    const response = await fetch(
      `{{baseUrl}}/api/mcp/list_instances?${params.toString()}`,
      {
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN',
        },
      }
    );

    return await response.json();
  };

  // Usage
  const activeInstances = await listMCPInstances('org-uuid', 'active');
  console.log(`You have ${activeInstances.length} active MCP connections`);
  ```

  ```json Response theme={null}
  [
    {
      "id": "inst-uuid-1",
      "status": "active",
      "mcp_server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
      "name": "My Gmail Account",
      "created_at": "2024-01-15T10:30:00Z"
    },
    {
      "id": "inst-uuid-2",
      "status": "active",
      "mcp_server_id": "b2c3d4e5-f6g7-8h9i-0j1k-l2m3n4o5p6q7",
      "name": "Work Slack",
      "created_at": "2024-01-14T09:15:00Z"
    },
    {
      "id": "inst-uuid-3",
      "status": "pending",
      "mcp_server_id": "c3d4e5f6-g7h8-9i0j-1k2l-m3n4o5p6q7r8",
      "name": null,
      "created_at": "2024-01-16T14:20:00Z"
    }
  ]
  ```
</CodeGroup>

**Endpoint:** `GET /api/mcp/list_instances`

**Query Parameters:**

| Parameter | Required | Type   | Description                                 |
| --------- | -------- | ------ | ------------------------------------------- |
| `org_id`  | Yes      | string | Organization UUID                           |
| `status`  | No       | string | Filter by status: active, pending, inactive |

**Response:**

Array of MCP instance objects with fields:

| Field           | Type   | Description            |
| --------------- | ------ | ---------------------- |
| `id`            | string | Instance UUID          |
| `status`        | string | Current status         |
| `mcp_server_id` | string | Parent server UUID     |
| `name`          | string | Custom name (nullable) |
| `created_at`    | string | ISO 8601 timestamp     |

### Update Instance

Update the custom name of an MCP instance.

<CodeGroup>
  ```bash curl theme={null}
  curl -X PUT "{{baseUrl}}/api/mcp/instance?mcp_instance_id=inst-uuid" \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "My Primary Gmail Account"
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/instance"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json"
  }
  params = {
      "mcp_instance_id": "inst-uuid"
  }
  data = {
      "name": "My Primary Gmail Account"
  }

  response = requests.put(url, headers=headers, params=params, json=data)
  updated = response.json()

  print(f"Updated: {updated['name']}")
  ```

  ```typescript TypeScript theme={null}
  const updateMCPInstance = async (
    instanceId: string,
    name: string
  ): Promise<MCPInstance> => {
    const response = await fetch(
      `{{baseUrl}}/api/mcp/instance?mcp_instance_id=${instanceId}`,
      {
        method: 'PUT',
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name }),
      }
    );

    return await response.json();
  };

  // Usage
  await updateMCPInstance('inst-uuid', 'My Primary Gmail Account');
  ```

  ```json Response theme={null}
  {
    "id": "inst-uuid",
    "status": "active",
    "mcp_server_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
    "name": "My Primary Gmail Account",
    "created_at": "2024-01-15T10:30:00Z"
  }
  ```
</CodeGroup>

**Endpoint:** `PUT /api/mcp/instance`

**Query Parameters:**

| Parameter         | Required | Type   | Description             |
| ----------------- | -------- | ------ | ----------------------- |
| `mcp_instance_id` | Yes      | string | Instance UUID to update |

**Request Body:**

| Field  | Type   | Required | Description                      |
| ------ | ------ | -------- | -------------------------------- |
| `name` | string | Yes      | New custom name for the instance |

### Delete Instance

Delete an MCP instance and disconnect from the external service.

<CodeGroup>
  ```bash curl theme={null}
  curl -X DELETE "{{baseUrl}}/api/mcp/instance?mcp_instance_id=inst-uuid" \
    -H "Authorization: Bearer YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "{{baseUrl}}/api/mcp/instance"
  headers = {
      "Authorization": "Bearer YOUR_TOKEN"
  }
  params = {
      "mcp_instance_id": "inst-uuid"
  }

  response = requests.delete(url, headers=headers, params=params)
  result = response.json()

  print(result["message"])
  ```

  ```typescript TypeScript theme={null}
  const deleteMCPInstance = async (instanceId: string): Promise<void> => {
    const response = await fetch(
      `{{baseUrl}}/api/mcp/instance?mcp_instance_id=${instanceId}`,
      {
        method: 'DELETE',
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN',
        },
      }
    );

    const result = await response.json();
    console.log(result.message);
  };

  // Usage
  await deleteMCPInstance('inst-uuid');
  ```

  ```json Response theme={null}
  {
    "message": "MCP instance deleted successfully"
  }
  ```
</CodeGroup>

**Endpoint:** `DELETE /api/mcp/instance`

**Query Parameters:**

| Parameter         | Required | Type   | Description             |
| ----------------- | -------- | ------ | ----------------------- |
| `mcp_instance_id` | Yes      | string | Instance UUID to delete |

**Behavior:**

* Deletes MCP instance from Composio (if active)
* Removes session record from database
* Revokes OAuth access tokens
* Cannot be undone

## Error Responses

| Status Code | Description           | Example                                            |
| ----------- | --------------------- | -------------------------------------------------- |
| 400         | Bad Request           | Invalid server\_id or missing parameters           |
| 401         | Unauthorized          | Invalid or missing token                           |
| 403         | Forbidden             | Insufficient permissions (requires mcp:write/read) |
| 404         | Not Found             | MCP server or instance not found                   |
| 500         | Internal Server Error | Composio API failure or database error             |

**Error Response Format:**

```json theme={null}
{
  "detail": "Error message describing what went wrong"
}
```

**Common Error Messages:**

```json theme={null}
// No auth config found
{
  "detail": "No auth config found for server: server-uuid"
}

// Connection attempt not found
{
  "detail": "No connection attempt found. Please connect your account first."
}

// Instance not found
{
  "detail": "MCP instance not found"
}

// OAuth failure
{
  "detail": "Failed to create connected account: [Composio error details]"
}
```

## Implementation Notes

### OAuth Flow

Complete OAuth flow implementation:

```typescript theme={null}
// 1. List available servers
const servers = await listMCPServers();

// 2. User selects server (e.g., Gmail)
const gmailServer = servers.find(s => s.toolkit_slug === 'gmail');

// 3. Initiate connection
const connection = await connectMCPAccount(gmailServer.id, 'chat');

// 4. Redirect to OAuth
window.location.href = connection.redirect_url;

// 5. User completes OAuth on external site
// ... user authorizes ...

// 6. OAuth provider redirects to callback
// Backend handles: GET /api/mcp/callback?mcp_server_id=...&mcp_session_id=...

// 7. Backend redirects to frontend
// Frontend receives: /mcp/callback?mcp_server_id=...&mcp_session_id=...

// 8. Frontend can now generate MCP URL
const mcpUrl = await generateMCPUrl(gmailServer.id, sessionId);

// 9. Use MCP URL in Playground
// Pass to MCP Playground Service for tool usage
```

### Session Management

Best practices for managing MCP sessions:

```python theme={null}
# Check user's existing connections
instances = list_instances(org_id, status="active")

# Filter by server
gmail_instances = [i for i in instances if i["mcp_server_id"] == gmail_server_id]

if gmail_instances:
    # User already connected
    instance_id = gmail_instances[0]["id"]
else:
    # Need to connect
    connection = connect_account(gmail_server_id)
    # Redirect user to OAuth...
```

### Feature Flags

MCP functionality is controlled by feature flags:

* **`mcp_sessions`**: Quota for number of MCP connections
* Checked on `POST /connect_account`
* Returns 402 Payment Required if quota exceeded

### Composio Integration

The service integrates with Composio for:

1. **OAuth Management**:
   * Creating connected accounts
   * Generating redirect URLs
   * Handling callbacks

2. **Instance Management**:
   * Creating MCP instances
   * Generating MCP URLs
   * Deleting instances

3. **Authentication**:
   * Token management
   * Automatic token refresh
   * Secure credential storage

## Rate Limiting

Rate limits may apply based on:

* Feature flag quotas (`mcp_sessions`)
* Composio API limits
* External service OAuth limits

## Security Considerations

### OAuth Security

* OAuth tokens never exposed to client
* Tokens stored securely in Composio
* Automatic token refresh
* Callback URL validation

### Access Control

* All endpoints require authentication
* RBAC permissions enforced
* Org-scoped operations
* User isolation

### Data Privacy

* No MCP data stored permanently
* OAuth scopes request minimal permissions
* Users can revoke access anytime
* Audit trail for connections

## Next Steps

Explore MCP integration further:

* [**MCP Playground Service**](/pages/api-reference/mcp-playground-service) - Chat with MCP tools
* [**MCP Concepts**](/pages/concepts/mcp) - Understanding MCP architecture
* [**Authentication Guide**](/pages/authentication/overview) - Security and RBAC
* [**Getting Started**](/pages/getting-started/quickstart) - Quick start guide

Ready to build with MCP? Check out the [**MCP Playground API**](/pages/api-reference/mcp-playground-service) to start using connected tools!
