A production-ready AI real estate agent with real-time streaming responses using Server-Sent Events (SSE). This implementation adds streaming capabilities to the secure MCP architecture from Part 3.
📍 Current Branch:
part-4-sse
This is Part 4 of a 4-part series showing the evolution from a simple chatbot to a production-ready AI agent system. This part adds real-time streaming with SSE while maintaining all security features and the frontend UI at localhost:3000.
Building on the secure MCP architecture from Part 3, this branch adds real-time streaming capabilities:
- 📡 Server-Sent Events: Real-time streaming of AI responses
- 💭 Thinking Indicators: Visual feedback when AI is processing vs responding
- 📝 Progressive Rendering: Stream responses character-by-character as generated
- 🔄 Auto Reconnection: Automatic retry on connection drops
- ⏱️ Production Timeouts: Configurable timeouts for all operations
- 🎯 Event Types: Multiple event types (thinking, content, error, done)
- 🔗 Connection Management: Graceful SSE connection lifecycle
- All features from Part 3 (JWT auth, MCP microservices, user management)
- Real-time streaming AI responses
- Enhanced UX with thinking indicators
- Robust error handling and reconnection
- Production-ready timeout configuration
The project maintains the secure MCP microservices architecture from Part 3 with added streaming layers:
- SSE Controller: Handles streaming endpoints
- Event Service: Manages SSE connections and events
- Stream Manager: Coordinates multi-step streaming operations
// Different event types sent via SSE
'thinking' // AI is processing (tool calls, reasoning)
'content' // Streaming response content
'error' // Error occurred during processing
'done' // Response completed successfully
/agents/chat-stream
- Protected streaming chat endpoint/sse/health
- SSE connection health check
The chat interface provides a smooth, real-time experience:
- Thinking Indicators: Shows "🤔 Thinking..." when AI processes requests
- Progressive Text: Response appears character-by-character
- Connection Status: Visual indicators for SSE connection health
- Auto Reconnect: Seamless reconnection if connection drops
- User sends message
- Shows "Thinking..." indicator
- Tool execution feedback (if applicable)
- Progressive response streaming begins
- Final response completion
- Uses native EventSource API
- Fallback for older browsers
- Automatic retry logic
- Graceful degradation
- Node.js 18+
- npm 9+
- OpenRouter API key
- Clone the repository:
git clone [email protected]:lorenseanstewart/llm-tools-series.git
cd llm-tools-series
npm run install-all # Installs dependencies for all workspaces
Note: The default branch is
part-4-sse
which contains the complete project with Server-Sent Events implementation.
- Setup environment:
There are FOUR .env files you need to update. In the three directories within the apps directory, remove the .example
part of the file name .env.example.
. The main-app
also needs your open router key. The fourth .env file is at the root of the project and also needs you open router key.
npm run setup
Important: You need to configure THREE .env files with matching JWT_SECRET:
apps/main-app/.env
- Set your OpenRouter API key and JWT_SECRETapps/mcp-listings/.env
- Add the same JWT_SECRETapps/mcp-analytics/.env
- Add the same JWT_SECRET
The JWT_SECRET must be identical across all services for authentication to work.
- Start all services:
npm run dev
This starts:
- Main app with streaming UI: http://localhost:3000
- MCP Listings server: http://localhost:3001
- MCP Analytics server: http://localhost:3002
- Experience real-time streaming:
- Visit http://localhost:3000
- Login with your credentials (or register)
- Ask the AI agent a question
- Watch the real-time response streaming!
Connect to streaming chat:
# First authenticate to get JWT token
TOKEN=$(curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "securepassword123"}' \
| jq -r '.access_token')
# Connect to SSE stream
curl -X POST http://localhost:3000/agents/chat-stream \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: text/event-stream" \
-H "Cache-Control: no-cache" \
-d '{"userMessage": "Find me homes in Portland"}' \
--no-buffer
The server sends events in this format:
event: thinking
data: {"status": "processing", "message": "Analyzing your request..."}
event: content
data: {"chunk": "I found several great properties in Portland"}
event: content
data: {"chunk": " that match your criteria. Here are the top options:"}
event: done
data: {"status": "completed"}
// Connect to SSE endpoint
const eventSource = new EventSource('/agents/chat-stream', {
headers: {
'Authorization': `Bearer ${token}`
}
});
// Handle different event types
eventSource.addEventListener('thinking', (event) => {
const data = JSON.parse(event.data);
showThinkingIndicator(data.message);
});
eventSource.addEventListener('content', (event) => {
const data = JSON.parse(event.data);
appendToResponse(data.chunk);
});
eventSource.addEventListener('done', (event) => {
hideThinkingIndicator();
markResponseComplete();
});
eventSource.addEventListener('error', (event) => {
handleStreamError(event);
});
// Configurable via environment variables
{
timeout: process.env.SSE_TIMEOUT || 120000, // 2 minutes
keepAlive: process.env.SSE_KEEPALIVE || 30000, // 30 seconds
retry: process.env.SSE_RETRY || 3000 // 3 seconds
}
- Chunk Size: Configurable response chunking
- Delay: Optional delay between chunks for demo effect
- Buffer: Response buffering strategies
The test suite includes SSE-specific testing:
# Run all tests including SSE tests
npm run test
# Run SSE-specific tests
npm run test -w apps/main-app -- sse
# Test streaming with coverage
npm run test:cov
SSE test coverage includes:
- Event stream creation and management
- Authentication with streaming endpoints
- Error handling and reconnection
- Event type validation
- Connection lifecycle testing
- Use browser dev tools Network tab to see SSE connections
- Monitor EventSource connection states
- Test connection drops and reconnection
- Verify event ordering and completeness
- Connection drops: Check network stability and timeout settings
- Auth failures: Ensure JWT token is valid and passed correctly
- Event parsing: Verify JSON format in event data
- Browser limits: Be aware of concurrent SSE connection limits
- SSE connections are long-lived
- Monitor server memory usage with many concurrent connections
- Consider connection pooling for production
- Implement proper cleanup on client disconnect
Congratulations! You've completed the full series. Here's what you've learned:
- Part 1:
part-1-chatbot-to-agent
- Foundation with direct tool integration - Part 2:
part-2-mcp-scaling
- Microservices with MCP - Part 3:
part-3-mcp-security
- JWT authentication and security - Part 4:
part-4-sse
- Real-time streaming with Server-Sent Events
This Part 4 implementation is production-ready with:
- Secure authentication
- Scalable microservices
- Real-time user experience
- Comprehensive error handling
- Full test coverage
MIT