Skip to main content
Glama
MoRocety

fotmob-mcp

by MoRocety
README.md
# fotmob-mcp

Exploring [FotMob](https://www.fotmob.com) football data. Two things live here:

1. An MCP (Model Context Protocol) server for querying FotMob from any MCP-compatible LLM client.
2. A Premier League stats dashboard: a pipeline that pulls full-squad player stats into SQLite,
   plus a web UI for sorting players by any stat and viewing FBref-style percentile breakdowns.

Both talk to FotMob's public web API endpoints (undocumented, used by fotmob.com itself), so
behavior may change if FotMob changes their API.

## Stats dashboard

Pulls every Premier League squad (~580 players) with meta data (age, position, foot, nationality,
height, market value) and ~37 season-long stat categories (goals, xG, xA, tackles, defensive
actions, goalkeeping stats, etc.) into a local SQLite database, then serves a dashboard to sort,
filter, and compare players — including percentile bars against same-position peers, similar to
old FBref scouting reports.

```bash
npm install
npm run pipeline      # fetch everything into data/fotmob.db (~5-10 min; foot/value lookups are the slow part)
npm run pipeline:fast # same, but skips the slow per-player foot/market-value enrichment
npm run web           # serve the dashboard at http://localhost:3000
```

Re-run `npm run pipeline` periodically to refresh with the latest stats (it's a full upsert, safe
to re-run anytime — e.g. weekly during the season). The SQLite file lives at `data/fotmob.db` and
is gitignored; each environment builds its own.

### Dashboard structure

- `pipeline/` — fetches league squads + stat leaderboards from FotMob, writes to SQLite
- `server/` — Express API (`/api/meta`, `/api/players`, `/api/players/:id`, `/api/leaders/:statName`) serving the SQLite data
- `public/` — vanilla JS/HTML/CSS frontend: sortable player table, category tabs (Standard/Shooting/Passing/Possession/Defense/Discipline/Goalkeeping), player detail drawer with percentile bars, and a leaders view

No hosting is set up yet — this runs locally. To make it publicly accessible, deploy `server/` (it
serves both the API and the static frontend) to any Node host with a persistent disk for the
SQLite file (e.g. Render, Railway, Fly.io, a VPS), and schedule `npm run pipeline` to run periodically there.

## MCP server

## Tools

- `get_matches_by_date` — all matches across leagues on a given date (`YYYYMMDD`)
- `get_match_details` — lineups, stats, events, and score for a match
- `get_team` — squad, fixtures, recent results, and table position for a team
- `get_league` — table, top scorers, and fixtures for a league
- `get_player` — bio, stats, and recent ratings for a player
- `search` — search teams, players, leagues, or matches by name

## Setup

```bash
npm install
npm run build
```

## Usage

Run directly:

```bash
npm start
```

Or point an MCP client at it, e.g. in Claude Code / Claude Desktop config:

```json
{
  "mcpServers": {
    "fotmob": {
      "command": "node",
      "args": ["/absolute/path/to/fotmob-mcp/dist/index.js"]
    }
  }
}
```

During development, run without building first:

```bash
npm run dev
```

## Finding IDs

FotMob team/league/player/match IDs aren't obvious from names alone — use the `search` tool
first to resolve a name to an ID, then feed that ID into the other tools.

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a clearly distinct resource: matches by date, match details, teams, leagues, players, and search. There is no meaningful overlap between the entity-specific getters and the general search tool.

Naming Consistency4/5

Five tools follow the consistent get_<resource> pattern, while 'search' is a bare verb that breaks the pattern slightly. The naming is otherwise predictable and all snake_case.

Tool Count5/5

Six tools is a well-scoped set for a football data server, covering all major entity types without redundancy. Each tool earns its place in the surface.

Completeness5/5

The surface covers core football data needs: matches by date, detailed match info, teams, leagues, players, and discovery via search. There are no dead ends or obvious missing operations for the stated domain.

Maintenance

ActivityMaintained
ResponsivenessSyncing