Why Stream Live Sports Data to Claude?
Hey there, Claude enthusiasts! Picture this: you're glued to a Premier League match, and your Claude agent is right beside you, crunching live stats, predicting the next goal, or generating witty commentary. Sounds futuristic? It's not—with Model Context Protocol (MCP) servers, you can pipe real-time sports data straight into Claude's brain.
MCP servers extend Claude's capabilities by acting as dynamic data bridges. Unlike static prompts, they let Claude agents fetch fresh context on-demand via tool calls. For live sports, this means pulling scores, player stats, and odds from APIs and streaming them seamlessly. Perfect for analytics, betting bots, or fan apps.
In this guide, we'll build a Node.js MCP server using Server-Sent Events (SSE) for streaming live soccer data from the free API-Football (formerly API-Football). Then, integrate it with a Claude agent via the Anthropic SDK. By the end, you'll have a setup for real-time predictions and commentary.
What you'll build:
- An MCP server polling a sports API every 30 seconds.
- SSE endpoint for Claude to subscribe to live updates.
- Claude agent tool that streams data and analyzes it on-the-fly.
Let's dive in! (Estimated time: 45 minutes)
Prerequisites
Before we code, grab these:
- Node.js (v18+): Download here.
- API-Football key: Sign up at api-sports.io for a free tier (1000 req/month). Covers live soccer from 1100+ leagues.
- Anthropic API key: From console.anthropic.com. Claude Opus or Sonnet recommended for complex analysis.
- Basic terminal & code editor (VS Code is great).
- Familiarity with JavaScript (beginner-friendly steps ahead).
Pro tip: Test API-Football with their docs—endpoint like https://v3.football.api-sports.io/fixtures/live gives global live matches.
Step 1: Set Up Your MCP Server Project
Create a new directory and initialize:
git clone <your-repo> || mkdir claude-sports-mcp && cd claude-sports-mcp
npm init -y
npm install express cors eventsource axios node-cron
express: Web server.cors: Cross-origin for Claude tools.axios: API calls.node-cron: Polling scheduler.
Why cron? Sports APIs don't push; we poll efficiently.
Step 2: Build the Core MCP Server
Create server.js:
const express = require('express');
const cors = require('cors');
const axios = require('axios');
const cron = require('node-cron');
const app = express();
app.use(cors());
app.use(express.json());
const PORT = 3000;
const API_KEY = 'YOUR_API_SPORTS_KEY'; // Env var in prod: process.env.API_KEY
const API_BASE = 'https://v3.football.api-sports.io';
// In-memory cache for live data (update every 30s)
let liveData = { fixtures: [], timestamp: null };
// Poll live fixtures
async function fetchLiveData() {
try {
const response = await axios.get(`${API_BASE}/fixtures?live=all`, {
headers: { 'x-apisports-key': API_KEY }
});
liveData = {
fixtures: response.data.response || [],
timestamp: new Date().toISOString()
};
console.log(`Updated live data: ${liveData.fixtures.length} matches`);
} catch (error) {
console.error('API fetch error:', error.message);
}
}
// Cron job: every 30 seconds
cron.schedule('*/30 * * * * *', fetchLiveData);
// Initial fetch
fetchLiveData();
// SSE endpoint: /stream/live/soccer
app.get('/stream/live/soccer', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*'
});
const sendUpdate = () => {
const dataStr = JSON.stringify(liveData);
res.write(`data: ${dataStr}\
\
`);
};
sendUpdate(); // Initial
const interval = setInterval(sendUpdate, 30000); // Every 30s
req.on('close', () => {
clearInterval(interval);
res.end();
});
});
// Static GET for one-off: /live/soccer
app.get('/live/soccer', (req, res) => {
res.json(liveData);
});
app.listen(PORT, () => {
console.log(`MCP Server running at http://localhost:${PORT}`);
});
Run it:
node server.js
Visit http://localhost:3000/live/soccer—boom, live matches! SSE at /stream/live/soccer for continuous flow. This is your MCP endpoint—Claude will call it like a tool.
MCP Protocol Note: MCP servers follow Anthropic's spec: JSON responses, SSE for streams. Claude's SDK auto-handles auth/context via mcp:// URIs (in beta).
Step 3: Define the Claude Tool for Your MCP Server
Claude agents shine with tools. Create agent.js using Anthropic SDK:
npm install @anthropic-ai/sdk
const Anthropic = require('@anthropic-ai/sdk');
const { EventSource } = require('eventsource'); // For SSE in tools
const anthropic = new Anthropic({ apiKey: 'YOUR_ANTHROPIC_KEY' });
const MCP_TOOL = {
name: 'get_live_sports_data',
description: 'Fetch or stream live soccer data from MCP server. Use for real-time analysis.',
input_schema: {
type: 'object',
properties: {
stream: { type: 'boolean', description: 'True for SSE stream' },
league: { type: 'string', enum: ['PL', 'UCL', 'MLS'] } // Filter optional
}
}
};
async function toolHandler(input) {
const url = input.stream
? 'http://localhost:3000/stream/live/soccer'
: 'http://localhost:3000/live/soccer';
if (!input.stream) {
const res = await fetch(url);
return await res.json();
}
// Stream handling (simplified; parse SSE)
return new Promise((resolve) => {
const eventSource = new EventSource(url);
let buffer = '';
eventSource.onmessage = (event) => {
buffer += event.data;
// Resolve on first update for demo
if (buffer) {
eventSource.close();
resolve(JSON.parse(buffer));
}
};
});
}
// Agent conversation
async function runAgent(prompt) {
const msg = await anthropic.messages.create({
model: 'claude-3-5-sonnet-20240620',
max_tokens: 1024,
tools: [MCP_TOOL],
messages: [{ role: 'user', content: prompt }],
tool_choice: { type: 'auto' }
});
// Handle tool use (loop for streams)
console.log(msg.content);
}
// Test
runAgent('Analyze live Premier League games and predict winners.');
Key Insight: Claude auto-calls get_live_sports_data when needed. For streams, extend with stream: true—agent loops for updates.
Step 4: Test Your Setup
- Start MCP server:
node server.js. - Run agent:
node agent.js.
Output example:
Claude: Currently, 5 live PL matches. Arsenal leads 2-0 vs. Chelsea (possession 62%). Prediction: Arsenal wins 3-1 (based on xG 2.1 vs 0.8).
Live update: Goal! Chelsea equalizes...
Tweak prompt: "Act as sports commentator for live soccer. Use tool every 30s for updates."
Step 5: Advanced Features – Predictions & Commentary
Enhance your agent:
- ML Predictions: Add simple logistic regression on stats (use
ml-matrixnpm).
// In toolHandler, post-process
function predictWinner(fixture) {
const homeXG = fixture.home.xg || 1.2;
return homeXG > 1.0 ? 'Home win' : 'Away win';
}
-
Multi-league: Extend
/stream/:sport(soccer, basketball via different APIs). -
Claude Code Integration: In Claude Code CLI, add MCP URI:
claude-code --mcp http://localhost:3000. -
Productionize: Dockerize, add Redis cache, NGINX for SSE proxy. Deploy to Render/Vercel.
Error Handling: Rate limits? Fallback to cached data. API down? Claude prompt: "If no data, use last known."
Real-World Use Cases
- Fantasy Sports Bot: Streams lineups, scores to optimize trades.
- Betting Alerts: Claude analyzes odds shifts via OddsAPI integration.
- Team Dashboards: n8n workflow pulls MCP to Slack.
- Enterprise: Legal/sports betting firms use for compliant analytics.
Compared to GPT: Claude's superior reasoning + MCP streaming = fewer hallucinations on live data.
Wrapping Up
You've just supercharged Claude with live sports superpowers! This MCP server scales to any streaming API (NBA, NFL via Sportradar). Fork on GitHub, experiment, and share in Claude Directory comments.
Next Steps:
- Add WebSockets for bidirectional (Claude sends filters).
- Integrate with MCP ecosystem tools like Claude Agents SDK.
- Check Anthropic updates—MCP v2 promises native streaming.
Questions? Hit the forums. Go build that unbeatable agent!
(Word count: 1428)
Stay ahead of the AI curve
The most important updates, news, and content — delivered in one weekly newsletter.