Claude Skills Guide

Claude Code Server-Sent Events API Guide

Server-Sent Events (SSE) provide a simple, standards-based way to push real-time updates from a server to a client over HTTP. Unlike WebSockets, SSE works over a single persistent connection and automatically handles reconnection, making it ideal for streaming logs, live dashboards, and notification systems. This guide shows you how to implement SSE with Claude Code, with practical examples you can apply to your projects.

How Server-Sent Events Work

SSE relies on the Content-Type: text/event-stream header. The server sends events in a specific format:

data: {"message": "processing"}

data: {"message": "complete"}
event: done

Each event consists of optional fields: event, data, id, and retry. The data field contains your payload, and the event field lets you name events for routing on the client.

Basic Server Implementation

Create a simple SSE endpoint using any backend framework. Here’s a Python Flask example:

from flask import Flask, Response, stream_with_context

app = Flask(__name__)

@app.route('/stream')
def stream():
    def generate():
        for i in range(10):
            yield f"data: {i}\n\n"
            time.sleep(1)
    
    return Response(generate(), mimetype='text/event-stream')

The yield pattern streams each message immediately rather than waiting for the full response. For production use with the pdf skill or other document processing workflows, you might stream progress updates as files are processed.

Client-Side Consumption

On the client side, use the native EventSource API:

const source = new EventSource('/stream');

source.onmessage = (event) => {
  console.log('Received:', event.data);
};

source.addEventListener('progress', (event) => {
  updateProgressBar(JSON.parse(event.data));
});

source.onerror = () => {
  console.log('Connection lost, reconnecting...');
};

The EventSource API automatically handles reconnection and sends the last event ID, allowing your server to resume from where the connection dropped. This makes SSE particularly reliable for long-running operations.

Combining SSE with Claude Skills

When building AI-powered applications with Claude Code, SSE becomes valuable for streaming responses. Many Claude skills work well with streaming architectures:

Here’s how you might stream Claude Code responses to a client:

async function streamClaudeResponse(prompt) {
  const response = await fetch('/api/claude/stream', {
    method: 'POST',
    body: JSON.stringify({ prompt })
  });
  
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value);
    // Parse SSE format and append to UI
    displayChunk(chunk);
  }
}

Event Routing and Filtering

For complex applications, use named events to route messages to different handlers:

@app.route('/updates')
def updates():
    def generate():
        # Send status updates
        yield "event: status\ndata: {\"stage\": \"loading\"}\n\n"
        
        # Send progress
        for i in range(100):
            yield f"event: progress\ndata: {i}\n\n"
            
        # Send completion
        yield "event: complete\ndata: {}\n\n"
    
    return Response(generate(), mimetype='text/event-stream')

Client-side routing:

source.addEventListener('status', (e) => updateStatus(e.data));
source.addEventListener('progress', (e) => updateProgress(e.data));
source.addEventListener('complete', (e) => finishTask(e.data));

This pattern keeps your client code organized when multiple event types flow through a single connection.

Error Handling and Reconnection

SSE handles reconnection automatically, but you should implement graceful degradation:

source.onerror = (error) => {
  if (source.readyState === EventSource.CLOSED) {
    // Manual reconnect after delay
    setTimeout(() => {
      source = new EventSource('/stream');
    }, 5000);
  }
};

For critical applications, the supermemory skill can help you track connection health metrics and alert you when streams fail unexpectedly.

Performance Considerations

SSE connections consume server resources. For high-traffic applications:

import redis

@app.route('/stream')
def stream():
    pubsub = redis.pubsub()
    pubsub.subscribe('updates')
    
    for message in pubsub.listen():
        if message['type'] == 'message':
            yield f"data: {message['data']}\n\n"

This Redis-backed approach scales horizontally and handles thousands of simultaneous connections efficiently.

Testing Your SSE Endpoints

Use the tdd skill to write comprehensive tests for your streaming endpoints:

def test_sse_endpoint():
    response = client.get('/stream')
    
    assert response.status_code == 200
    assert response.content_type == 'text/event-stream'
    
    # Read streamed content
    lines = response.response
    assert any(b'data:' in line for line in lines)

The webapp-testing skill can also validate SSE behavior in browser environments, checking that events arrive within expected timeframes and that reconnection works after network interruptions.

Conclusion

Server-Sent Events offer a straightforward solution for real-time streaming in web applications. The protocol is simple, works natively in browsers, and handles reconnection automatically. By combining SSE with Claude Code skills like tdd, webapp-testing, frontend-design, and supermemory, you can build robust real-time features while maintaining code quality and user experience.

Whether you’re streaming AI responses, live logs, or notification updates, SSE provides a reliable foundation that integrates well with modern development workflows.

Built by theluckystrike — More at zovo.one