DocsAPI ReferenceWebSocket API

WebSocket API

Real-time communication with MCPCodex using WebSockets. Enable streaming responses, live collaboration, and instant notifications.

Why WebSockets?

Real-time AI Development

While REST APIs are great for simple requests, AI development often requires real-time interaction, streaming responses, and continuous context awareness. WebSockets enable these advanced workflows.

WebSocket Benefits

  • • Real-time streaming responses
  • • Bidirectional communication
  • • Lower latency than HTTP polling
  • • Persistent connection state
  • • Server-initiated messages

Use Cases

  • • Live code generation
  • • Multi-agent orchestration
  • • Real-time collaboration
  • • Progress monitoring
  • • Context synchronization

Basic Connection

Establishing a WebSocket connection to MCPCodex is straightforward. The connection requires authentication and supports automatic reconnection.

basic-connection.js
// Basic WebSocket Connection
const ws = new WebSocket('wss://api.mcpcodex.com/v1/ws', {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

ws.onopen = () => {
  console.log('Connected to MCPCodex WebSocket API');
  
  // Send initial handshake
  ws.send(JSON.stringify({
    type: 'auth',
    token: 'YOUR_API_KEY',
    version: '2.0.0'
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  handleMessage(message);
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = (event) => {
  console.log('Connection closed:', event.code, event.reason);
};

Connection Parameters

Endpoints

wss://api.mcpcodex.com/v1/ws
General WebSocket API
wss://api.mcpcodex.com/v1/agents
Multi-agent orchestration
wss://api.mcpcodex.com/v1/projects/:id/stream
Project-specific streaming

Authentication

• API key in Authorization header
• JWT token for user sessions
• OAuth 2.0 bearer tokens
• Project-specific access tokens

Streaming Code Generation

Watch AI generate code in real-time, see the reasoning process, and get immediate feedback. This creates a more interactive and transparent development experience.

streaming-generation.js
// Real-time Code Generation
class MCPCodexStream {
  constructor(apiKey) {
    this.ws = new WebSocket('wss://api.mcpcodex.com/v1/ws');
    this.requestId = 0;
    this.activeStreams = new Map();
    
    this.setupEventHandlers();
  }

  setupEventHandlers() {
    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      
      switch (message.type) {
        case 'stream_start':
          this.handleStreamStart(message);
          break;
        case 'token':
          this.handleToken(message);
          break;
        case 'tool_call':
          this.handleToolCall(message);
          break;
        case 'stream_end':
          this.handleStreamEnd(message);
          break;
        case 'error':
          this.handleError(message);
          break;
      }
    };
  }

  async generateCode(prompt, options = {}) {
    const requestId = ++this.requestId;
    
    const request = {
      id: requestId,
      type: 'generate',
      prompt,
      model: options.model || 'claude-3-opus',
      stream: true,
      context: options.context || {},
      constraints: options.constraints || {}
    };

    // Set up promise to resolve when stream ends
    return new Promise((resolve, reject) => {
      this.activeStreams.set(requestId, {
        resolve,
        reject,
        chunks: [],
        metadata: {}
      });

      this.ws.send(JSON.stringify(request));
    });
  }

  handleToken(message) {
    const stream = this.activeStreams.get(message.requestId);
    if (stream) {
      stream.chunks.push(message.token);
      
      // Emit token event for real-time updates
      this.emit('token', {
        requestId: message.requestId,
        token: message.token,
        fullText: stream.chunks.join('')
      });
    }
  }

  handleToolCall(message) {
    this.emit('tool_call', {
      requestId: message.requestId,
      tool: message.tool,
      arguments: message.arguments,
      thinking: message.thinking
    });
  }

  handleStreamEnd(message) {
    const stream = this.activeStreams.get(message.requestId);
    if (stream) {
      const result = {
        text: stream.chunks.join(''),
        metadata: message.metadata,
        usage: message.usage
      };
      
      stream.resolve(result);
      this.activeStreams.delete(message.requestId);
    }
  }
}

// Usage example
const stream = new MCPCodexStream('YOUR_API_KEY');

stream.on('token', (data) => {
  // Update UI in real-time
  document.getElementById('output').textContent += data.token;
});

stream.on('tool_call', (data) => {
  console.log(`AI is using tool: ${data.tool}`);
  console.log(`Thinking: ${data.thinking}`);
});

const result = await stream.generateCode(
  "Create a React component for user authentication",
  {
    model: "claude-3-opus",
    context: {
      framework: "react",
      typescript: true,
      styling: "tailwind"
    }
  }
);

Token Streaming

Receive generated text token by token, allowing for real-time display of AI thinking.

Tool Calls

Watch AI use tools in real-time, see reasoning, and understand the development process.

Progress Tracking

Monitor generation progress with metadata, usage statistics, and completion status.

Multi-Agent Orchestration

Coordinate multiple AI agents working together on complex tasks. Monitor their progress, see their interactions, and control the workflow in real-time.

agent-orchestration.js
// Multi-Agent Orchestration via WebSocket
class AgentOrchestrator {
  constructor(apiKey) {
    this.ws = new WebSocket('wss://api.mcpcodex.com/v1/agents');
    this.agents = new Map();
    this.workflows = new Map();
  }

  async createWorkflow(name, config) {
    const workflowId = this.generateId();
    
    const message = {
      type: 'create_workflow',
      id: workflowId,
      name,
      agents: config.agents,
      coordination: config.coordination || 'sequential',
      context: config.context || {}
    };

    this.ws.send(JSON.stringify(message));
    
    return new Promise((resolve) => {
      this.workflows.set(workflowId, { resolve, agents: [] });
    });
  }

  async executeWorkflow(workflowId, task) {
    const message = {
      type: 'execute_workflow',
      workflowId,
      task,
      timestamp: Date.now()
    };

    this.ws.send(JSON.stringify(message));
    
    return new Promise((resolve, reject) => {
      const workflow = this.workflows.get(workflowId);
      if (workflow) {
        workflow.executeResolve = resolve;
        workflow.executeReject = reject;
      }
    });
  }

  handleWorkflowEvents(message) {
    const workflow = this.workflows.get(message.workflowId);
    if (!workflow) return;

    switch (message.event) {
      case 'agent_started':
        this.emit('agent_started', {
          workflowId: message.workflowId,
          agentId: message.agentId,
          agentType: message.agentType,
          task: message.task
        });
        break;

      case 'agent_progress':
        this.emit('agent_progress', {
          workflowId: message.workflowId,
          agentId: message.agentId,
          progress: message.progress,
          step: message.step,
          thinking: message.thinking
        });
        break;

      case 'agent_completed':
        this.emit('agent_completed', {
          workflowId: message.workflowId,
          agentId: message.agentId,
          result: message.result,
          artifacts: message.artifacts
        });
        break;

      case 'workflow_completed':
        if (workflow.executeResolve) {
          workflow.executeResolve({
            results: message.results,
            artifacts: message.artifacts,
            metrics: message.metrics
          });
        }
        break;

      case 'workflow_error':
        if (workflow.executeReject) {
          workflow.executeReject(new Error(message.error));
        }
        break;
    }
  }
}

// Example: Full-Stack Feature Implementation
const orchestrator = new AgentOrchestrator('YOUR_API_KEY');

orchestrator.on('agent_started', (data) => {
  console.log(`${data.agentType} agent started: ${data.task}`);
});

orchestrator.on('agent_progress', (data) => {
  console.log(`Progress: ${data.step} - ${data.thinking}`);
});

const workflowId = await orchestrator.createWorkflow('user-management', {
  agents: [
    { type: 'architect', model: 'gpt-4' },
    { type: 'frontend-dev', model: 'claude-3-opus' },
    { type: 'backend-dev', model: 'claude-3-opus' },
    { type: 'tester', model: 'gpt-3.5-turbo' }
  ],
  coordination: 'parallel_then_merge'
});

const result = await orchestrator.executeWorkflow(workflowId, {
  feature: "User profile management with photo upload",
  requirements: {
    frontend: "React with TypeScript",
    backend: "Node.js with Express",
    database: "PostgreSQL",
    storage: "AWS S3",
    auth: "JWT with refresh tokens"
  }
});

Workflow Patterns

Sequential

Agents work in sequence: Architect → Frontend Dev → Backend Dev → Tester

Parallel

Multiple agents work simultaneously on different aspects of the project

Parallel-Then-Merge

Agents work in parallel, then results are merged by a coordinator agent

Context-Aware Streaming

Maintain real-time synchronization with your project context. Get live suggestions, monitor file changes, and keep AI agents aware of your current development state.

context-streaming.js
// Context-Aware Streaming with Project State
class ProjectContextStream {
  constructor(apiKey, projectId) {
    this.ws = new WebSocket(`wss://api.mcpcodex.com/v1/projects/${projectId}/stream`);
    this.projectId = projectId;
    this.contextVersion = 0;
    
    this.setupContextSync();
  }

  setupContextSync() {
    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      
      if (message.type === 'context_sync') {
        this.handleContextSync(message);
      } else if (message.type === 'file_changed') {
        this.handleFileChange(message);
      } else if (message.type === 'suggestion') {
        this.handleSuggestion(message);
      }
    };
  }

  // Stream changes to project files
  watchFile(filePath) {
    this.ws.send(JSON.stringify({
      type: 'watch_file',
      filePath,
      projectId: this.projectId
    }));
  }

  // Request AI analysis of current context
  analyzeContext(analysisType = 'full') {
    this.ws.send(JSON.stringify({
      type: 'analyze_context',
      projectId: this.projectId,
      analysisType, // 'full', 'incremental', 'focused'
      contextVersion: this.contextVersion
    }));
  }

  // Stream live suggestions based on current work
  enableLiveSuggestions(config = {}) {
    this.ws.send(JSON.stringify({
      type: 'enable_suggestions',
      projectId: this.projectId,
      config: {
        frequency: config.frequency || 'on_change',
        types: config.types || ['improvements', 'bugs', 'optimizations'],
        confidence_threshold: config.threshold || 0.8
      }
    }));
  }

  handleContextSync(message) {
    this.contextVersion = message.version;
    this.emit('context_updated', {
      version: message.version,
      changes: message.changes,
      summary: message.summary
    });
  }

  handleFileChange(message) {
    this.emit('file_changed', {
      filePath: message.filePath,
      changeType: message.changeType, // 'created', 'modified', 'deleted'
      diff: message.diff,
      suggestions: message.suggestions
    });
  }

  handleSuggestion(message) {
    this.emit('suggestion', {
      type: message.suggestionType,
      filePath: message.filePath,
      line: message.line,
      suggestion: message.suggestion,
      confidence: message.confidence,
      reasoning: message.reasoning
    });
  }
}

// Usage in development environment
const contextStream = new ProjectContextStream('YOUR_API_KEY', 'project-123');

// Watch critical files
contextStream.watchFile('src/components/UserProfile.tsx');
contextStream.watchFile('src/api/auth.ts');

// Enable live suggestions
contextStream.enableLiveSuggestions({
  frequency: 'on_change',
  types: ['security', 'performance', 'best_practices']
});

contextStream.on('suggestion', (data) => {
  if (data.confidence > 0.9) {
    showInlineHint(data.filePath, data.line, data.suggestion);
  }
});

contextStream.on('file_changed', (data) => {
  console.log(`File ${data.filePath} was ${data.changeType}`);
  if (data.suggestions.length > 0) {
    showSuggestions(data.suggestions);
  }
});

Live Context Sync

  • • Real-time file change detection
  • • Automatic context updates
  • • Incremental analysis
  • • Version tracking
  • • Conflict resolution

Smart Suggestions

  • • Context-aware recommendations
  • • Security vulnerability alerts
  • • Performance optimization hints
  • • Code quality improvements
  • • Best practice enforcement

Robust Connection Management

Production Considerations

WebSocket connections can be interrupted by network issues, server restarts, or client changes. Implement robust reconnection logic and message queuing for production use.

robust-connection.js
// Robust Connection Management
class RobustWebSocketClient {
  constructor(url, options = {}) {
    this.url = url;
    this.options = options;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = options.maxReconnectAttempts || 10;
    this.reconnectInterval = options.reconnectInterval || 1000;
    this.heartbeatInterval = options.heartbeatInterval || 30000;
    this.messageQueue = [];
    this.isConnected = false;
    
    this.connect();
    this.setupHeartbeat();
  }

  connect() {
    try {
      this.ws = new WebSocket(this.url);
      this.setupEventHandlers();
    } catch (error) {
      console.error('Failed to create WebSocket connection:', error);
      this.scheduleReconnect();
    }
  }

  setupEventHandlers() {
    this.ws.onopen = () => {
      console.log('WebSocket connected');
      this.isConnected = true;
      this.reconnectAttempts = 0;
      
      // Send queued messages
      while (this.messageQueue.length > 0) {
        const message = this.messageQueue.shift();
        this.ws.send(message);
      }
      
      this.emit('connected');
    };

    this.ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      
      if (message.type === 'pong') {
        this.lastPongReceived = Date.now();
        return;
      }
      
      this.handleMessage(message);
    };

    this.ws.onclose = (event) => {
      console.log('WebSocket closed:', event.code, event.reason);
      this.isConnected = false;
      
      if (event.code !== 1000) { // Not a normal closure
        this.scheduleReconnect();
      }
      
      this.emit('disconnected', { code: event.code, reason: event.reason });
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
      this.emit('error', error);
    };
  }

  send(message) {
    const messageStr = JSON.stringify(message);
    
    if (this.isConnected && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(messageStr);
    } else {
      // Queue message for when connection is restored
      this.messageQueue.push(messageStr);
      
      if (!this.isConnected) {
        this.connect();
      }
    }
  }

  scheduleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached');
      this.emit('max_reconnect_attempts');
      return;
    }

    this.reconnectAttempts++;
    const delay = Math.min(
      this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1),
      30000
    );

    console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
    
    setTimeout(() => {
      this.connect();
    }, delay);
  }

  setupHeartbeat() {
    setInterval(() => {
      if (this.isConnected) {
        this.send({ type: 'ping', timestamp: Date.now() });
        
        // Check if we received a pong recently
        const timeSinceLastPong = Date.now() - (this.lastPongReceived || 0);
        if (timeSinceLastPong > this.heartbeatInterval * 2) {
          console.warn('Heartbeat timeout, reconnecting...');
          this.ws.close();
        }
      }
    }, this.heartbeatInterval);
  }

  close() {
    this.ws.close(1000, 'Client closing connection');
  }
}

Reconnection Strategy

  • • Exponential backoff for retry delays
  • • Maximum retry attempt limits
  • • Automatic message queue management
  • • Connection state tracking
  • • Graceful degradation

Health Monitoring

  • • Heartbeat ping/pong mechanism
  • • Connection timeout detection
  • • Latency monitoring
  • • Error rate tracking
  • • Performance metrics

Message Types

TypeDirectionDescriptionPurpose
authClient → ServerAuthentication handshakeInitial connection setup
generateClient → ServerCode generation requestStart streaming generation
tokenServer → ClientGenerated text tokenReal-time text streaming
tool_callServer → ClientAI tool executionShow AI reasoning process
suggestionServer → ClientCode improvement suggestionLive development assistance
errorBidirectionalError notificationError handling and recovery
ping/pongBidirectionalConnection health checkKeep connection alive

Next Steps

Need Help with WebSockets?

WebSocket implementation can be complex. Our team can help you get it right.