Skip to main content
Glama
travisfleish

Genius Sports RSS Monitor MCP

by travisfleish
README.md
# Genius Sports RSS Monitor MCP

Read-only Model Context Protocol (MCP) server for monitoring public RSS and Atom feeds from competitor and industry websites. Built for Genius Sports competitive intelligence workflows.

## What this MCP does

This server helps an agent track public updates from sites such as:

- Sportradar news/blog pages
- Stats Perform news/blog pages
- Sports data, betting technology, fan engagement, and sports advertising publishers

It exposes five read-only tools that fetch feeds, normalize entries, filter by recency, search content, and summarize recent activity by theme.

## Supported feed types

- RSS 2.0
- Atom
- Public HTTP/HTTPS feeds only (no authentication)

## Tools

| Tool | Purpose |
| --- | --- |
| `fetch_feed` | Fetch and parse a feed; return metadata + normalized entries |
| `list_recent_entries` | Return entries from the last N days (default 14, max 30) |
| `search_feed_entries` | Search title/summary/content within a date window |
| `compare_recent_entries` | Group recent entries into competitive-intelligence themes |
| `monitor_company_feed` | Convenience wrapper with company name, entries, themes, and summary |

### Normalized entry schema

Each entry includes:

- `id`
- `title`
- `link`
- `published_at`
- `source_feed_title`
- `source_feed_url`
- `author` (optional)
- `summary_snippet`
- `content_snippet`
- `categories`
- `matched_query` (optional, search results only)

## Project structure

```text
server.ts            # Vercel + local HTTP entrypoint
api/
  health.ts          # GET /health
  server.ts          # MCP handler exports
src/
  mcp/registerTools.ts
  types.ts
  rss/
  tools/
  utils/
scripts/
  test-feed.ts       # Local feed parser smoke test
```

## Requirements

- Node.js 20+
- npm (or pnpm/yarn)

## Run locally

1. Install dependencies:

```bash
npm install
```

2. Copy optional environment variables:

```bash
cp .env.example .env
```

3. Start the local server:

```bash
npm run dev
```

This runs a local Node HTTP server and serves:

- MCP endpoint: `http://localhost:3000/mcp`
- Health check: `http://localhost:3000/health`

For Vercel-native local emulation, use:

```bash
npm run dev:vercel
```

4. Smoke-test feed parsing without MCP:

```bash
npm run test:feed
```

Or test a specific feed:

```bash
npm run test:feed -- "https://example.com/feed.xml"
```

5. Type-check:

```bash
npm run typecheck
```

### Example curl checks

Health:

```bash
curl -s http://localhost:3000/health | jq
```

MCP initialize (Streamable HTTP clients handle session setup automatically; this is mainly for debugging):

```bash
curl -s -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'
```

## Deploy to Vercel

1. Install the Vercel CLI if needed:

```bash
npm i -g vercel
```

2. Deploy:

```bash
vercel
```

For production:

```bash
vercel --prod
```

3. Use your deployment URL:

- MCP endpoint: `https://YOUR-PROJECT.vercel.app/mcp`
- Health endpoint: `https://YOUR-PROJECT.vercel.app/health`

### Recommended Vercel settings

- Enable [Fluid Compute](https://vercel.com/docs/functions/fluid-compute) for better MCP session behavior
- `vercel.json` already sets `maxDuration: 60` for the MCP handler

### Optional environment variables

Set in Vercel Project Settings → Environment Variables:

| Variable | Default | Description |
| --- | --- | --- |
| `FEED_FETCH_TIMEOUT_MS` | `15000` | Feed fetch timeout in milliseconds |
| `FEED_USER_AGENT` | `GeniusSportsRSSMonitor/1.0` | Custom User-Agent for feed requests |

## Connect as a Custom MCP in ChatGPT Agent Builder

1. Deploy this server to a public HTTPS URL (for example on Vercel).
2. Open ChatGPT → Agent Builder (or your agent configuration UI).
3. Add a **Custom MCP** integration.
4. Choose **Streamable HTTP** as the transport.
5. Set the MCP server URL to:

```text
https://YOUR-PROJECT.vercel.app/mcp
```

6. Save and connect. The agent should discover these tools:

- `fetch_feed`
- `list_recent_entries`
- `search_feed_entries`
- `compare_recent_entries`
- `monitor_company_feed`

7. Verify connectivity by asking the agent to call `monitor_company_feed` with a public test feed.

### Cursor / Claude Desktop config example

```json
{
  "mcpServers": {
    "genius-sports-rss-monitor": {
      "url": "https://YOUR-PROJECT.vercel.app/mcp"
    }
  }
}
```

For local development:

```json
{
  "mcpServers": {
    "genius-sports-rss-monitor": {
      "url": "http://localhost:3000/mcp"
    }
  }
}
```

## Example public feeds for testing

Use any public RSS/Atom URL. Good generic test feeds:

- BBC News RSS: `https://feeds.bbci.co.uk/news/rss.xml`
- NYT Technology RSS: `https://rss.nytimes.com/services/xml/rss/nyt/Technology.xml`
- W3C News Atom: `https://www.w3.org/blog/news/feed/atom/`

Competitor/industry placeholders to configure in your agent (replace with the current public feed URL for each site):

- Sportradar newsroom/blog feed: `https://sportradar.com/content-type/newsroom/feed/` *(verify current public feed URL)*
- Stats Perform newsroom/blog feed: `https://www.statsperform.com/feed/` *(verify current public feed URL)*

Example agent prompt:

```text
Monitor Sportradar's public feed for the last 14 days and summarize product updates, partnerships, and betting-related announcements.
```

Example tool call:

```json
{
  "company_name": "Sportradar",
  "feed_url": "https://feeds.bbci.co.uk/news/rss.xml",
  "days_back": 14,
  "limit": 10
}
```

## Theme categories

`compare_recent_entries` and `monitor_company_feed` use lightweight keyword heuristics to classify entries into:

- partnerships
- launches
- product updates
- customer wins
- thought leadership
- betting
- advertising
- fan engagement
- data/integrity
- other

## Known limitations

- Read-only: no write actions, no authenticated feeds, no scraping of pages without RSS/Atom
- Some sites publish HTML pages but not machine-readable feeds; those URLs will fail validation or parsing
- Theme grouping is heuristic, not ML-based
- Feed publishers may rate-limit or block unknown user agents
- Entries without reliable publish dates are included in recent results
- Very large feeds are truncated by the `limit` parameter rather than paginated
- Serverless cold starts may add latency on first request

## Security notes

- Only public HTTP/HTTPS URLs are accepted
- Requests use safe timeouts and truncated response snippets
- No secrets are logged
- No persistent storage of fetched feed content

## License

MIT