P

anthropic_mcp_hackathon_sse_client

...
Created 12/12/2024bytony-nexartis

Language:

Python

Stars:

3

Forks:

1

MCP Client

A Python client for interacting with Model Control Protocol (MCP) servers using Server-Sent Events (SSE).

Architecture

Server-Sent Events (SSE)

The client establishes a persistent connection with MCP servers using Server-Sent Events (SSE), enabling real-time, server-to-client communication. This architecture allows servers to push updates to the client without requiring constant polling.

Key SSE events:

  • endpoint: Provides the session-specific messaging endpoint
  • tools: Delivers available tools and capabilities
  • error: Communicates server-side errors
  • result: Returns tool execution results

Connection Flow

  1. Client initiates SSE connection to /sse endpoint
  2. Server responds with session ID via endpoint event
  3. Server sends available tools via tools event
  4. Client maintains persistent connection for real-time updates
  5. Tool calls are made via POST requests to the SSE endpoint
  6. Results stream back through the SSE connection

Usage

# Install dependencies
pip install -r requirements.txt

# Run the client
python client_sse.py

Environment Variables

  • MCP_SERVER_URL: URL of the MCP server
  • MCP_API_KEY: API key for authentication
  • ANTHROPIC_API_KEY: API key for Claude integration

Features

  • Real-time bidirectional communication with MCP servers
  • Automatic session management
  • Dynamic tool discovery and integration
  • Streaming responses for long-running operations
  • Robust error handling and connection management

Server Implementation Guide

TODO: Adding SSE Support to an MCP Server

To modify an existing MCP server to support SSE, follow these steps:

  1. Add SSE Dependencies

    import { EventEmitter } from 'events';
    import { FastifyInstance } from 'fastify';
    
  2. Create Session Management

    interface Session {
      id: string;
      emitter: EventEmitter;
      tools: Tool[];
    }
    
    
             
         
             
                    const sessions = new Map();
    
  3. Implement SSE Endpoint

    server.get('/sse', async (request, reply) => {
      const sessionId = generateSessionId();
      const session = createSession(sessionId);
      
      reply.raw.setHeader('Content-Type', 'text/event-stream');
      reply.raw.setHeader('Cache-Control', 'no-cache');
      reply.raw.setHeader('Connection', 'keep-alive');
      
      // Send initial session info
      reply.raw.write(`event: endpoint\ndata: /messages/?session_id=${sessionId}\n\n`);
      
      // Send available tools
      const tools = await getTools();
      reply.raw.write(`event: tools\ndata: ${JSON.stringify(tools)}\n\n`);
      
      // Handle client disconnect
      request.raw.on('close', () => {
        sessions.delete(sessionId);
      });
    });
    
  4. Modify Tool Handlers

    server.post('/sse', async (request, reply) => {
      const { session_id, tool, args } = request.body;
      const session = sessions.get(session_id);
      
      if (!session) {
        throw new Error('Invalid session');
      }
      
      try {
        const result = await executeToolCall(tool, args);
        reply.raw.write(`event: result\ndata: ${JSON.stringify(result)}\n\n`);
      } catch (error) {
        reply.raw.write(`event: error\ndata: ${JSON.stringify(error)}\n\n`);
      }
    });
    
  5. Update Server Configuration

    const server = new Server({
      name: "mcp-sse-server",
      version: "1.0.0"
    }, {
      capabilities: {
        resources: {},
        tools: {},
        sse: true  // Enable SSE capability
      }
    });
    
  6. Error Handling

    server.setErrorHandler(async (error, request, reply) => {
      const sessionId = request.body?.session_id;
      const session = sessions.get(sessionId);
      
      if (session) {
        session.emitter.emit('error', error);
      }
      reply.code(500).send(error);
    });
    
  7. Session Cleanup

                ```typescript
    

    function cleanupSessions() { const now = Date.now(); for (const [id, session] of sessions.entries()) { if (now - session.lastActive > SESSION_TIMEOUT) { sessions.delete(id); } } }

    setInterval(cleanupSessions, CLEANUP_INTERVAL);

Key Considerations

  1. Connection Management

    • Implement heartbeat mechanism
    • Handle reconnection gracefully
    • Clean up inactive sessions
  2. Security

    • Validate session IDs
    • Implement rate limiting
    • Add authentication middleware
  3. Performance

    • Monitor memory usage for active sessions
    • Implement connection pooling
    • Add request queuing for heavy operations
  4. Testing

    • Add unit tests for SSE endpoints
    • Test connection edge cases
    • Verify tool execution through SSE

Error Handling

The client implements several error handling mechanisms:

  • Connection timeout detection
  • Automatic reconnection attempts
  • Graceful error reporting
  • Session state validation

Development

The client uses Python's aiohttp library for async HTTP and SSE handling.

Last updated: 1/27/2025

Publisher info

tony-nexartis's avatar

Tony Rose

2
followers
4
following
2
repos

More MCP servers built with Python

composer-trade-mcp

Create, backtest, and execute trades directly in one chat box. The Composer MCP Server gives LLMs the power to backtest investment ideas and execute automated trading strategies. Trade across stocks, ETFs, and crypto directly in Claude.

By https://github.com/ronnyli
slidespeak-mcp

An MCP to generate presentations with AI. Create and edit PowerPoint presentations with AI.

By https://github.com/SlideSpeak
PaddleOCR

The PaddleOCR MCP server brings enterprise-grade OCR and document parsing capabilities to AI applications. Built on PaddleOCR — a proven solution with 50,000+ GitHub stars, deeply integrated by leading projects like MinerU, RAGFlow, and OmniParser— with targeted optimizations based on the MCP concept.

By PaddlePaddle