Skip to main content
The MCP Playground Service provides a conversational interface for interacting with MCP servers. It supports two modes: Intelligent Discovery (AI recommends servers) and Direct MCP Usage (use specific servers). The service handles tool orchestration, streaming responses, and conversation management.

MCP Playground Overview

Authentication

Requires a valid Bearer token with mcp:write permission.

Base URL

/api/mcp_playground

Chat with MCP

Send Message to MCP Playground

Send a message and receive streaming responses from AI using MCP tools.
# Intelligent Discovery Mode (no MCP instances)
curl -X POST "{{baseUrl}}/api/mcp_playground/chat" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Show me my urgent emails from today",
    "model": "gpt-4-turbo"
  }'

# Direct MCP Mode (with specific instances)
curl -X POST "{{baseUrl}}/api/mcp_playground/chat" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Forward urgent emails to Slack",
    "mcp_instance_ids": ["gmail-instance-id", "slack-instance-id"],
    "model": "claude-3.5-sonnet"
  }'
Endpoint: POST /api/mcp_playground/chat Request Body:
FieldTypeRequiredDescription
contentstringYesUserโ€™s message/query
mcp_instance_idsarrayNoMCP instance UUIDs to use (Direct Mode)
modelstringNoLLM model to use (defaults based on mode)
Model Options: The service accepts any model name starting with the provider prefix. Hardcoded defaults are used when no model is specified:
Model PatternProviderDefault BehaviorUse Case
gpt-*, o1*OpenAI-General purpose, reasoning
claude-*Anthropic-Tool use, long context
deepseek-*DeepSeekIntelligent Mode: deepseek-chatDatabase queries, cost-effective
gemini-*GoogleDirect Mode: gemini-2.5-flashFast tool execution
How Defaults Work:
  • Intelligent Discovery Mode (no mcp_instance_ids): Defaults to deepseek-chat if model not provided
  • Direct MCP Mode (with mcp_instance_ids): Defaults to gemini-2.5-flash if model not provided
Response Format: Server-Sent Events (SSE) stream with these data types:

Stream Event Types

1. Message Content

Regular AI response tokens.
{
  "message": "text token",
  "tool": null
}

2. Tool Call Started

AI initiates a tool call.
{
  "message": "",
  "tool": {
    "id": "call_abc123",
    "name": "gmail_list_messages",
    "input": {
      "query": "is:urgent is:unread",
      "maxResults": 10
    },
    "output": null
  }
}

3. Tool Call Completed

Tool execution finished.
{
  "message": "",
  "tool": {
    "id": "call_abc123",
    "name": "gmail_list_messages",
    "successful": true,
    "error": null,
    "input": {
      "query": "is:urgent is:unread",
      "maxResults": 10
    },
    "output": {
      "messages": [
        {
          "id": "msg123",
          "subject": "Urgent: Project Deadline",
          "from": "boss@company.com",
          "snippet": "Need this by EOD..."
        }
      ],
      "resultSizeEstimate": 45,
      "nextPageToken": "page_token_xyz"
    }
  }
}
Tool Output Fields:
FieldTypeDescription
successfulbooleanWhether tool executed successfully
errorstringError message if failed (null if successful)
outputobjectTool-specific result data
Pagination Metadata: Some tools return pagination information:
FieldTypeDescription
nextPageTokenstringToken for next page of results
resultSizeEstimatenumberTotal number of results available
The system automatically tracks this metadata and uses it when the user requests โ€œmoreโ€ results.

4. MCP Server Recommendation

Intelligent Mode suggests servers to connect.
{
  "mcp": {
    "server_ids": [
      "gmail-server-uuid",
      "slack-server-uuid"
    ]
  },
  "message": ""
}
Frontend should:
  1. Extract server_ids
  2. Fetch server details via MCP Service
  3. Prompt user to connect servers
  4. After connection, resend message with mcp_instance_ids

5. Completion Signal

Stream finished.
{
  "message": "DONE",
  "tool": null
}

6. Error

Stream encountered an error.
{
  "error": "Error message describing what went wrong"
}

Mode Details

Intelligent Discovery Mode

Trigger: No mcp_instance_ids provided Behavior:
  1. AI analyzes user query
  2. Searches database for relevant MCP servers
  3. Returns streaming response with recommendations
  4. Includes {"mcp": {"server_ids": [...]}} in stream
Example Flow:
// User: "Send an email to john@example.com"
await chatWithMCP(
  {
    content: "Send an email to john@example.com",
    model: "deepseek-chat"  // Default for Intelligent Mode
  },
  (token) => display(token),
  () => {},
  (serverIds) => {
    // serverIds = ["gmail-server-uuid"]
    // Prompt user to connect Gmail
    showConnectDialog(serverIds);
  }
);

// After user connects Gmail...
await chatWithMCP(
  {
    content: "Send an email to john@example.com",
    mcp_instance_ids: ["gmail-instance-id"]  // Now in Direct Mode
  },
  (token) => display(token),
  (tool) => showToolExecution(tool),
  () => {}
);
Intelligent Agent Features:
  • Natural Language Understanding: Analyzes intent
  • Database Search: Queries mcp_servers and mcp_tools tables
  • Context Awareness: Uses conversation history (30 exchanges)
  • Smart Recommendations: Suggests relevant servers only
  • Conversational: Continues chatting while recommending

Direct MCP Mode

Trigger: mcp_instance_ids provided Behavior:
  1. Generates MCP URLs for specified instances
  2. Connects to all MCP servers
  3. Initializes AI agent with multi-MCP tools
  4. Streams tool calls and responses
  5. Maintains conversation history (16 exchanges)
Example Flow:
// User has connected Gmail and Slack
await chatWithMCP(
  {
    content: "Forward urgent emails to #general channel",
    mcp_instance_ids: ["gmail-instance", "slack-instance"],
    model: "gemini-2.5-flash"  // Fast model for tool use
  },
  (token) => display(token),
  (tool) => {
    if (tool.output === null) {
      // Tool started
      showToolStart(tool.name, tool.input);
    } else {
      // Tool completed
      showToolResult(tool.name, tool.output, tool.successful);
    }
  },
  () => {}
);

// Possible tool sequence:
// 1. gmail_search_messages (query: "is:urgent")
// 2. gmail_get_message (id: "msg123")
// 3. slack_send_message (channel: "general", text: "...")
Multi-MCP Features:
  • Parallel Connections: Connect to multiple servers
  • Tool Orchestration: AI chains tools across servers
  • Context Preservation: Full conversation history
  • Metadata Tracking: Pagination tokens preserved
  • XML Prompting: Structured context for better responses

Conversation Management

Memory System

Conversation Storage:
  • Intelligent Mode: 60 messages max (30 exchanges) - hardcoded
  • Direct Mode: 30 messages - passed as memory_size parameter to playground factory
  • TTL: 30 minutes of inactivity (hardcoded)
  • Format: Chronological array of {role, content, created_at}
Automatic Cleanup:
# Sessions inactive for >30 minutes are cleared
last_active = datetime.now() - timedelta(minutes=30)
if session_last_active < last_active:
    clear_session(session_id)
History Usage: The system automatically includes conversation history in each request using structured XML formatting. Each conversation includes user and assistant messages with timestamps, allowing the AI to maintain context across multiple exchanges. This enables contextual interactions:
  • โ€œShow me moreโ€ - AI remembers previous query
  • โ€œSend that to Slackโ€ - AI knows what โ€œthatโ€ refers to
  • โ€œWhat was the first email about?โ€ - AI recalls earlier context

Tool Metadata Tracking

Pagination tokens and metadata automatically preserved:
# After tool completes with pagination
metadata = {
    "nextPageToken": "page_xyz",
    "resultSizeEstimate": 150
}

# Stored for session
factory.add_tool_metadata(session_id, "gmail_list_messages", metadata)

# Used in future calls
# User: "Show me more emails"
# AI automatically uses nextPageToken

Error Handling

Connection Errors

{
  "error": "Failed to connect to MCP server. Please check the URL and try again."
}
Causes:
  • MCP server unavailable
  • Invalid MCP URL
  • Network issues
Solutions:
  • Verify MCP instance is active
  • Check network connectivity
  • Try reconnecting MCP instance

Timeout Errors

{
  "error": "MCP server connection timed out. The server may be unavailable."
}
Causes:
  • MCP server too slow (>30s)
  • Heavy computation
  • Network latency
Solutions:
  • Retry request
  • Use faster MCP server
  • Break into smaller operations

Tool Errors

{
  "message": "",
  "tool": {
    "id": "call_abc",
    "name": "gmail_send_message",
    "successful": false,
    "error": "Insufficient permissions to send emails",
    "input": {...},
    "output": null
  }
}
Common Tool Errors:
  • Insufficient permissions
  • Invalid parameters
  • Resource not found
  • Rate limit exceeded

No Valid Instances

{
  "detail": "No valid MCP instances found for the provided IDs"
}
Causes:
  • Instance IDs donโ€™t exist
  • Instances not active
  • User doesnโ€™t own instances
Solutions:
  • Check instance IDs
  • Verify instances are active via /api/mcp/list_instances
  • Reconnect MCP servers

Advanced Features

Multi-Server Orchestration

Chain operations across multiple MCP servers:
// Example: Email-to-Slack workflow
await chatWithMCP(
  {
    content: "Find emails about 'Project Alpha' and post summary to Slack",
    mcp_instance_ids: ["gmail-id", "slack-id"]
  },
  (token) => display(token),
  (tool) => {
    // Sequence of tools:
    // 1. gmail_search_messages (query: "Project Alpha")
    // 2. gmail_get_message (for each result)
    // 3. slack_send_message (summarized content)
    logToolExecution(tool);
  }
);

Contextual Follow-ups

Leverage conversation history for natural interactions:
// First query
await chat({ content: "List my Gmail labels" });
// Response: "You have labels: Work, Personal, Important..."

// Follow-up (no need to specify "Gmail")
await chat({ content: "Show emails in the Work label" });
// AI remembers we're working with Gmail

// Another follow-up
await chat({ content: "Send the first one to Slack" });
// AI knows which email to send

Complex Searches

Use comprehensive search strategies:
await chatWithMCP(
  {
    content: "Find all urgent communications from this week",
    mcp_instance_ids: ["gmail-id", "slack-id"]
  },
  // AI automatically:
  // - Searches Gmail for is:urgent, is:important, from:boss, subject:urgent/ASAP
  // - Searches Slack for mentions, DMs, urgent keywords
  // - Combines and presents results
);

Best Practices

For Frontend Developers

  1. Handle Both Modes:
    if (streamData.mcp?.server_ids) {
      // Intelligent Mode - prompt to connect
      showConnectServersDialog(streamData.mcp.server_ids);
    }
    
  2. Display Tool Execution:
    if (tool.output === null) {
      showLoadingIndicator(`Calling ${tool.name}...`);
    } else {
      hideLoadingIndicator();
      if (!tool.successful) {
        showError(tool.error);
      }
    }
    
  3. Buffer Message Tokens:
    let buffer = '';
    onToken((token) => {
      buffer += token;
      if (buffer.length > 50 || token.includes(' ')) {
        display(buffer);
        buffer = '';
      }
    });
    
  4. Handle Errors Gracefully:
    try {
      await chatWithMCP(message);
    } catch (error) {
      if (error.message.includes('No valid MCP instances')) {
        promptReconnect();
      } else {
        showErrorDialog(error.message);
      }
    }
    

For Users

  1. Be Specific: โ€œShow urgent emails from last weekโ€ vs โ€œshow emailsโ€
  2. Use Natural Language: The AI understands intent
  3. Leverage History: Reference previous messages
  4. Connect Relevant Servers: Only connect what youโ€™ll use
  5. Review Tool Calls: Understand what the AI is doing

For Developers

  1. Model Selection:
    • Intelligent Mode Default: deepseek-chat (hardcoded, optimized for DB queries)
    • Direct Mode Default: gemini-2.5-flash (hardcoded, optimized for tool execution)
    • Override for Quality: Use gpt-4, o1, or claude-3.5-sonnet for complex reasoning
    • Override for Context: Use claude-3-opus for long conversations
    • Model string must start with: gpt, o1, claude, deepseek, or gemini
  2. Instance Management:
    • Cache active instance IDs
    • Refresh list periodically
    • Handle instance expiration
  3. Error Recovery:
    • Retry on timeout (once)
    • Fallback to simpler queries
    • Clear instructions on permission errors

Rate Limiting

  • Feature flag: mcp_sessions quota
  • Concurrent MCP connections: No hard limit (performance degrades)
  • Message rate: No explicit limit
  • Tool execution timeout: 30 seconds per tool

Security

  • Authentication: JWT required
  • RBAC: mcp:write permission required
  • Org Isolation: Sessions scoped to organizations
  • Data Privacy: Conversations cleared after 30 minutes
  • Tool Safety: User owns all MCP connections

Performance Considerations

Optimize for Speed

  1. Use Fast Models:
    • Default gemini-2.5-flash for Direct Mode (optimized for tool use)
    • Default deepseek-chat for Intelligent Mode (optimized for DB queries)
    • Override with faster models if needed
  2. Limit MCP Servers:
    • Only connect necessary servers
    • More servers = slower initialization
  3. Reduce History:
    • Default 30 messages for Direct Mode
    • Reduce memory_size parameter for faster context loading
  4. Batch Operations:
    • โ€œProcess first 10 emailsโ€ vs โ€œProcess allโ€

Optimize for Quality

  1. Use Reasoning Models:
    • Override defaults with gpt-4 or o1 for complex logic
    • Use claude-3.5-sonnet for advanced tool orchestration
    • Defaults are optimized for speed, not quality
  2. Provide Context:
    • Longer queries = better understanding
    • Reference previous conversations
    • Use conversation history features
  3. Note on History:
    • Intelligent Mode: Fixed at 30 exchanges
    • Direct Mode: Fixed at 30 messages (memory_size hardcoded in service)
    • Cannot be increased without code changes

Next Steps

Continue exploring MCP integration: Ready to build? Check out our Quick Start Guide or explore Example Use Cases!