Skip to main content
Glama
jjaquezito

Football Intelligence MCP

by jjaquezito

Football Intelligence MCP

Un servidor local de Model Context Protocol que da a cualquier host MCP — Claude Desktop, Claude Code o un chatbot personalizado — acceso a una base de datos histórica de fútbol curada que cubre 36 982 partidos de las siete mejores competiciones europeas de 2010 a 2025.

El protocolo está implementado directamente sobre JSON-RPC 2.0, sin usar ningún SDK de MCP: cada mensaje se construye y analiza a mano siguiendo la especificación de 2025-06-18.

Qué hay en la base de datos

Datos extraídos originalmente de API-Football, normalizados en PostgreSQL.

Competición

ID de liga

Temporadas

Premier League

39

2010–2025

La Liga

140

2010–2025

Serie A

135

2010–2025

Bundesliga

78

2010–2025

Ligue 1

61

2010–2025

Primeira Liga

94

2010–2025

UEFA Champions League

2

2011–2025

Tabla

Filas

fixtures

36 982

fixture_events

476 186

fixture_player_statistics

881 739

lineup_players

1 436 165

fixture_team_statistics

51 822

players

26 996

standings

2 329

Límites de cobertura conocidos

El servidor informa de estos límites en lugar de adivinar, y tú deberías hacer lo mismo:

  • Las estadísticas de partidos comienzan en 2015. Las temporadas 2010–2014 contienen resultados, goles, eventos y alineaciones, pero no datos de tiros, posesión o pases.

  • Los goles esperados (xG) solo existen a partir de 2023 y nunca para la Champions League.

  • Los datos de formación y entrenador comienzan en 2015.

  • 58 partidos (0,16 %) tienen un gol que falta en su lista de eventos: una brecha de API-Football. Los marcadores no se ven afectados; provienen del registro del partido, no de sumar eventos.

Llama a la herramienta data_coverage para comprobar qué existe para cualquier liga y temporada.

Related MCP server: api-football-mcp-server

Instalación

Requiere Python 3.10+ y PostgreSQL 14+.

git clone https://github.com/jaq23369/football-intelligence-mcp.git
cd football-intelligence-mcp

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

createdb football
pg_restore -d football data/football.dump

cp .env.example .env      # edit DATABASE_URL if your setup differs

Verifica la restauración:

psql -d football -c "SELECT count(*) FROM fixtures;"
#  count
# -------
#  36982

Ejecutar el servidor

python server.py

El servidor habla JSON-RPC sobre stdio. Normalmente lo lanza un host MCP en lugar de hacerlo manualmente, pero puedes manejarlo directamente:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"manual","version":"1.0"}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | python server.py

Claude Desktop

Añade a claude_desktop_config.json:

{
  "mcpServers": {
    "football": {
      "command": "/absolute/path/to/football-intelligence-mcp/.venv/bin/python",
      "args": ["/absolute/path/to/football-intelligence-mcp/server.py"]
    }
  }
}

Claude Code

claude mcp add football -- /absolute/path/to/.venv/bin/python /absolute/path/to/server.py

Protocolo

Transporte: stdio, JSON delimitado por líneas nuevas. Versión del protocolo 2025-06-18.

Método

Notas

initialize

Handshake. Devuelve serverInfo y capacidades.

notifications/initialized

Notificación del cliente. Sin id, sin respuesta.

ping

Comprobación de actividad. Devuelve {}.

tools/list

Devuelve las once definiciones de herramientas.

tools/call

Ejecuta una herramienta.

Los errores siguen JSON-RPC 2.0: -32700 error de análisis, -32600 solicitud no válida, -32601 método no encontrado, -32602 parámetros no válidos, -32603 error interno.

Los fallos a nivel de herramienta no son errores JSON-RPC: devuelven un resultado normal con isError: true, para que el modelo pueda leer el mensaje y recuperarse.

stdout solo lleva JSON-RPC. Todos los diagnósticos van a stderr.

Herramientas

search_team

Encuentra equipos por nombre parcial, ordenados por cuántos partidos tienen registrados. Llama a esto primero: todas las demás herramientas de equipo necesitan un team_id.

Parámetro

Tipo

Requerido

Por defecto

query

string

sí

—

limit

integer

no

10

{"name": "search_team", "arguments": {"query": "Liverpool", "limit": 1}}
[{"team_id": 40, "name": "Liverpool", "country": "England",
  "founded": 1892, "partidos": 762,
  "primera_temporada": 2010, "ultima_temporada": 2025}]

search_player

Encuentra jugadores por nombre, ordenados por minutos jugados.

Parámetro

Tipo

Requerido

Por defecto

query

string

sí

—

limit

integer

no

10

get_match

Registro completo del partido: marcador, estadio, árbitro, estadísticas por equipo y cada gol con minuto y asistencia. Los partidos anteriores a 2015 devuelven una nota explícita en lugar de estadísticas vacías.

Parámetro

Tipo

Requerido

fixture_id

integer

sí

get_team_form

Forma reciente: racha, puntos, goles a favor y en contra.

before restringe el cálculo a partidos estrictamente anteriores a esa fecha, lo que permite reconstruir el estado de un equipo en cualquier momento pasado. Esta es la protección contra el sesgo de mirar hacia adelante al construir características predictivas.

Parámetro

Tipo

Requerido

Por defecto

team_id

integer

sí

—

last

integer

no

5

before

string (YYYY-MM-DD)

no

—

{"name": "get_team_form",
 "arguments": {"team_id": 40, "last": 5, "before": "2020-01-01"}}

get_head_to_head

Balance de victorias/empates/derrotas entre dos equipos, sus enfrentamientos más recientes y promedios por equipo (goles por partido, tarjetas amarillas/rojas, faltas, córners) a lo largo de su historial completo: contexto útil para decidir una apuesta, no solo un número de predicción. Las tarjetas/faltas/córners solo están disponibles para partidos desde 2015; los partidos sin estadísticas se excluyen de esos promedios, no se cuentan como cero.

Parámetro

Tipo

Requerido

Por defecto

team_a

integer

sí

—

team_b

integer

sí

—

limit

integer

no

10

get_team_season

Posición final en la liga, puntos y goles, junto con promedios por partido de tiros, posesión, córners y precisión de pases.

Parámetro

Tipo

Requerido

team_id

integer

sí

league_id

integer

sí

season

integer

sí

Las temporadas se nombran por su año de inicio: 2024 significa la temporada 2024-25.

get_player_season

Totales por temporada del jugador agregados a partir de registros a nivel de partido: goles, asistencias, minutos, tiros, pases clave, tarjetas y valoración media.

Parámetro

Tipo

Requerido

player_id

integer

sí

season

integer

sí

compare_teams

Forma reciente de dos equipos más su historial cara a cara, en una sola llamada.

Parámetro

Tipo

Requerido

Por defecto

team_a

integer

sí

—

team_b

integer

sí

—

last

integer

no

10

compare_players

Totales de dos jugadores para la misma temporada, lado a lado.

Parámetro

Tipo

Requerido

player_a

integer

sí

player_b

integer

sí

season

integer

sí

data_coverage

Qué existe realmente en la base de datos, por liga y temporada. Úsalo antes de afirmar que falta un dato.

Parámetro

Tipo

Requerido

league_id

integer

no

season

integer

no

predict_match

Probabilidad de victoria/empate/derrota para un partido, a partir de un modelo entrenado con 23 168 partidos (2015–2025, seis ligas domésticas — Champions League excluida, su formato de eliminatorias no es comparable a una tabla de todos contra todos). Se compararon dos candidatos cara a cara en una temporada de validación reservada (regresión logística vs. un clasificador de árboles con gradiente); se mantuvo el que tenía mejor pérdida logarítmica de validación. Consulta model.metricas_prueba_2025 en la propia respuesta de la herramienta para obtener la puntuación de prueba honesta, nunca tocada durante la selección.

El partido no necesita existir ya en la base de datos. El Elo actual de cada equipo, la forma reciente y los días de descanso se guardan en una instantánea team_current_form, actualizada independientemente de cualquier partido individual, por lo que esto funciona tanto para un partido programado para la próxima semana como para uno jugado hace cinco años.

Parámetro

Tipo

Requerido

home_team_id

integer

sí

away_team_id

integer

sí

{"name": "predict_match", "arguments": {"home_team_id": 529, "away_team_id": 531}}
{
  "local": "Barcelona", "visitante": "Athletic Club",
  "probabilidad_local": 0.779, "probabilidad_empate": 0.145, "probabilidad_visitante": 0.076,
  "modelo": "logistic_regression",
  "advertencia": "Probabilidad estadistica basada en historial, no una garantia..."
}

El modelo entrenado se incluye en data/predict_model.joblib (unos pocos KB: un pipeline de scikit-learn ajustado, no pesos brutos). El reentrenamiento requiere el pipeline completo de características (conocimiento/ml/), que vive en el repositorio privado del proyecto, no aquí, la misma relación que data/football.dump con el pipeline de extracción que lo construyó.

Sesión de ejemplo

¿Qué equipo ganó la Premier League en 2015?

→ search_team {"query": "Leicester"}
→ get_team_season {"team_id": 46, "league_id": 39, "season": 2015}

Leicester City, con 81 puntos de 23 victorias, 12 empates y 3 derrotas, y solo un 42,7 % de posesión media, algo inusual para un campeón.

Arquitectura

MCP host  ──JSON-RPC/stdio──>  server.py  ──>  knowledge/engine.py  ──>  PostgreSQL

server.py posee el protocolo y nada más. Toda la lógica de consultas vive en knowledge/engine.py, que devuelve diccionarios simples y no tiene conocimiento de MCP, por lo que se puede probar o reutilizar por completo de forma independiente.

Licencia

MIT. Los datos de fútbol provienen de API-Football y se redistribuyen aquí para uso académico.


Construido para CC3067 Redes, Universidad del Valle de Guatemala.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides programmatic access to comprehensive football statistics and live match data via API-Football, enabling applications to retrieve league standings, team fixtures, player statistics, and real-time match events.
    6
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language querying of football/soccer data via the API-Football service, providing access to leagues, teams, players, fixtures, standings, and statistics.
    2
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Access football (soccer) data including competitions, matches, standings, and team details via the Football-Data.org API.
    105 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides comprehensive soccer/football data including standings, team search, league search, match predictions, and head-to-head records via the API-Football service.
    61 npm
    MIT