Skip to main content
Glama
nickdesi

FFBB MCP Server

🏀 FFBB MCP Server

Le basket français officiel, directement dans vos assistants IA.

Serveur MCP pour consulter calendriers, classements, bilans, résultats, scores live et règlements officiels de la FFBB (Fédération Française de Basketball).

🇺🇸 English Summary: Official Model Context Protocol (MCP) server for French Basketball (FFBB). Connect your AI assistants (Claude, Cursor, Copilot, ChatGPT, Antigravity) to live French basketball schedules, standings, scores, team records, club directories, and official federal regulations via Streamable HTTP or Stdio.

🌐 Site · 🧩 Extension VS Code · 📚 Documentation · 💬 Support

Version Python CI MCP Glama License: Apache 2.0 GitHub stars



⚡ Démarrage express (< 2 min)

TIP

Aucune installation requise : le serveur est hébergé publiquement. Ajoutez simplement l'endpoint MCP à votre client :

https://ffbb.desimone.fr/mcp

Puis posez vos questions en langage naturel :

« Quel est le prochain match des U15 de mon club (nommer le club) ? » « Donne-moi le classement de la poule des U15M2 du Stade Clermontois et le dernier résultat. » « Y a-t-il des matchs en direct ce soir ? »

👉 Voir la section Installation pour brancher l'endpoint sur VS Code, Claude, Cursor, etc.


Related MCP server: SportScore

✨ Fonctionnalités

  • 🗓️ Calendriers & résultats — matchs passés et à venir, par club ou par équipe.

  • 🏆 Classements — poules complètes avec points, différentiel et forme.

  • 📊 Bilans agrégés — toutes phases confondues en un seul appel.

  • 🔴 Scores live — matchs en cours, mis à jour toutes les 30 s.

  • 🔎 Recherche universelle — clubs, compétitions, salles, engagements.

  • 🚀 Optimisé pour les LLM — réponses agrégées et cache TTL pour réduire le contexte et le nombre d'appels.


🚀 Installation

VS Code / GitHub Copilot

Option recommandée — installer l'extension FFBB Basketball MCP depuis les releases, puis ouvrir Copilot Chat en mode agent.

Alternative sans extension — ➕ Installer FFBB MCP en un clic

Claude Desktop

  1. Ouvrez les Paramètres de Claude, puis Connecteurs (ou Plugins).

  2. Cliquez sur Ajouter un connecteur personnalisé.

  3. Renseignez l'URL publique https://ffbb.desimone.fr/mcp et validez.

Claude Desktop n'accepte que le transport stdio local : on utilise donc le bridge SSE officiel via npx.

WARNING

Prérequis : Node.js (inclut npm et npx). Sans Node.js, privilégiez l'Option A.

{
  "mcpServers": {
    "ffbb": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/client-sse", "https://ffbb.desimone.fr/mcp"]
    }
  }
}

Cursor / autres clients MCP

Configurez un serveur MCP distant :

Champ

Valeur

Type

Streamable HTTP

URL

https://ffbb.desimone.fr/mcp

Google Antigravity

Configurez directement l'URL distante dans mcp_config.json via la directive native serverUrl :

{
  "mcpServers": {
    "ffbb_mcp": {
      "serverUrl": "https://ffbb.desimone.fr/mcp"
    }
  }
}

🧰 Outils principaux

Outil

Usage

NOTE

Référence complète des paramètres :docs/TOOLS_REFERENCE.md.


🌐 Instance publique

Endpoint MCP (transport Streamable HTTP) :

https://ffbb.desimone.fr/mcp

Endpoint

URL

📊 Dashboard

https://ffbb.desimone.fr/dashboard

📈 Métriques

https://ffbb.desimone.fr/metrics.json

❤️ Santé

https://ffbb.desimone.fr/health


🏗️ Architecture

flowchart LR
    A[Client MCP<br/>Claude · Cursor · Antigravity] -->|Streamable HTTP / Stdio| B[FFBB MCP Server<br/>MCPServer]
    B --> C[Services métier<br/>Cache SWR & Agrégation]
    C --> D[ffbb-data-client<br/>SDK Python]
    D --> E[(API FFBB · Meilisearch · Directus)]

Points clés :

  • Double transport : Streamable HTTP distant (spec 2026-07-28, Stateless Core) ou Stdio local (uvx) ;

  • SDK Python découplé : Requêtes vers les sources fédérales et parsing Pydantic v2 délégués à ffbb-data-client ; le serveur MCP ne les interroge pas directement ;

  • Agrégation composite : 12 outils optimisés pour réduire les allers-retours et le contexte LLM ;

  • Cache intelligent & SWR : Stale-While-Revalidate avec TTL par type de donnée (30 s lives, 1 h bilans, 24 h clubs) ;

  • Observabilité complète : Dashboard HTML, métriques Prometheus, snapshot JSON et healthcheck intégrés.

Détails : docs/ARCHITECTURE.md et docs/PERFORMANCE.md.


💻 Développement local

uv sync --extra dev       # installer les dépendances
uv run ruff format .      # formater
uv run ruff check --fix . # linter
uv run mypy src           # vérifier les types
uv run pytest             # lancer les tests

Voir CONTRIBUTING.md pour les règles de contribution.


🧪 Tests

uv run pytest             # tests unitaires + couverture
uv run pytest tests/      # ciblé

Le pipeline CI (.github/workflows/ci.yml) exécute ruff, mypy, pytest et le contrôle de couverture à chaque push/PR.


📚 Documentation


🤝 Communauté


❓ Dépannage

Symptôme

Cause probable

Solution

Missing session ID / deadline exceeded

Wrapper mcp-remote ou mauvais transport

Utiliser serverUrl natif dans mcp_config.json (voir Google Antigravity)

Claude Desktop refuse l'URL http

Claude Desktop impose stdio

Utiliser le bridge @modelcontextprotocol/client-sse via npx (voir Claude Desktop)

Données live obsolètes

Cache TTL

Attendre le rafraîchissement (≤ 30 s) ou interroger l'endpoint /health


🌟 Stargazers & Communauté

Star History Chart


Available Tools

18 tools
ffbb_bilanBilan complet toutes phasesA
Read-onlyIdempotent

Bilan complet d'une équipe toutes phases confondues en UN seul appel (V/D/N, paniers, phases).

Outil prioritaire pour 'quel est le bilan de X ?' ou 'résultats de U11M1'.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie/genre/numéro (ex: 'U11M1', 'Senior').
club_nameNoNom du club (ex: 'Stade Clermontois', 'ASVEL'). Requis si organisme_id absent.
season_idNoID de la saison FFBB (optionnel).
organisme_idNoID FFBB du club (ex: '9326' ou 'ARA0063058'). Requis si club_name absent.
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, contourne le cache.
numero_equipeNoNuméro d'équipe (ex: 1, 2).
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: a single call aggregates all phases and returns V/D/N, paniers, and phases. It does not cover every behavioral detail, but it adds meaningful value beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no filler. The main capability and single-call advantage are front-loaded, and the usage guidance is compact and directly actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description partially fills the return-value gap by naming V/D/N, paniers, and phases, and clarifies the all-phases scope. The 10-parameter anyOf selection logic is left to the schema, which is acceptable given full schema coverage, though explicit guidance on when to prefer ffbb_bilan_saison would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description's example 'U11M1' hints at using the 'categorie' parameter, but it does not add significant parameter-specific meaning beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action and resource: 'Bilan complet d'une équipe toutes phases confondues' and enumerates the returned content (V/D/N, paniers, phases). This distinguishes it from sibling tools like ffbb_bilan_saison by emphasizing the 'toutes phases' scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly marks the tool as the priority for common queries like 'quel est le bilan de X ?' or 'résultats de U11M1', giving the agent clear situational guidance. It does not explicitly mention exclusions or alternatives, but the examples and 'toutes phases' phrasing imply when it should be chosen.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_bilan_saisonBilan détaillé de saisonA
Read-onlyIdempotent

Bilan détaillé de la saison pour une équipe précise (toutes phases).

Cet outil est optimisé pour les questions du type "Quel est le bilan de la saison des U11M1 ?".

Il agrège toutes les phases (toutes poules) de la saison FFBB pour l'équipe identifiée par (organisme_id/club_name, categorie, numero_equipe).

Pour chaque phase, il retourne :

  • competition

  • poule_id

  • position

  • match_joues, gagnes, perdus, nuls

  • paniers_marques, paniers_encaissés, difference

Et fournit également un champ bilan_total qui cumule toutes les phases.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie + genre + numéro d'équipe facultatif (ex: 'U11M', 'U11M1', 'U13F2', 'SeniorM'). Cette valeur sert à filtrer les engagements et les poules.
club_nameNoNom du club (ex: 'Stade Clermontois', 'ASVEL').
season_idNoID de la saison FFBB (optionnel).
organisme_idNoID FFBB du club (alternative plus rapide à club_name).
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, contourne le cache pour récupérer des données fraîches.
numero_equipeNoNuméro d'équipe (1, 2, ...) pour identifier l'équipe précise dans la catégorie (défaut: 1).
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, and non-destructive behavior. The description adds useful behavioral context: it aggregates all phases, returns per-phase statistics, and provides a cumulative bilan_total. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, followed by a concise bullet list of return fields. There is slight repetition of 'toutes phases', but the overall structure is clear and economical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having 10 parameters and no output schema, the description covers the tool's use case, identification logic, aggregation behavior, and return fields. Optional disambiguation parameters are left to the schema, which is reasonable given the 100% schema coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents the parameters. The description usefully groups the team identification parameters (organisme_id/club_name, categorie, numero_equipe), but it does not add much per-parameter meaning beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource and action: a detailed season record for a specific team, covering all phases. It also gives an example question and lists the returned fields. It does not explicitly name a sibling alternative, so it stops short of full differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly frames the tool as optimized for questions like 'Quel est le bilan de la saison des U11M1 ?', giving an agent a clear trigger for when to use it. It does not state when not to use it or mention alternatives such as ffbb_bilan.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_clubOutils agrégés clubA
Read-onlyIdempotent

Outils agrégés club : calendrier (matchs pluriels), équipes engagées ou classement.

Outil de référence pour toute demande au pluriel : matchs restants, calendrier complet. Résout NM3, PNM, etc. vers la bonne équipe.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre max de matchs retournés (1-100, pagination).
phaseNoNom ou numéro de phase (ex: 'Phase 2').
scopeNoScope : 'team' (équipe résolue), 'club' (global club) ou 'competition'.
actionNoAction : 'calendrier' (matchs pluriels/restants), 'equipes' ou 'classement'.calendrier
filtreNoFiltre catégorie/genre (alias pour 'categorie', ex: 'U11M', 'Senior', 'NM3').
offsetNoIndex de départ pour pagination calendrier (défaut 0).
date_finNoDate fin YYYY-MM-DD (action='calendrier').
group_byNoRegroupement : competition, team ou date.
poule_idNoID poule (action='classement' ou 'calendrier'). Optionnel si club et catégorie sont fournis.
categorieNoCatégorie, division ou filtre d'équipe (alias pour 'filtre', ex: 'NM3', 'U15M', 'Senior').
club_nameNoNom du club (ex: 'Stade Clermontois'). Requis si organisme_id absent.
season_idNoID de la saison FFBB (optionnel).
adversaireNoNom adversaire pour filtrer les confrontations directes (action='calendrier').
date_debutNoDate début YYYY-MM-DD (action='calendrier').
organisme_idNoID FFBB du club (ex: '9326'). Requis si club_name absent.
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, contourne le cache.
include_youthNoInclut les équipes jeunes si demande senior.
numero_equipeNoNuméro d'équipe (ex: 1, 2) pour action='calendrier' ou 'classement'.
status_filterNoFiltre statuts : scheduled, live, final.
competition_idNoID FFBB de la compétition pour désambiguïser.
strict_filtersNoFiltrage strict sans extrapolation (défaut True).
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.
include_reservesNoInclut les réserves si demande équipe 1.
include_friendliesNoInclut les amicaux (exclus par défaut).
exclude_competition_typesNoTypes de compétition exclus (ex: ['PLAT']).
include_competition_typesNoTypes de compétition inclus (ex: ['DIV']).

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false), so the description is not required to repeat those. It adds useful behavioral context by stating that the tool aggregates calendar, teams, and standings, and that it resolves division labels like NM3/PNM to the correct team.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it lists the core actions in the first sentence and then gives routing and disambiguation guidance in the second. There is slight redundancy with the title ('Outils agrégés club'), but no major wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 27-parameter tool with no output schema, the description is relatively thin. It gives good routing context and disambiguation, but it does not mention the identifier requirement (one of organisme_id, club_name, poule_id, engagement_id, or competition_id) or how to choose between the three actions beyond their names. The schema fills most gaps, but the description alone is not fully sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies: every parameter is already documented in the schema. The description adds only minimal extra parameter semantics beyond the schema, mainly the resolution hint for category/division names like NM3/PNM.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies a club-level aggregate tool with three concrete outputs: calendrier (matchs pluriels), équipes engagées, and classement. It also differentiates itself from singular-match siblings by positioning itself as 'Outil de référence pour toute demande au pluriel' and adds disambiguation behavior ('Résout NM3, PNM, etc. vers la bonne équipe').

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly routes plural/cumulative requests to this tool ('toute demande au pluriel : matchs restants, calendrier complet'), so an agent knows when to reach for it. It does not explicitly name sibling exclusions, but the singular/plural framing is a clear enough contextual signal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_explain_tiebreak_rulesRègles de départage et calcul de classement FFBBA
Read-onlyIdempotent

Fournit les règles officielles de départage en cas d'égalité (Article 28 du RSG FFBB).

Explique le calcul du point-average particulier (confrontations directes), du quotient particulier, et du mini-championnat à 3 équipes ou plus. Lecture seule, idempotent, sans effet de bord ; cache SWR court.

Utilise cet outil uniquement quand deux équipes ou plus sont à égalité de points dans une poule et que tu dois expliquer pourquoi l'une est classée devant l'autre. Avec poule_id, les règles sont appliquées à la poule concrète ; sans, tu obtiens les règles génériques. Ne pas utiliser pour rechercher un extrait réglementaire — utilise ffbb_search_regulations à la place ; pour récupérer le texte d'un article précis — utilise ffbb_get_regulation_article ; pour lister les règlements disponibles — utilise ffbb_list_regulations. Ne pas utiliser non plus pour obtenir le classement brut — utilise ffbb_club(action="classement") — ni pour le bilan chiffré — utilise ffbb_bilan. Utilise ffbb_explain_tiebreak_rules au lieu de ffbb_search_regulations quand la question porte sur le départage et non sur le texte réglementaire.

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonNoSaison sportive (défaut '2026-2027')2026-2027
poule_idNoID optionnel de la poule FFBB pour appliquer les règles de départage

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description reinforces this and adds the 'cache SWR court' detail, which is new behavioral context. It does not contradict the annotations. Since the annotations carry most of the safety profile, the description adds a small but useful extra detail about caching.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the main purpose. It is longer than a typical description but every sentence serves a purpose: explaining what it does, the calculation types, safety note, and usage guidance with alternatives. It could be slightly trimmed, but it remains efficient and organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (explaining tiebreak rules) and simple schema (2 optional params), the description covers purpose, usage, parameter semantics, and safety. It does not describe the output format, but with no output schema and the tool being an explanation tool, this is not a critical omission. The description is complete enough for an agent to decide when to use it and how to pass parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (season and poule_id) already have descriptions. The description adds meaningful semantics for poule_id: 'Avec poule_id, les règles sont appliquées à la poule concrète ; sans, tu obtiens les règles génériques.' This clarifies the effect of the optional parameter, going beyond the schema's basic description. This earns a score above the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool provides official tiebreak rules (Article 28 du RSG FFBB) and explains the calculations for point-average, quotient, and mini-championnat. It clearly distinguishes from sibling tools by naming alternatives for different tasks, so an agent can immediately understand what this tool is for and what it is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use ('uniquement quand deux équipes ou plus sont à égalité de points dans une poule') and when-not-to-use, naming specific alternatives (ffbb_search_regulations, ffbb_get_regulation_article, ffbb_list_regulations, ffbb_club(action='classement'), ffbb_bilan). It even clarifies that this tool is preferred over ffbb_search_regulations for tiebreak questions. This is comprehensive and unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_find_team_candidatesRecherche et désambiguïsation d'équipes candidatesA
Read-onlyIdempotent

Recherche et ordonne les équipes candidates d'un club/CTC pour désambiguïser avant tout calendrier/résultat.

Évite la confusion entre équipe fanion sans numéro (ex: U13F en régional) et équipe réserve (ex: U13F2 en départemental). Retourne la liste des candidats triés avec confiance, motif, détails de compétition et prochain match.

ParametersJSON Schema
NameRequiredDescriptionDefault
sexeNoGenre de l'équipe ('M', 'F' ou 'MIXTE').
categorieNoCatégorie, étiquette ou division demandée (ex: 'U13F1', 'U13F', 'U15M', 'NM3', 'Senior'). L'outil extrait tranche d'âge, genre et numéro recherchés pour isoler les candidats.
club_nameNoNom du club ou de la CTC (ex: 'Cournon', 'Stade Clermontois'). Requis si organisme_id absent.
season_idNoID de la saison FFBB (optionnel).
organisme_idNoID FFBB du club (ex: '9289'). Requis si club_name absent.
force_refreshNoSi True, force le rafraîchissement des données.
numero_equipeNoNuméro d'équipe facultatif (ex: 1, 2).
include_next_matchNoSi True (défaut), récupère le prochain match programmé pour chaque candidat.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds useful behavioral context by stating that it returns a sorted list of candidates with confidence, reason, competition details, and next match, which goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: a clear action sentence, a concrete example of the problem, and a concise statement of the output. Every sentence contributes to understanding or selecting the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 8 parameters, 100% schema coverage, and no output schema, the description provides enough context to understand when and why to use it, and what it returns. It could be more complete by noting edge cases or the exact output shape, but the annotations and schema carry much of the remaining burden.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces the disambiguation intent and mentions club/CTC, but it does not add significant meaning about individual parameters beyond what the schema already documents. It provides context, not new parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Recherche et ordonne les équipes candidates d'un club/CTC' with a clear purpose ('pour désambiguïser avant tout calendrier/résultat'). It also gives a concrete example of the ambiguity resolved (fanion sans numéro vs réserve), which distinguishes it from siblings like ffbb_next_match or ffbb_last_result.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly indicates when to use the tool: before handling calendars or results when disambiguating teams. The fanion/réserve example provides a concrete trigger scenario. It does not explicitly name alternatives or give 'when not to use' guidance, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_getRessource FFBB par identifiantA
Read-onlyIdempotent

Recupere une ressource FFBB par identifiant.

  • type="competition" equivaut a get_competition. Si club est fourni, localise directement la poule du club au sein de la compétition.

  • type="poule" charge la poule (classements + rencontres).

  • type="organisme" charge les details d'un club.

  • type="engagement" charge les details d'un engagement d'équipe (club, poule, calendrier filtré).

  • type="rencontre" charge une rencontre précise.

  • type="salle" charge les details d'une salle et son adresse normalisée.

⚠️ Attention: type="poule" peut être tronqué si la poule est grande. Pour un calendrier exhaustif, préférez ffbb_club(action="calendrier").

Avertissement: ne pas utiliser pour obtenir un score ou un prochain match. Utiliser ffbb_last_result et ffbb_next_match a la place.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesIdentifiant FFBB exact (string opaque, ex: '200000003057825'). Ne pas passer un nom de club: utiliser d'abord ffbb_search pour résoudre l'id.
clubNoNom ou ID du club à localiser dans les poules (si type='competition'). Permet de trouver directement l'ID et le nom de poule d'un club dans une compétition multi-poules.
typeYesType de ressource a charger.
force_refreshNoSi True et type='poule', contourne le cache pour recuperer la poule en temps reel (scores live).

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context: type='poule' can be truncated for large poules, force_refresh bypasses the cache for live scores, and the club parameter locates the club's poule within a competition. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a front-loaded summary, concise bullets, and short warning paragraphs. It is longer than minimal because there are eight resource types to cover, and most lines earn their place. A small redundancy exists between the 'Attention' and 'Avertissement' warnings, so it is not perfectly tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with eight enum types, four parameters, and no output schema, the description covers most behavior: return content is described for competition, poule, organisme, engagement, rencontre, and salle, and important caveats such as truncation and cache bypass are included. However, the enum values 'officiel' and 'entraineur' are not explained, and no response shape is described.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds operational meaning beyond the schema: id is an opaque FFBB identifier resolved via ffbb_search, club only applies to type='competition', and force_refresh is meaningful only for type='poule'. This extra context justifies a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Récupère une ressource FFBB par identifiant') and immediately enumerates the supported resource types in bullet form. It also distinguishes itself from ffbb_last_result and ffbb_next_match, so an agent can tell it apart from siblings without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit routing guidance: type='competition' is equivalent to get_competition, exhaustive calendars should use ffbb_club(action='calendrier'), and score/next-match lookups should use ffbb_last_result and ffbb_next_match. It clearly states when to use this tool and when to use an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_get_regulation_articleLecture exacte d'un article de règlement FFBBA
Read-onlyIdempotent

Récupère le texte intégral et exact d'un article spécifique de règlement sans troncature.

Retourne dict avec document_id, article_number, titre, contenu et saison ; lecture seule, idempotent, sans effet de bord, cache SWR. Utilise cet outil quand tu connais le numéro d'article et le document (obtenu via ffbb_list_regulations ou ffbb_search_regulations) et que tu veux le contenu verbatim. Ne pas utiliser pour rechercher par mot-clé — utilise ffbb_search_regulations à la place ; pour lister les documents disponibles — utilise ffbb_list_regulations ; pour expliquer un départage — utilise ffbb_explain_tiebreak_rules. Si document_id est omis, précise organizer et season pour lever l'ambiguïté.

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonNoSaison sportive (défaut '2026-2027')2026-2027
organizerNoOrganisateur du texte (ex: 'FFBB', 'Ligue AURA', 'Comité 63')
document_idNoIdentifiant du document source (ex: 'rsg_ffbb_2026_2027', 'rsp_u15_elite_2026_2027', 'reglement_aura_2026_2027', 'reglement_comite_63_2026_2027')
article_numberYesNuméro ou référence de l'article (ex: 'Article 28', 'Article 51', 'Article 4.1', 'Article 7')

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds useful behavior beyond annotations: no truncation, SWR cache behavior, and the exact dict fields returned. It does repeat some annotation signals, but the cache and return-format context provide extra value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: purpose, return behavior, then usage guidance. Every sentence contributes, and the alternative tools are listed clearly without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 parameters and no output schema, the description covers the necessary context: exact return fields, idempotence and caching, when to use it, and how to disambiguate when document_id is absent. Nothing important is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful parameter relationships: if document_id is omitted, organizer and season should be provided to avoid ambiguity, and the document can be obtained via ffbb_list_regulations or ffbb_search_regulations. This goes beyond the schema's individual parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise action: retrieving the full, exact text of a specific regulation article without truncation. It clearly differentiates from siblings by naming what this tool is not for — keyword search, listing documents, and tiebreak explanations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use the tool: when the article number and document are already known and verbatim content is needed. It also gives exclusions with exact sibling alternatives: use ffbb_search_regulations for keyword search, ffbb_list_regulations for listing, and ffbb_explain_tiebreak_rules for tiebreak explanations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_head_to_headFace-à-Face & Comparaison d'équipes (H2H)A
Read-onlyIdempotent

Compare deux équipes et analyse leurs confrontations directes (H2H) et dynamiques.

ParametersJSON Schema
NameRequiredDescriptionDefault
club_aNoNom du premier club (ex: 'Stade Clermontois').
club_bNoNom du second club / adversaire (ex: 'Vichy', 'Roanne').
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie d'équipe commune à comparer (ex: 'SEM1', 'U18M', 'Senior').
club_nameNoAlias pour club_a : nom du premier club (ex: 'Stade Clermontois').
season_idNoID de la saison FFBB (optionnel).
adversaireNoAlias pour club_b : nom du second club / adversaire (ex: 'Vichy').
organisme_idNoAlias pour organisme_id_a : ID FFBB du premier club.
adversaire_idNoAlias pour organisme_id_b : ID FFBB du second club / adversaire.
engagement_idNoID FFBB de l'engagement partagé ou équipe A (alias pour engagement_id_a).
force_refreshNoSi True, force le rafraîchissement des données
competition_idNoID FFBB de la compétition pour désambiguïser.
organisme_id_aNoID FFBB du premier club (ex: '9326').
organisme_id_bNoID FFBB du second club / adversaire.
engagement_id_aNoID FFBB de l'engagement équipe A (prioritaire).
engagement_id_bNoID FFBB de l'engagement équipe B (prioritaire).
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds no behavioral context such as data source, caching, or return semantics, but it does not contradict the annotations either.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. The word 'dynamiques' is slightly ambiguous and prevents a perfect score, but the structure is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a high-complexity tool with 17 parameters, multiple alias groups, no output schema, and no required fields. The description only states the purpose and leaves the agent to infer which parameter combination to supply and what the response will contain, so it is incomplete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 17 parameters have schema descriptions, so the schema carries the semantic load and the baseline is 3. The description adds no guidance on alias groups or preferred identification methods (names vs IDs vs engagement IDs), which is a missed opportunity but not a deficiency given 100% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses 'Compare' as a specific verb, identifies 'deux équipes' as the resource, and explicitly mentions H2H, which distinguishes this tool from the single-team sibling tools like ffbb_team_summary or ffbb_last_result. The word 'dynamiques' is slightly vague, but the core purpose is unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The imperative 'Compare deux équipes' and the mention of 'confrontations directes (H2H)' make the intended use case clear: any request for a two-team head-to-head comparison. It does not explicitly name alternatives or give when-not-to-use conditions, so it falls short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_last_resultDernier résultat d'équipeA
Read-onlyIdempotent

Dernier résultat d'une équipe précise.

SINGULIER UNIQUEMENT: retourne le dernier match joué d'une seule équipe. Recommendation LLM : Si la categorie est imprécise ou sans numéro (ex: 'U11M'), appeler d'abord ffbb_resolve_team pour obtenir le numero_equipe reel.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'SEM1', 'NM3').
club_nameNoNom du club (ex: 'Stade Clermontois')
season_idNoID de la saison FFBB (optionnel).
organisme_idNoIdentifiant FFBB du club (organisme_id, ex: '9326' ou 'ARA0063058').
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, force un rafraichissement des donnees de poule
numero_equipeNoNuméro d'équipe dans la catégorie. Résoudre avec ffbb_resolve_team si ambigu.
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive behavior. The description adds useful behavioral nuance beyond annotations: the tool only handles one team at a time and may need an exact resolved `numero_equipe` for ambiguous categories. No contradiction with the readOnlyHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded, with the core singular-only behavior stated first and the resolver recommendation as a targeted extra. The first two sentences are slightly redundant, but the whole thing remains tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Together with the rich schema and annotations, the description is sufficiently complete: it specifies the return scope, emphasizes singularity, and gives a concrete disambiguation workflow. There is no output schema, so a note on the exact result fields would be an enhancement, but it is not a blocker.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter already has a meaningful description, including the resolver note on `numero_equipe`. The tool description adds no new per-parameter meaning, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: 'retourne le dernier match joué d'une seule équipe' (returns the last played match of a single team), with a specific resource and scope. It emphasizes singular-only behavior, which distinguishes it from any batch or team-wide tools, though it does not explicitly name sibling alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a direct LLM recommendation: if the category is imprecise or lacks a number, call `ffbb_resolve_team` first to obtain the real `numero_equipe`. It also makes the singular-only constraint explicit. It does not mention exclusions or compare against sibling tools such as `ffbb_next_match`, but the context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_list_regulationsListe des règlements et juridictions FFBB disponiblesA
Read-onlyIdempotent

Liste l'ensemble des textes réglementaires fédéraux (RSG, RSP Élite, NM1-NM3, LF2-NF3), régionaux (Ligues IDF, Hauts-de-France, AURA...) et départementaux (Comités Paris, Nord, Rhône, Puy-de-Dôme...) indexés.

Retourne l'inventaire complet sous forme dict avec documents[] (document_id, titre, organizer, level, season) trié par juridiction. Lecture seule, idempotent, sans effet de bord ; cache SWR (TTL ≈24h).

Utilise cet outil pour découvrir les document_id disponibles avant d'appeler ffbb_get_regulation_article ou pour choisir un périmètre avant ffbb_search_regulations. Ne pas utiliser pour rechercher un extrait textuel — utilise ffbb_search_regulations à la place ; pour obtenir le texte d'un article précis — utilise ffbb_get_regulation_article ; pour expliquer un départage — utilise ffbb_explain_tiebreak_rules. Avec season, filtre l'inventaire à la saison ciblée (défaut 2026-2027).

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonNoSaison sportive (défaut '2026-2027')2026-2027

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark read-only, idempotent, and non-destructive, and the description adds the non-obvious SWR cache with TTL ≈24h. It also discloses the return shape as a dict with documents[] containing document_id, titre, organizer, level, season, sorted by jurisdiction, which is beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is organized into three focused blocks: scope, return/behavior, and usage routing. Every sentence adds useful information, examples like RSG and Ligues IDF clarify the catalog, and the scoping verb is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully compensates by specifying the exact returned structure and sort order. It also covers the one parameter, the default, and the operational characteristics (cache, side effects), making the tool callable without additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a generic 'Saison sportive' description. The tool description adds meaning by stating that season 'filtre l'inventaire à la saison ciblée' and reinforcing the default '2026-2027', which is a clear improvement over the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Liste l'ensemble des textes réglementaires' and enumerates the federal, regional, and departmental scope. It distinguishes itself from siblings by naming ffbb_get_regulation_article and ffbb_search_regulations as tools with a different purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use this tool: discover document_id before ffbb_get_regulation_article or choose a perimeter before ffbb_search_regulations. It also gives direct counter-guidance: not for textual search, article text, or tiebreak explanation, each with the correct sibling tool named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_livesScores en directC
Read-onlyIdempotent

Flux live FFBB, éventuellement complété par un calendrier ciblé et prudent.

ParametersJSON Schema
NameRequiredDescriptionDefault
categorieNoCatégorie de l'équipe ciblée, par exemple U18M ou NM2.
club_nameNoNom du club si son identifiant n'est pas connu.
organisme_idNoID du club pour cibler et compléter le flux live.
engagement_idNoID d'engagement précis de l'équipe ciblée.
numero_equipeNoNuméro de l'équipe ciblée dans la catégorie.
include_scheduledNoSi True, inclut aussi les matchs programmés à venir (statut SCHEDULED). Par défaut (False), ne retourne que les matchs réellement en cours de jeu.
include_calendar_fallbackNoPour une cible club/équipe, complète le flux FFBB avec les matchs dont l'horaire est dépassé, sans les présenter comme live confirmés.

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare the operation read-only, idempotent, non-destructive, and open-world, so the safety profile is covered. The description adds a weak behavioral hint that the live stream may be supplemented by a 'ciblé et prudent' calendar, indicating not all returned entries are confirmed live. But it lacks detail about data freshness, response shape, or why the fallback is cautious, and it partly duplicates the include_calendar_fallback parameter description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely short, but it is an under-specified noun phrase rather than a useful sentence. It spends its only clause on vague marketing-like wording ('ciblé et prudent') instead of concrete behavior. For a tool with 7 optional parameters, this is under-specification, not effective conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 7 optional parameters, an agent receives almost no help on what the response contains or how to build a valid request. The description omits return values, data source restrictions, and any example usage patterns. The annotations cover safety but not operational completeness, so the description is insufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 7 parameters are described in the input schema (100% coverage), so the schema carries the semantic load. The description itself provides no additional parameter-level meaning beyond the vague 'calendrier ciblé' phrase, which maps to include_calendar_fallback. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the tool as a live FFBB feed and hints at calendar augmentation, so an agent can infer it returns live basketball scores. However, it is a noun phrase with no explicit verb such as 'retrieves' or 'returns,' and it does not directly distinguish itself from sibling tools like ffbb_last_result or ffbb_next_match. This is clear but not fully specified.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description contains no guidance on when to prefer ffbb_lives over the many sibling tools. It neither states 'use for current in-progress games' nor mentions alternatives or exclusion conditions. A user must infer usage from the word 'live' and the title 'Scores en direct.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_next_matchProchain match d'équipeA
Read-onlyIdempotent

Prochain match à jouer pour une équipe précise.

⚠️ SINGULIER UNIQUEMENT. Si la demande est au pluriel ("matchs restants", "derniers matchs à jouer", "calendrier"), utiliser ffbb_club(action="calendrier") à la place.

⚠️ ATTENTION LLM : Cet outil retourne STRICTEMENT LE PROCHAIN MATCH UNIQUE. Ne l'utilise JAMAIS si l'utilisateur demande "les prochains matchs" au pluriel. Pour toute requête au pluriel, utilise OBLIGATOIREMENT ffbb_club(action="calendrier") et filtre les résultats toi-même.

Recommendation LLM : Si la categorie est imprécise ou sans numéro (ex: 'U11M'), appeler d'abord ffbb_resolve_team pour obtenir le numero_equipe reel.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'SEM1', 'NM3').
club_nameNoNom du club (ex: 'Stade Clermontois')
season_idNoID de la saison FFBB (optionnel).
organisme_idNoIdentifiant FFBB du club (organisme_id, ex: '9326' ou 'ARA0063058').
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, force un rafraichissement des donnees de poule
numero_equipeNoNuméro d'équipe dans la catégorie. Résoudre avec ffbb_resolve_team si ambigu.
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context beyond annotations, notably that the tool returns STRICTLY ONE next match and should never be used for plural requests. No annotation contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and the critical singular-only constraint. The warnings about plural requests are somewhat repeated, but each repetition reinforces an important failure mode Lewis: 'ATTENTION LLM' is redundant with the earlier warning yet still earns its place due to the high cost of misuse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 10 parameters, an anyOf selection constraint, and no output schema, the description provides critical routing and parameter-resolution guidance. It does not fully explain how to choose among organisme_id, club_name, engagement_id, poule_id, and competition_id, but the schema descriptions largely cover those fields, and the description covers the main ambiguity traps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds extra semantic guidance by explaining that an imprecise category such as 'U11M' should first be resolved via ffbb_resolve_team to get the real numero_equipe, which clarifies how to use the categorie and numero_equipe parameters together.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb plus resource: 'Prochain match à jouer pour une équipe précise.' This clearly distinguishes it from siblings like ffbb_last_result and ffbb_club(action="calendrier") by emphasizing the singular next match for one team.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use and when-not-to-use guidance: use it only for singular next-match requests, and use ffbb_club(action="calendrier") for plural requests. It also recommends ffbb_resolve_team when the category lacks a number, directly steering the agent to the correct alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_resolve_teamRésolution d'équipeA
Read-onlyIdempotent

Identifie une equipe unique (Pivot central).

DOIT etre utilise avant ffbb_next_match ou ffbb_last_result si l'agent ne connait pas le numero d'equipe exact ou si la categorie est ambiguë (ex: 'U11M'). Pour une équipe senior au niveau national ou régional, la catégorie FFBB interne est souvent SEM1 ou SEF1 ; le serveur résout désormais NM3, NM2, NF1, PNM, R2, etc. vers la bonne équipe et sa poule.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'SEM1') ou division (ex: 'NM3', 'R2', 'PNM'). Si le numéro manque, cet outil retourne la bonne équipe ou des candidats.
club_nameNoNom du club (ex: 'Stade Clermontois', 'ASVEL').
season_idNoID de la saison FFBB (optionnel).
organisme_idNoID FFBB du club (alternative plus rapide à club_name).
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, force le rafraîchissement des données.
numero_equipeNoNuméro d'équipe facultatif (ex: 1, 2).
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/openWorld/idempotent/non-destructive behavior, and the description does not contradict them. It adds meaningful context by explaining that the server resolves common division labels into internal FFBB categories and pools, and that the tool acts as a central prerequisite before dependent tools. It does not, however, describe the candidate-return behavior in the main text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, followed by direct usage guidance and a useful alias-resolution nuance. Each sentence earns its place, and there is no redundant restating of the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a resolver tool with no output schema, the description conveys the core behavior — it identifies a unique team, is a central prerequisite, and maps common division labels to the correct team and pool. The parameter schema further fills in ambiguity handling by mentioning 'la bonne équipe ou des candidats.' It could still explain the output shape more explicitly, but the current guidance is largely sufficient given the rich schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 10 parameters have schema descriptions (100% coverage), so the baseline is 3 and the schema already carries the parameter meaning. The main description reinforces the 'categorie' semantics with division examples, but adds little beyond what the 'categorie' parameter description already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Identifie une equipe unique (Pivot central).' It clearly positions this tool as the central team resolver and distinguishes it from the sibling match/result/search tools by naming which tools depend on it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool ('DOIT etre utilise avant ffbb_next_match ou ffbb_last_result') and the exact condition: when the agent does not know the exact team number or the category is ambiguous. It also provides a concrete senior-category alias example (NM3, NM2, NF1, PNM, R2), giving clear routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_saisonsListe des saisons FFBBA
Read-onlyIdempotent

Liste des saisons FFBB (référentiel temporel).

Retourne la liste complète des saisons FFBB sous forme list[dict] triée chronologiquement, chaque entrée contenant id (et alias season_id), libelle (et alias label), debut, fin, enCours (booléen, calculé via debut <= today <= fin), code, actif et within_date_range (booléen). Lecture seule, idempotent, sans effet de bord ni écriture. Cache SWR avec TTL long (≈24h) ; force_refresh=True contourne le cache pour données fraîches et active_only=True filtre côté serveur pour ne garder que la saison active.

Utilise cet outil pour récupérer les id / season_id de saison disponibles avant d'appeler ffbb_bilan, ffbb_club ou ffbb_team_summary avec un filtre de saison. Ne pas utiliser pour obtenir un classement, un calendrier ou un bilan — utilise ffbb_club(action="classement") ou ffbb_bilan à la place ; pour la version du serveur, utilise ffbb_version.

ParametersJSON Schema
NameRequiredDescriptionDefault
active_onlyNoTrue = saison active uniquement.
force_refreshNoSi True, contourne le cache.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description transparently discloses cache behavior with SWR and a ~24h TTL, explains that force_refresh bypasses the cache, and describes computed fields like enCours and within_date_range. It also confirms the read-only, idempotent, side-effect-free nature, which is consistent with the annotations. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but efficient, front-loading the core purpose and return shape before moving to behavior, parameters, and usage routing. Every section earns its place, and the explicit usage/alternative guidance avoids the need for further inference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by fully specifying the return type and the fields inside each dict, including aliases and computed booleans. It also covers cache behavior, parameter effects, and routing to sibling tools, making the tool complete for an agent to invoke correctly without additional lookups.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers both parameters with 100% description coverage, so the baseline is 3, but the tool description adds meaning beyond the schema by explaining that force_refresh provides fresh data and that active_only filters server-side. This gives the agent a clearer sense of the practical effect of each parameter, though the schema already provides the basic semantic.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns the complete list of FFBB seasons as a chronologically sorted list[dict], with a detailed field breakdown. It also distinguishes itself from sibling tools by explicitly saying it is not for rankings, calendars, or bilan, and names the alternatives. This makes the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: retrieve season ids before calling ffbb_bilan, ffbb_club, or ffbb_team_summary with a season filter. It also provides when-not-to-use guidance and names the correct alternatives for rankings, bilan, and server version, so an agent can route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_search_regulationsRecherche dans les règlements sportifs FFBBA
Read-onlyIdempotent

Recherche plein texte déterministe dans les règlements officiels FFBB, régionaux et départementaux.

Permet de retrouver les articles pertinents sur les qualifications, montées/descentes, brassages jeunes, règles techniques (durée, ballons, zone), forfaits et brûlage. Retourne dict avec results[] (id, document_id, article_number, article_title, relevance_score, content, topics[], source_url) triés par pertinence ; lecture seule, idempotent, cache SWR.

Utilise cet outil quand tu ne connais pas le numéro d'article et que tu cherches par mots-clés. Ne pas utiliser pour récupérer un article précis — utilise ffbb_get_regulation_article à la place ; pour lister les documents — utilise ffbb_list_regulations ; pour expliquer un départage — utilise ffbb_explain_tiebreak_rules au lieu de chercher le texte. Affûte avec level, organizer, category et limit pour réduire le bruit.

ParametersJSON Schema
NameRequiredDescriptionDefault
levelNoNiveau de compétition ciblé : 'federal' (FFBB national / RSG / Élite), 'regional' (Ligues, ex: AURA), 'departmental' (Comités, ex: Comité 63)
limitNoNombre maximal d'extraits d'articles à retourner (défaut 5, max 10)
queryNoTerme ou question de recherche dans les règlements (ex: 'brûlage équipe réserve', 'défense de zone U13', 'brassages départementaux', 'barrages accession')
topicNoMots-clés thématiques (ex: 'departages', 'brulage', 'forfaits', 'poule_haute')
seasonNoSaison sportive ciblée (par défaut '2026-2027')2026-2027
categoryNoCatégorie d'âge ou division (ex: 'U13', 'U15', 'U18', 'seniors', 'elite')
organizerNoNom ou sigle de l'organisateur (ex: 'FFBB', 'Ligue AURA', 'Comité 63')

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only, idemponent, non-destructive traits, but the description adds extra behavioral details not in annotations: deterministic search, SWR cache, sorted by relevance, and a precise return dict shape. This materially helps the agent predict side effects and output structure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence pulls weight: scope, examples of relevant topics, return format, side-effect disclosure, explicit routing to siblings, and parameter-narrowing advice. It is front-loaded with the core purpose, and no filler appears.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given seven parameters, no required args, no output schema, and many siblings, this description is remarkably complete. It tells what the tool returns, sorts by relevance, is read-only and idemponent, and exactly which sibling should be used in adjacent cases. Nothing critical is missing for correct selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema fully explains each parameter. The description contributes only a heuristic tip to narrow with level/organizer/category/limit and a few query examples, but no additional semantic information beyond the schema descriptions. This meets the baseline without exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

A clear, specific verb and resource: full-text search in official FFBB regulations, and scope is narrowed to federal/regional/departmental. The description names the most relevant siblings to avoid confusion and defines what the tool is not for (retrieving an article, listing docs, explaining tiebreaks), so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use this tool (when the article number is unknown and searching by keywords) and when not to use it, naming ffbb_get_regulation_article, ffbb_list_regulations, and ffbb_explain_tiebreak_rules as alternatives. It even advises narrowing with level, organizer, category, and limit, leaving little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_team_summaryRésumé complet d'équipeA
Read-onlyIdempotent

Résumé complet d'équipe : bilan, classement, dernier et prochain match en un seul appel.

Résout NM3, PNM, NF1, etc. vers la bonne équipe. En cas d'ambiguïté, suggère les candidats.

ParametersJSON Schema
NameRequiredDescriptionDefault
poule_idNoID FFBB de la poule pour désambiguïser.
categorieNoCatégorie/division + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'SEM1', 'NM3', 'PNM').
club_nameNoNom du club (ex: 'Stade Clermontois', 'ASVEL').
season_idNoID de la saison FFBB (optionnel).
organisme_idNoID FFBB du club (alternative plus rapide à club_name).
engagement_idNoID FFBB de l'engagement (prioritaire pour désambiguïser).
force_refreshNoSi True, force un rafraichissement des donnees
numero_equipeNoNuméro d'équipe dans la catégorie (ex: 1, 2).
competition_idNoID FFBB de la compétition pour désambiguïser.
competition_typeNoType de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Read-only, open-world, and idempotent safety are already covered by annotations, so the description only needs to add behavior beyond that. It adds the resolution behavior for abbreviations like NM3/PNM/NF1 and the fallback of suggesting candidates on ambiguity. This is useful operational context not present in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the primary result, and the second adds the important resolution/ambiguity behavior. Every sentence earns its place without repeating schema or annotation details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 10 parameters and no output schema, the description covers the main gaps by enumerating the returned sections and explaining disambiguation and ambiguity handling. The anyOf parameter grouping is left to the schema, which is acceptable because the schema already describes it fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% property description coverage, so the baseline is 3. The description hints that category codes like NM3/PNM are resolveable, but most parameter meaning is already provided by the schema. No significant parameter-semantics value is added beyond that baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states that the tool returns a full team bundle (bilan, classement, dernier et prochain match) in a single call, which identifies a specific combined resource. The one-call phrasing differentiates it from sibling tools that cover only one component. The resolution of division codes (NM3, PNM, NF1) further clarifies its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear that the tool is for obtaining a complete team summary in one call rather than assembling it from separate sibling calls. It does not explicitly name alternative tools or state when not to use it, but the context is strong enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ffbb_versionVersion et diagnostics serveurA
Read-onlyIdempotent

Informations de version et configuration runtime du serveur FFBB MCP.

Retourne dict compact et typé {package_version, mcp_sdk_version, python_version, transport, cache_ttls} ; lecture seule, idempotent, sans appel réseau externe ni effet de bord, <10ms.

Utilise cet outil pour diagnostiquer la version déployée, vérifier le transport (stdio vs streamable-http) ou inspecter les TTL avant de debugger un autre outil. Ne pas utiliser pour obtenir des données basket — utilise ffbb_search, ffbb_club ou ffbb_bilan à la place ; pour la santé live, préfère /health.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, and the description is fully consistent with them (no contradiction). The description adds valuable context beyond annotations: no external network call, no side effects, <10ms latency, and the compact typed return shape. Given the annotations carry the safety profile, the extra performance and network behavior context earns a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, front-loaded paragraphs: purpose and return shape first, then use cases, then exclusions. Every sentence earns its place, though the return fields are effectively mentioned twice (once in the dict description and once in the use-case sentence), a minor redundancy that keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only diagnostic tool with rich annotations, the description covers purpose, use cases, exclusions, return shape, and performance. It does not spell out the exact format of each dict value, but for such a low-complexity tool nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline of 4 applies — there is nothing to document. The description instead clarifies the output shape ({package_version, mcp_sdk_version, python_version, transport, cache_ttls}), which is genuinely useful since there is no output schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific purpose: diagnosing server version and runtime configuration. It names the exact resource (FFBB MCP server), lists the returned fields, and explicitly differentiates itself from basket-data tools (ffbb_search, ffbb_club, ffbb_bilan) and from the live-health endpoint (/health). An agent can instantly tell what this tool is and is not for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it (diagnose deployed version, verify transport stdio vs streamable-http, inspect TTLs before debugging another tool) and when not to (not for basket data, not for live health, with named alternatives). This is textbook usage guidance — nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.16.4
    • Changedffbb_get1 field changed
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "competition",
        -  "poule",
        -  "organisme",
        -  "rencontre",
        -  "officiel",
        -  "entraineur",
        -  "salle"
        -]New value: +[
        +  "competition",
        +  "poule",
        +  "organisme",
        +  "rencontre",
        +  "officiel",
        +  "entraineur",
        +  "salle",
        +  "engagement"
        +]
    • Changedffbb_search2 fields changed
      • changedInput schema / properties / sort / description
        Previous value: -"Tri Meilisearch (ex: ['libelle:asc'])."New value: +"Tri Meilisearch (ex: ['nom:asc'])."
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "all",
        -  "competitions",
        -  "organismes",
        -  "rencontres",
        -  "salles",
        -  "pratiques",
        -  "terrains",
        -  "tournois",
        -  "engagements",
        -  "formations",
        -  "officiels",
        -  "entraineurs",
        -  "communes"
        -]New value: +[
        +  "all",
        +  "competitions",
        +  "organismes",
        +  "rencontres",
        +  "salles",
        +  "pratiques",
        +  "terrains",
        +  "tournois",
        +  "engagements",
        +  "formations",
        +  "news",
        +  "galeries",
        +  "rss"
        +]
  2. 3 tool updatesv1.15.0
    • Changedffbb_club9 fields changed
      • addedInput schema / properties / exclude_competition_types
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Types de compétition exclus (ex: ['PLAT']).",
        +  "title": "Exclude Competition Types"
        +}
      • addedInput schema / properties / group_by
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "competition",
        +        "team",
        +        "date"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Regroupement : competition, team ou date.",
        +  "title": "Group By"
        +}
      • addedInput schema / properties / include_competition_types
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Types de compétition inclus (ex: ['DIV']).",
        +  "title": "Include Competition Types"
        +}
      • addedInput schema / properties / include_friendlies
        Added value: +{
        +  "default": false,
        +  "description": "Inclut les amicaux (exclus par défaut).",
        +  "title": "Include Friendlies",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / include_reserves
        Added value: +{
        +  "default": false,
        +  "description": "Inclut les réserves si demande équipe 1.",
        +  "title": "Include Reserves",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / include_youth
        Added value: +{
        +  "default": false,
        +  "description": "Inclut les équipes jeunes si demande senior.",
        +  "title": "Include Youth",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / scope
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "team",
        +        "club",
        +        "competition"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Scope : 'team' (équipe résolue), 'club' (global club) ou 'competition'.",
        +  "title": "Scope"
        +}
      • addedInput schema / properties / status_filter
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Filtre statuts : scheduled, live, final.",
        +  "title": "Status Filter"
        +}
      • addedInput schema / properties / strict_filters
        Added value: +{
        +  "default": true,
        +  "description": "Filtrage strict sans extrapolation (défaut True).",
        +  "title": "Strict Filters",
        +  "type": "boolean"
        +}
    • Addedffbb_find_team_candidates
    • Changedffbb_lives6 fields changed
      • addedInput schema / properties / categorie
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Catégorie de l'équipe ciblée, par exemple U18M ou NM2.",
        +  "title": "Categorie"
        +}
      • addedInput schema / properties / club_name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nom du club si son identifiant n'est pas connu.",
        +  "title": "Club Name"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID d'engagement précis de l'équipe ciblée.",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / include_calendar_fallback
        Added value: +{
        +  "default": true,
        +  "description": "Pour une cible club/équipe, complète le flux FFBB avec les matchs dont l'horaire est dépassé, sans les présenter comme live confirmés.",
        +  "title": "Include Calendar Fallback",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / numero_equipe
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Numéro de l'équipe ciblée dans la catégorie.",
        +  "title": "Numero Equipe"
        +}
      • addedInput schema / properties / organisme_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID du club pour cibler et compléter le flux live.",
        +  "title": "Organisme Id"
        +}
  3. 1 tool updatev1.14.5
    • Changedffbb_head_to_head1 field changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_a"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id_a"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "engagement_id_a"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "engagement_id"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "poule_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "club_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id_b"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  }
        +]
  4. 16 tool updatesv1.13.0
    • Changedffbb_bilan8 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • changedInput schema / properties / club_name / description
        Previous value: -"Nom du club (ex: 'Stade Clermontois', 'ASVEL')."New value: +"Nom du club (ex: 'Stade Clermontois', 'ASVEL'). Requis si organisme_id absent."
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • changedInput schema / properties / organisme_id / description
        Previous value: -"ID FFBB du club (ex: 9326)."New value: +"ID FFBB du club (ex: '9326' ou 'ARA0063058'). Requis si club_name absent."
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
    • Changedffbb_bilan_saison7 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • changedInput schema / properties / numero_equipe / default
        Previous value: -1New value: +null
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
    • Changedffbb_club14 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "poule_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / action / default
        Added value: +"calendrier"
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • changedInput schema / properties / filtre / description
        Previous value: -"Filtre catégorie/genre (ex: 'U11M', 'Senior', 'NM3')."New value: +"Filtre catégorie/genre (alias pour 'categorie', ex: 'U11M', 'Senior', 'NM3')."
      • changedInput schema / properties / limit / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 100,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / limit / description
        Previous value: -"Nombre max de matchs retournés (pagination)."New value: +"Nombre max de matchs retournés (1-100, pagination)."
      • addedInput schema / properties / offset
        Added value: +{
        +  "anyOf": [
        +    {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Index de départ pour pagination calendrier (défaut 0).",
        +  "title": "Offset"
        +}
      • changedInput schema / properties / organisme_id / description
        Previous value: -"ID FFBB du club (ex: 9326). Requis si club_name absent."New value: +"ID FFBB du club (ex: '9326'). Requis si club_name absent."
      • changedInput schema / properties / poule_id / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / poule_id / description
        Previous value: -"ID poule (action='classement'). Optionnel si club et catégorie sont fournis."New value: +"ID poule (action='classement' ou 'calendrier'). Optionnel si club et catégorie sont fournis."
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "action"
        -]
    • Addedffbb_explain_tiebreak_rules
    • Changedffbb_get3 fields changed
      • addedInput schema / properties / id / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / id / description
        Previous value: -"Identifiant numérique FFBB exact. Ne pas passer un nom de club: utiliser d'abord ffbb_search pour résoudre l'id."New value: +"Identifiant FFBB exact (string opaque, ex: '200000003057825'). Ne pas passer un nom de club: utiliser d'abord ffbb_search pour résoudre l'id."
      • removedInput schema / properties / id / type
        Removed value: -"integer"
    • Addedffbb_get_regulation_article
    • Changedffbb_head_to_head15 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id_a"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / adversaire
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Alias pour club_b : nom du second club / adversaire (ex: 'Vichy').",
        +  "title": "Adversaire"
        +}
      • addedInput schema / properties / adversaire_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Alias pour organisme_id_b : ID FFBB du second club / adversaire.",
        +  "title": "Adversaire Id"
        +}
      • changedInput schema / properties / club_b / description
        Previous value: -"Nom du second club (ex: 'Vichy', 'Roanne')."New value: +"Nom du second club / adversaire (ex: 'Vichy', 'Roanne')."
      • addedInput schema / properties / club_name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Alias pour club_a : nom du premier club (ex: 'Stade Clermontois').",
        +  "title": "Club Name"
        +}
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement partagé ou équipe A (alias pour engagement_id_a).",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / engagement_id_a
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement équipe A (prioritaire).",
        +  "title": "Engagement Id A"
        +}
      • addedInput schema / properties / engagement_id_b
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement équipe B (prioritaire).",
        +  "title": "Engagement Id B"
        +}
      • addedInput schema / properties / organisme_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Alias pour organisme_id_a : ID FFBB du premier club.",
        +  "title": "Organisme Id"
        +}
      • changedInput schema / properties / organisme_id_a / description
        Previous value: -"ID FFBB du premier club (ex: 9326)."New value: +"ID FFBB du premier club (ex: '9326')."
      • changedInput schema / properties / organisme_id_b / description
        Previous value: -"ID FFBB du second club."New value: +"ID FFBB du second club / adversaire."
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
    • Changedffbb_last_result15 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / categorie / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / categorie / default
        Added value: +null
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'U11F')"New value: +"Catégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'SEM1', 'NM3')."
      • removedInput schema / properties / categorie / type
        Removed value: -"string"
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / numero_equipe / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / numero_equipe / default
        Previous value: -1New value: +null
      • removedInput schema / properties / numero_equipe / type
        Removed value: -"integer"
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club (organisme_id, ex: 1234 ou 'ARA0063058')"New value: +"Identifiant FFBB du club (organisme_id, ex: '9326' ou 'ARA0063058')."
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "categorie"
        -]
    • Addedffbb_list_regulations
    • Changedffbb_lives1 field changed
      • addedInput schema / properties / include_scheduled
        Added value: +{
        +  "default": false,
        +  "description": "Si True, inclut aussi les matchs programmés à venir (statut SCHEDULED). Par défaut (False), ne retourne que les matchs réellement en cours de jeu.",
        +  "title": "Include Scheduled",
        +  "type": "boolean"
        +}
    • Changedffbb_next_match15 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / categorie / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / categorie / default
        Added value: +null
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'U11F')"New value: +"Catégorie de l'équipe précise (ex: 'U11M1', 'U11M', 'SEM1', 'NM3')."
      • removedInput schema / properties / categorie / type
        Removed value: -"string"
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / numero_equipe / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / numero_equipe / default
        Previous value: -1New value: +null
      • removedInput schema / properties / numero_equipe / type
        Removed value: -"integer"
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club (organisme_id, ex: 1234 ou 'ARA0063058')"New value: +"Identifiant FFBB du club (organisme_id, ex: '9326' ou 'ARA0063058')."
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "categorie"
        -]
    • Changedffbb_resolve_team7 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / force_refresh
        Added value: +{
        +  "default": false,
        +  "description": "Si True, force le rafraîchissement des données.",
        +  "title": "Force Refresh",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
    • Changedffbb_saisons1 field changed
      • addedInput schema / properties / force_refresh
        Added value: +{
        +  "default": false,
        +  "description": "Si True, contourne le cache.",
        +  "title": "Force Refresh",
        +  "type": "boolean"
        +}
    • Changedffbb_search4 fields changed
      • changedInput schema / properties / filter_by / description
        Previous value: -"Filtre Meilisearch natif (ex: 'codePostal = \"63000\"')."New value: +"Filtre Meilisearch natif (ex: 'codePostal = \"63000\"', 'codePostal IN [\"63000\", \"63100\"]', 'departement = \"Puy-de-Dôme\"')."
      • addedInput schema / properties / force_refresh
        Added value: +{
        +  "default": false,
        +  "description": "Si True, force le rafraîchissement des données.",
        +  "title": "Force Refresh",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Nombre maximum de résultats à retourner."New value: +"Nombre maximum de résultats à retourner (1-100)."
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Index de départ pour pagination (défaut: 0).",
        +  "title": "Offset",
        +  "type": "integer"
        +}
    • Addedffbb_search_regulations
    • Changedffbb_team_summary9 fields changed
      • changedInput schema / anyOf
        Previous value: -[
        -  {
        -    "required": [
        -      "club_name"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "organisme_id"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "engagement_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "competition_id"
        +    ]
        +  }
        +]
      • addedInput schema / properties / competition_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la compétition pour désambiguïser.",
        +  "title": "Competition Id"
        +}
      • addedInput schema / properties / competition_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Type de compétition ('PLAT', 'COUPE', etc.) pour désambiguïser.",
        +  "title": "Competition Type"
        +}
      • addedInput schema / properties / engagement_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de l'engagement (prioritaire pour désambiguïser).",
        +  "title": "Engagement Id"
        +}
      • addedInput schema / properties / numero_equipe / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / numero_equipe / default
        Previous value: -1New value: +null
      • removedInput schema / properties / numero_equipe / type
        Removed value: -"integer"
      • addedInput schema / properties / poule_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID FFBB de la poule pour désambiguïser.",
        +  "title": "Poule Id"
        +}
      • addedInput schema / properties / season_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "ID de la saison FFBB (optionnel).",
        +  "title": "Season Id"
        +}
  5. 4 tool updatesv1.10.0
    • Changedffbb_club4 fields changed
      • addedInput schema / properties / categorie
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Catégorie, division ou filtre d'équipe (alias pour 'filtre', ex: 'NM3', 'U15M', 'Senior').",
        +  "title": "Categorie"
        +}
      • changedInput schema / properties / filtre / description
        Previous value: -"Filtre catégorie/genre (ex: 'U11M', 'Senior')."New value: +"Filtre catégorie/genre (ex: 'U11M', 'Senior', 'NM3')."
      • changedInput schema / properties / numero_equipe / description
        Previous value: -"Numéro d'équipe (ex: 1, 2) pour action='calendrier'."New value: +"Numéro d'équipe (ex: 1, 2) pour action='calendrier' ou 'classement'."
      • changedInput schema / properties / poule_id / description
        Previous value: -"ID poule (action='classement')."New value: +"ID poule (action='classement'). Optionnel si club et catégorie sont fournis."
    • Changedffbb_get2 fields changed
      • addedInput schema / properties / club
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nom ou ID du club à localiser dans les poules (si type='competition'). Permet de trouver directement l'ID et le nom de poule d'un club dans une compétition multi-poules.",
        +  "title": "Club"
        +}
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "competition",
        -  "poule",
        -  "organisme",
        -  "rencontre",
        -  "officiel",
        -  "entraineur"
        -]New value: +[
        +  "competition",
        +  "poule",
        +  "organisme",
        +  "rencontre",
        +  "officiel",
        +  "entraineur",
        +  "salle"
        +]
    • Changedffbb_resolve_team1 field changed
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'U15M'). Si le numéro manque, cet outil retourne la bonne équipe ou des candidats."New value: +"Catégorie + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'SEM1') ou division (ex: 'NM3', 'R2', 'PNM'). Si le numéro manque, cet outil retourne la bonne équipe ou des candidats."
    • Changedffbb_team_summary1 field changed
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'U15M', 'Senior')."New value: +"Catégorie/division + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'SEM1', 'NM3', 'PNM')."
  6. 13 tool updatesv1.9.0
    • Changedffbb_bilan6 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie + genre + numéro d'équipe (ex: 'U11M1', 'U13F2', 'U15M', 'Senior')."New value: +"Catégorie/genre/numéro (ex: 'U11M1', 'Senior')."
      • changedInput schema / properties / force_refresh / description
        Previous value: -"Si True, contourne le cache pour récupérer des données fraîches."New value: +"Si True, contourne le cache."
      • changedInput schema / properties / numero_equipe / description
        Previous value: -"Numéro d'équipe facultatif (ex: 1, 2)."New value: +"Numéro d'équipe (ex: 1, 2)."
      • changedInput schema / properties / organisme_id / description
        Previous value: -"ID FFBB du club (alternative plus rapide à club_name)."New value: +"ID FFBB du club (ex: 9326)."
      • changedOutput schema / (root)
        Previous value: -{
        -  "$defs": {
        -    "BilanResponse": {
        -      "description": "Réponse structurée et typée pour le bilan d'une équipe.",
        -      "properties": {
        -        "_meta": {
        -          "additionalProperties": true,
        -          "description": "Métadonnées de fraîcheur et de cache.",
        -          "title": "Meta",
        -          "type": "object"
        -        },
        -        "bilan_total": {
        -          "$ref": "#/$defs/BilanTotal",
        -          "description": "Totaux cumulés toutes phases."
        -        },
        -        "categorie": {
        -          "description": "Catégorie d'âge/genre.",
        -          "title": "Categorie",
        -          "type": "string"
        -        },
        -        "club": {
        -          "description": "Nom officiel du club.",
        -          "title": "Club",
        -          "type": "string"
        -        },
        -        "competitions_incluses": {
        -          "description": "Liste des noms de compétitions incluses dans le bilan.",
        -          "items": {
        -            "type": "string"
        -          },
        -          "title": "Competitions Incluses",
        -          "type": "array"
        -        },
        -        "dynamique": {
        -          "anyOf": [
        -            {
        -              "$ref": "#/$defs/FormeRecente"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Dynamique et forme récente de l'équipe principale sur les 5 derniers matchs."
        -        },
        -        "equipes_bilan": {
        -          "additionalProperties": true,
        -          "description": "Bilans ventilés par numéro d'équipe.",
        -          "title": "Equipes Bilan",
        -          "type": "object"
        -        },
        -        "phase_courante": {
        -          "anyOf": [
        -            {
        -              "$ref": "#/$defs/PhaseBilan"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Détails de la dernière phase en cours."
        -        },
        -        "phases": {
        -          "description": "Liste de toutes les phases jouées.",
        -          "items": {
        -            "$ref": "#/$defs/PhaseBilan"
        -          },
        -          "title": "Phases",
        -          "type": "array"
        -        },
        -        "profil_avance": {
        -          "anyOf": [
        -            {
        -              "additionalProperties": true,
        -              "type": "object"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Profil tactique avancé : rangs attaque/défense, style de jeu, clutch index et bilans domicile/extérieur.",
        -          "title": "Profil Avance"
        -        },
        -        "saison_terminee": {
        -          "default": true,
        -          "description": "Indique si la saison est terminée pour cette équipe (toutes les phases jouées).",
        -          "title": "Saison Terminee",
        -          "type": "boolean"
        -        }
        -      },
        -      "required": [
        -        "club",
        -        "categorie",
        -        "bilan_total"
        -      ],
        -      "title": "BilanResponse",
        -      "type": "object"
        -    },
        -    "BilanTotal": {
        -      "description": "Statistiques cumulées d'une équipe (victoires, défaites, paniers).",
        -      "properties": {
        -        "difference": {
        -          "default": 0,
        -          "description": "Différence de paniers (marqués - encaissés).",
        -          "title": "Difference",
        -          "type": "integer"
        -        },
        -        "gagnes": {
        -          "default": 0,
        -          "description": "Nombre de matchs gagnés.",
        -          "title": "Gagnes",
        -          "type": "integer"
        -        },
        -        "match_joues": {
        -          "default": 0,
        -          "description": "Nombre de matchs joués.",
        -          "title": "Match Joues",
        -          "type": "integer"
        -        },
        -        "nuls": {
        -          "default": 0,
        -          "description": "Nombre de matchs nuls.",
        -          "title": "Nuls",
        -          "type": "integer"
        -        },
        -        "paniers_encaisses": {
        -          "default": 0,
        -          "description": "Total des paniers encaissés.",
        -          "title": "Paniers Encaisses",
        -          "type": "integer"
        -        },
        -        "paniers_marques": {
        -          "default": 0,
        -          "description": "Total des paniers marqués.",
        -          "title": "Paniers Marques",
        -          "type": "integer"
        -        },
        -        "perdus": {
        -          "default": 0,
        -          "description": "Nombre de matchs perdus.",
        -          "title": "Perdus",
        -          "type": "integer"
        -        }
        -      },
        -      "title": "BilanTotal",
        -      "type": "object"
        -    },
        -    "FormeRecente": {
        -      "description": "Indicateur complet de dynamique et de forme récente (5 derniers matchs).",
        -      "properties": {
        -        "defaites_5_derniers": {
        -          "default": 0,
        -          "description": "Nombre de défaites sur les 5 derniers matchs.",
        -          "title": "Defaites 5 Derniers",
        -          "type": "integer"
        -        },
        -        "diff_moyenne_5": {
        -          "default": 0,
        -          "description": "Différentiel moyen de points sur les 5 derniers matchs.",
        -          "title": "Diff Moyenne 5",
        -          "type": "number"
        -        },
        -        "forme": {
        -          "description": "Résultats des 5 derniers matchs par ordre chronologique (ex: ['V', 'V', 'D', 'V', 'V']).",
        -          "items": {
        -            "type": "string"
        -          },
        -          "title": "Forme",
        -          "type": "array"
        -        },
        -        "forme_str": {
        -          "default": "",
        -          "description": "Représentation texte compacte de la forme (ex: 'V-V-D-V-V').",
        -          "title": "Forme Str",
        -          "type": "string"
        -        },
        -        "matchs": {
        -          "description": "Détail des matchs récents analysés.",
        -          "items": {
        -            "$ref": "#/$defs/MatchForme"
        -          },
        -          "title": "Matchs",
        -          "type": "array"
        -        },
        -        "meilleure_victoire": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Plus large victoire récente (ex: '+24 vs ASPTT (84-60)').",
        -          "title": "Meilleure Victoire"
        -        },
        -        "nuls_5_derniers": {
        -          "default": 0,
        -          "description": "Nombre de nuls sur les 5 derniers matchs.",
        -          "title": "Nuls 5 Derniers",
        -          "type": "integer"
        -        },
        -        "pire_defaite": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Plus lourde défaite récente (ex: '-12 vs US Chauriat (62-74)').",
        -          "title": "Pire Defaite"
        -        },
        -        "pts_encaisses_moyenne_5": {
        -          "default": 0,
        -          "description": "Moyenne de points encaissés par match sur les 5 derniers matchs.",
        -          "title": "Pts Encaisses Moyenne 5",
        -          "type": "number"
        -        },
        -        "pts_marques_moyenne_5": {
        -          "default": 0,
        -          "description": "Moyenne de points marqués par match sur les 5 derniers matchs.",
        -          "title": "Pts Marques Moyenne 5",
        -          "type": "number"
        -        },
        -        "ratio_victoires_5_derniers": {
        -          "default": 0,
        -          "description": "Pourcentage de victoires sur les 5 derniers matchs (0-100%).",
        -          "title": "Ratio Victoires 5 Derniers",
        -          "type": "number"
        -        },
        -        "serie_actuelle": {
        -          "$ref": "#/$defs/SerieEnCours",
        -          "description": "Série globale en cours toutes compétitions."
        -        },
        -        "serie_domicile": {
        -          "$ref": "#/$defs/SerieEnCours",
        -          "description": "Série en cours pour les matchs à domicile."
        -        },
        -        "serie_exterieur": {
        -          "$ref": "#/$defs/SerieEnCours",
        -          "description": "Série en cours pour les matchs à l'extérieur."
        -        },
        -        "tendance": {
        -          "default": "Stable ➡️",
        -          "description": "Tendance de la forme ('En hausse ↗️', 'Stable ➡️', 'En baisse ↘️').",
        -          "title": "Tendance",
        -          "type": "string"
        -        },
        -        "victoires_5_derniers": {
        -          "default": 0,
        -          "description": "Nombre de victoires sur les 5 derniers matchs.",
        -          "title": "Victoires 5 Derniers",
        -          "type": "integer"
        -        }
        -      },
        -      "title": "FormeRecente",
        -      "type": "object"
        -    },
        -    "MatchForme": {
        -      "description": "Détail d'un match pris en compte dans la forme récente.",
        -      "properties": {
        -        "adversaire": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de l'adversaire.",
        -          "title": "Adversaire"
        -        },
        -        "date": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Date et heure du match.",
        -          "title": "Date"
        -        },
        -        "domicile": {
        -          "default": true,
        -          "description": "True si domicile, False si déplacement.",
        -          "title": "Domicile",
        -          "type": "boolean"
        -        },
        -        "ecart": {
        -          "default": 0,
        -          "description": "Différence de points (+13 ou -8).",
        -          "title": "Ecart",
        -          "type": "integer"
        -        },
        -        "journee": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom ou numéro de journée.",
        -          "title": "Journee"
        -        },
        -        "resultat": {
        -          "description": "'V' (Victoire), 'D' (Défaite) ou 'N' (Nul).",
        -          "title": "Resultat",
        -          "type": "string"
        -        },
        -        "salle": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de la salle.",
        -          "title": "Salle"
        -        },
        -        "score": {
        -          "description": "Score du match (ex: '78 - 65').",
        -          "title": "Score",
        -          "type": "string"
        -        },
        -        "score_contre": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Points encaissés.",
        -          "title": "Score Contre"
        -        },
        -        "score_pour": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Points marqués.",
        -          "title": "Score Pour"
        -        }
        -      },
        -      "required": [
        -        "resultat",
        -        "score"
        -      ],
        -      "title": "MatchForme",
        -      "type": "object"
        -    },
        -    "PhaseBilan": {
        -      "description": "Bilan détaillé pour une phase de compétition spécifique.",
        -      "properties": {
        -        "competition": {
        -          "description": "Nom de la compétition.",
        -          "title": "Competition",
        -          "type": "string"
        -        },
        -        "difference": {
        -          "default": 0,
        -          "description": "Différence de paniers.",
        -          "title": "Difference",
        -          "type": "integer"
        -        },
        -        "gagnes": {
        -          "default": 0,
        -          "description": "Matchs gagnés.",
        -          "title": "Gagnes",
        -          "type": "integer"
        -        },
        -        "match_joues": {
        -          "default": 0,
        -          "description": "Matchs joués dans cette phase.",
        -          "title": "Match Joues",
        -          "type": "integer"
        -        },
        -        "nuls": {
        -          "default": 0,
        -          "description": "Matchs nuls.",
        -          "title": "Nuls",
        -          "type": "integer"
        -        },
        -        "numero_equipe": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Numéro de l'équipe (ex: '1', '2').",
        -          "title": "Numero Equipe"
        -        },
        -        "paniers_encaisses": {
        -          "default": 0,
        -          "description": "Paniers encaissés.",
        -          "title": "Paniers Encaisses",
        -          "type": "integer"
        -        },
        -        "paniers_marques": {
        -          "default": 0,
        -          "description": "Paniers marqués.",
        -          "title": "Paniers Marques",
        -          "type": "integer"
        -        },
        -        "perdus": {
        -          "default": 0,
        -          "description": "Matchs perdus.",
        -          "title": "Perdus",
        -          "type": "integer"
        -        },
        -        "phase_terminee": {
        -          "default": false,
        -          "description": "Indique si la phase est terminée.",
        -          "title": "Phase Terminee",
        -          "type": "boolean"
        -        },
        -        "phase_type": {
        -          "default": "poule",
        -          "description": "Type de phase (poule ou élimination).",
        -          "title": "Phase Type",
        -          "type": "string"
        -        },
        -        "position": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Position actuelle au classement.",
        -          "title": "Position"
        -        },
        -        "poule_id": {
        -          "description": "ID de la poule.",
        -          "title": "Poule Id",
        -          "type": "string"
        -        },
        -        "total_equipes": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nombre total d'équipes dans la poule.",
        -          "title": "Total Equipes"
        -        }
        -      },
        -      "required": [
        -        "competition",
        -        "poule_id"
        -      ],
        -      "title": "PhaseBilan",
        -      "type": "object"
        -    },
        -    "SerieEnCours": {
        -      "description": "Série actuelle de victoires, défaites ou invincibilité.",
        -      "properties": {
        -        "count": {
        -          "default": 0,
        -          "description": "Nombre de matchs consécutifs dans la série.",
        -          "title": "Count",
        -          "type": "integer"
        -        },
        -        "label": {
        -          "default": "",
        -          "description": "Description lisible (ex: '3 victoires consécutives').",
        -          "title": "Label",
        -          "type": "string"
        -        },
        -        "type": {
        -          "default": "aucune",
        -          "description": "'victoires', 'defaites', 'nuls' ou 'aucune'.",
        -          "title": "Type",
        -          "type": "string"
        -        }
        -      },
        -      "title": "SerieEnCours",
        -      "type": "object"
        -    }
        -  },
        -  "properties": {
        -    "result": {
        -      "anyOf": [
        -        {
        -          "additionalProperties": true,
        -          "type": "object"
        -        },
        -        {
        -          "$ref": "#/$defs/BilanResponse"
        -        }
        -      ],
        -      "title": "Result"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "ffbb_bilanOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_bilan_saison2 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_bilan_saisonDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_club14 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "poule_id"
        +    ]
        +  }
        +]
      • changedInput schema / properties / action / description
        Previous value: -"Action club. Utiliser 'calendrier' pour les demandes au pluriel (matchs restants, calendrier, prochaines journées)."New value: +"Action : 'calendrier' (matchs pluriels/restants), 'equipes' ou 'classement'."
      • changedInput schema / properties / adversaire / description
        Previous value: -"Nom de l'équipe adversaire pour filtrer uniquement les confrontations directes (ex: 'Royat Orcines', 'Stade Clermontois'). Utilisé avec action='calendrier'. Insensible à la casse et aux accents."New value: +"Nom adversaire pour filtrer les confrontations directes (action='calendrier')."
      • changedInput schema / properties / club_name / description
        Previous value: -"Nom du club (recommande, ex: 'Stade Clermontois'). Si absent, `organisme_id` doit etre fourni."New value: +"Nom du club (ex: 'Stade Clermontois'). Requis si organisme_id absent."
      • changedInput schema / properties / date_debut / description
        Previous value: -"Date de début de filtrage au format YYYY-MM-DD (ex: '2026-05-01')."New value: +"Date début YYYY-MM-DD (action='calendrier')."
      • changedInput schema / properties / date_fin / description
        Previous value: -"Date de fin de filtrage au format YYYY-MM-DD (ex: '2026-05-31')."New value: +"Date fin YYYY-MM-DD (action='calendrier')."
      • changedInput schema / properties / filtre / description
        Previous value: -"Filtre facultatif de categorie/genre (ex: 'U11', 'U11M', 'U11F'). Pour une équipe précise, compléter avec numero_equipe."New value: +"Filtre catégorie/genre (ex: 'U11M', 'Senior')."
      • changedInput schema / properties / force_refresh / description
        Previous value: -"Si True, contourne le cache pour les donnees de calendrier ou de classement (utile les jours de match)."New value: +"Si True, contourne le cache."
      • changedInput schema / properties / limit / description
        Previous value: -"Nombre maximum de matchs de calendrier à retourner (pagination/limite)."New value: +"Nombre max de matchs retournés (pagination)."
      • changedInput schema / properties / numero_equipe / description
        Previous value: -"Numéro d'équipe facultatif (ex: 1, 2, 3). Utilisé avec action='calendrier' pour ne récupérer que les matchs de cette équipe précise."New value: +"Numéro d'équipe (ex: 1, 2) pour action='calendrier'."
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club (ex: 1234 ou 'ARA0063058'). Si absent, `club_name` est utilise pour effectuer une recherche."New value: +"ID FFBB du club (ex: 9326). Requis si club_name absent."
      • changedInput schema / properties / phase / description
        Previous value: -"Nom ou numéro de la phase (ex: 'Phase 3', '2'). Utilisé avec action='classement' pour auto-résoudre la poule."New value: +"Nom ou numéro de phase (ex: 'Phase 2')."
      • changedInput schema / properties / poule_id / description
        Previous value: -"Identifiant de la poule (obligatoire pour action='classement' si aucun filtre ne permet de determiner la poule)."New value: +"ID poule (action='classement')."
      • changedOutput schema / (root)
        Previous value: -{
        -  "$defs": {
        -    "CalendrierMatch": {
        -      "description": "Structure de données typée représentant un match de calendrier.",
        -      "properties": {
        -        "adresse": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Adresse complète de la salle.",
        -          "title": "Adresse"
        -        },
        -        "adresse_salle": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Adresse de la salle.",
        -          "title": "Adresse Salle"
        -        },
        -        "competition_nom": {
        -          "default": "",
        -          "description": "Nom de la compétition associée.",
        -          "title": "Competition Nom",
        -          "type": "string"
        -        },
        -        "competition_type": {
        -          "default": "poule",
        -          "description": "Type de phase (poule ou élimination).",
        -          "title": "Competition Type",
        -          "type": "string"
        -        },
        -        "date": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Date et heure du match en ISO format.",
        -          "title": "Date"
        -        },
        -        "equipe1": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de l'équipe 1 (domicile).",
        -          "title": "Equipe1"
        -        },
        -        "equipe2": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de l'équipe 2 (extérieur).",
        -          "title": "Equipe2"
        -        },
        -        "id": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "string"
        -            }
        -          ],
        -          "description": "ID unique de la rencontre.",
        -          "title": "Id"
        -        },
        -        "is_last_match": {
        -          "default": false,
        -          "description": "Indique s'il s'agit du dernier match joué.",
        -          "title": "Is Last Match",
        -          "type": "boolean"
        -        },
        -        "is_next_match": {
        -          "default": false,
        -          "description": "Indique s'il s'agit du prochain match à venir.",
        -          "title": "Is Next Match",
        -          "type": "boolean"
        -        },
        -        "joue": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "boolean"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Indique si le match a été joué (1 ou True) ou non (0 ou False).",
        -          "title": "Joue"
        -        },
        -        "lieu_complet": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Adresse formatée complète : 'Nom Salle - Adresse, CP Ville'.",
        -          "title": "Lieu Complet"
        -        },
        -        "nom_salle": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de la salle (libelle).",
        -          "title": "Nom Salle"
        -        },
        -        "num_journee": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "string"
        -            }
        -          ],
        -          "default": "",
        -          "description": "Numéro de la journée de championnat.",
        -          "title": "Num Journee"
        -        },
        -        "played": {
        -          "default": false,
        -          "description": "Indique si le match est déjà joué.",
        -          "title": "Played",
        -          "type": "boolean"
        -        },
        -        "salle": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "additionalProperties": true,
        -              "type": "object"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Nom de la salle de sport ou dictionnaire d'informations.",
        -          "title": "Salle"
        -        },
        -        "salle_details": {
        -          "anyOf": [
        -            {
        -              "additionalProperties": true,
        -              "type": "object"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Détails enrichis de la salle de sport.",
        -          "title": "Salle Details"
        -        },
        -        "score_equipe1": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Score de l'équipe 1.",
        -          "title": "Score Equipe1"
        -        },
        -        "score_equipe2": {
        -          "anyOf": [
        -            {
        -              "type": "integer"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Score de l'équipe 2.",
        -          "title": "Score Equipe2"
        -        },
        -        "ville": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ],
        -          "default": null,
        -          "description": "Ville où se situe la salle.",
        -          "title": "Ville"
        -        }
        -      },
        -      "required": [
        -        "id"
        -      ],
        -      "title": "CalendrierMatch",
        -      "type": "object"
        -    }
        -  },
        -  "properties": {
        -    "result": {
        -      "anyOf": [
        -        {
        -          "items": {
        -            "additionalProperties": true,
        -            "type": "object"
        -          },
        -          "type": "array"
        -        },
        -        {
        -          "items": {
        -            "$ref": "#/$defs/CalendrierMatch"
        -          },
        -          "type": "array"
        -        }
        -      ],
        -      "title": "Result"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "ffbb_clubOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_get1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_getDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_head_to_head1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_head_to_headDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_last_result2 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_last_resultDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_lives1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "title": "Result",
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "ffbb_get_livesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_next_match2 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_next_matchDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_resolve_team2 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_resolve_teamDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_saisons1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "title": "Result",
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "ffbb_get_saisonsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_search1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "items": {
        -        "additionalProperties": true,
        -        "type": "object"
        -      },
        -      "title": "Result",
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "ffbb_searchOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_team_summary2 fields changed
      • addedInput schema / anyOf
        Added value: +[
        +  {
        +    "required": [
        +      "club_name"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "organisme_id"
        +    ]
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_team_summaryDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changedffbb_version1 field changed
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "ffbb_versionDictOutput",
        -  "type": "object"
        -}New value: +null
  7. 5 tool updatesv1.8.0
    • Changedffbb_bilan6 fields changed
      • addedInput schema / properties / numero_equipe
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Numéro d'équipe facultatif (ex: 1, 2).",
        +  "title": "Numero Equipe"
        +}
      • addedOutput schema / $defs / BilanResponse / properties / dynamique
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/FormeRecente"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Dynamique et forme récente de l'équipe principale sur les 5 derniers matchs."
        +}
      • addedOutput schema / $defs / BilanResponse / properties / profil_avance
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Profil tactique avancé : rangs attaque/défense, style de jeu, clutch index et bilans domicile/extérieur.",
        +  "title": "Profil Avance"
        +}
      • addedOutput schema / $defs / FormeRecente
        Added value: +{
        +  "description": "Indicateur complet de dynamique et de forme récente (5 derniers matchs).",
        +  "properties": {
        +    "defaites_5_derniers": {
        +      "default": 0,
        +      "description": "Nombre de défaites sur les 5 derniers matchs.",
        +      "title": "Defaites 5 Derniers",
        +      "type": "integer"
        +    },
        +    "diff_moyenne_5": {
        +      "default": 0,
        +      "description": "Différentiel moyen de points sur les 5 derniers matchs.",
        +      "title": "Diff Moyenne 5",
        +      "type": "number"
        +    },
        +    "forme": {
        +      "description": "Résultats des 5 derniers matchs par ordre chronologique (ex: ['V', 'V', 'D', 'V', 'V']).",
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Forme",
        +      "type": "array"
        +    },
        +    "forme_str": {
        +      "default": "",
        +      "description": "Représentation texte compacte de la forme (ex: 'V-V-D-V-V').",
        +      "title": "Forme Str",
        +      "type": "string"
        +    },
        +    "matchs": {
        +      "description": "Détail des matchs récents analysés.",
        +      "items": {
        +        "$ref": "#/$defs/MatchForme"
        +      },
        +      "title": "Matchs",
        +      "type": "array"
        +    },
        +    "meilleure_victoire": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Plus large victoire récente (ex: '+24 vs ASPTT (84-60)').",
        +      "title": "Meilleure Victoire"
        +    },
        +    "nuls_5_derniers": {
        +      "default": 0,
        +      "description": "Nombre de nuls sur les 5 derniers matchs.",
        +      "title": "Nuls 5 Derniers",
        +      "type": "integer"
        +    },
        +    "pire_defaite": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Plus lourde défaite récente (ex: '-12 vs US Chauriat (62-74)').",
        +      "title": "Pire Defaite"
        +    },
        +    "pts_encaisses_moyenne_5": {
        +      "default": 0,
        +      "description": "Moyenne de points encaissés par match sur les 5 derniers matchs.",
        +      "title": "Pts Encaisses Moyenne 5",
        +      "type": "number"
        +    },
        +    "pts_marques_moyenne_5": {
        +      "default": 0,
        +      "description": "Moyenne de points marqués par match sur les 5 derniers matchs.",
        +      "title": "Pts Marques Moyenne 5",
        +      "type": "number"
        +    },
        +    "ratio_victoires_5_derniers": {
        +      "default": 0,
        +      "description": "Pourcentage de victoires sur les 5 derniers matchs (0-100%).",
        +      "title": "Ratio Victoires 5 Derniers",
        +      "type": "number"
        +    },
        +    "serie_actuelle": {
        +      "$ref": "#/$defs/SerieEnCours",
        +      "description": "Série globale en cours toutes compétitions."
        +    },
        +    "serie_domicile": {
        +      "$ref": "#/$defs/SerieEnCours",
        +      "description": "Série en cours pour les matchs à domicile."
        +    },
        +    "serie_exterieur": {
        +      "$ref": "#/$defs/SerieEnCours",
        +      "description": "Série en cours pour les matchs à l'extérieur."
        +    },
        +    "tendance": {
        +      "default": "Stable ➡️",
        +      "description": "Tendance de la forme ('En hausse ↗️', 'Stable ➡️', 'En baisse ↘️').",
        +      "title": "Tendance",
        +      "type": "string"
        +    },
        +    "victoires_5_derniers": {
        +      "default": 0,
        +      "description": "Nombre de victoires sur les 5 derniers matchs.",
        +      "title": "Victoires 5 Derniers",
        +      "type": "integer"
        +    }
        +  },
        +  "title": "FormeRecente",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / MatchForme
        Added value: +{
        +  "description": "Détail d'un match pris en compte dans la forme récente.",
        +  "properties": {
        +    "adversaire": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Nom de l'adversaire.",
        +      "title": "Adversaire"
        +    },
        +    "date": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Date et heure du match.",
        +      "title": "Date"
        +    },
        +    "domicile": {
        +      "default": true,
        +      "description": "True si domicile, False si déplacement.",
        +      "title": "Domicile",
        +      "type": "boolean"
        +    },
        +    "ecart": {
        +      "default": 0,
        +      "description": "Différence de points (+13 ou -8).",
        +      "title": "Ecart",
        +      "type": "integer"
        +    },
        +    "journee": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Nom ou numéro de journée.",
        +      "title": "Journee"
        +    },
        +    "resultat": {
        +      "description": "'V' (Victoire), 'D' (Défaite) ou 'N' (Nul).",
        +      "title": "Resultat",
        +      "type": "string"
        +    },
        +    "salle": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Nom de la salle.",
        +      "title": "Salle"
        +    },
        +    "score": {
        +      "description": "Score du match (ex: '78 - 65').",
        +      "title": "Score",
        +      "type": "string"
        +    },
        +    "score_contre": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Points encaissés.",
        +      "title": "Score Contre"
        +    },
        +    "score_pour": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "description": "Points marqués.",
        +      "title": "Score Pour"
        +    }
        +  },
        +  "required": [
        +    "resultat",
        +    "score"
        +  ],
        +  "title": "MatchForme",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / SerieEnCours
        Added value: +{
        +  "description": "Série actuelle de victoires, défaites ou invincibilité.",
        +  "properties": {
        +    "count": {
        +      "default": 0,
        +      "description": "Nombre de matchs consécutifs dans la série.",
        +      "title": "Count",
        +      "type": "integer"
        +    },
        +    "label": {
        +      "default": "",
        +      "description": "Description lisible (ex: '3 victoires consécutives').",
        +      "title": "Label",
        +      "type": "string"
        +    },
        +    "type": {
        +      "default": "aucune",
        +      "description": "'victoires', 'defaites', 'nuls' ou 'aucune'.",
        +      "title": "Type",
        +      "type": "string"
        +    }
        +  },
        +  "title": "SerieEnCours",
        +  "type": "object"
        +}
    • Changedffbb_bilan_saison13 fields changed
      • addedInput schema / properties / categorie / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / categorie / default
        Added value: +null
      • changedInput schema / properties / categorie / description
        Previous value: -"Catégorie + genre (ex: 'U11M', 'U13F', 'SeniorM'). Cette valeur sert à filtrer les engagements et les poules."New value: +"Catégorie + genre + numéro d'équipe facultatif (ex: 'U11M', 'U11M1', 'U13F2', 'SeniorM'). Cette valeur sert à filtrer les engagements et les poules."
      • removedInput schema / properties / categorie / type
        Removed value: -"string"
      • addedInput schema / properties / club_name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nom du club (ex: 'Stade Clermontois', 'ASVEL').",
        +  "title": "Club Name"
        +}
      • addedInput schema / properties / numero_equipe / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / numero_equipe / default
        Added value: +1
      • changedInput schema / properties / numero_equipe / description
        Previous value: -"Numéro d'équipe (1, 2, ...) pour identifier l'équipe précise dans la catégorie."New value: +"Numéro d'équipe (1, 2, ...) pour identifier l'équipe précise dans la catégorie (défaut: 1)."
      • removedInput schema / properties / numero_equipe / type
        Removed value: -"integer"
      • changedInput schema / properties / organisme_id / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / organisme_id / default
        Added value: +null
      • changedInput schema / properties / organisme_id / description
        Previous value: -"ID FFBB du club (organisme) concerné."New value: +"ID FFBB du club (alternative plus rapide à club_name)."
      • removedInput schema / required
        Removed value: -[
        -  "organisme_id",
        -  "categorie",
        -  "numero_equipe"
        -]
    • Addedffbb_head_to_head
    • Changedffbb_resolve_team1 field changed
      • addedInput schema / properties / numero_equipe
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Numéro d'équipe facultatif (ex: 1, 2).",
        +  "title": "Numero Equipe"
        +}
    • Changedffbb_team_summary2 fields changed
      • addedInput schema / properties / force_refresh
        Added value: +{
        +  "default": false,
        +  "description": "Si True, force un rafraichissement des donnees",
        +  "title": "Force Refresh",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / numero_equipe
        Added value: +{
        +  "default": 1,
        +  "description": "Numéro d'équipe dans la catégorie (ex: 1, 2).",
        +  "title": "Numero Equipe",
        +  "type": "integer"
        +}
  8. 4 tool updatesv1.5.1
    • Changedffbb_bilan3 fields changed
      • addedOutput schema / $defs / BilanResponse / properties / competitions_incluses
        Added value: +{
        +  "description": "Liste des noms de compétitions incluses dans le bilan.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Competitions Incluses",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / BilanResponse / properties / saison_terminee
        Added value: +{
        +  "default": true,
        +  "description": "Indique si la saison est terminée pour cette équipe (toutes les phases jouées).",
        +  "title": "Saison Terminee",
        +  "type": "boolean"
        +}
      • addedOutput schema / $defs / PhaseBilan / properties / total_equipes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nombre total d'équipes dans la poule.",
        +  "title": "Total Equipes"
        +}
    • Changedffbb_club6 fields changed
      • addedInput schema / properties / adversaire
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nom de l'équipe adversaire pour filtrer uniquement les confrontations directes (ex: 'Royat Orcines', 'Stade Clermontois'). Utilisé avec action='calendrier'. Insensible à la casse et aux accents.",
        +  "title": "Adversaire"
        +}
      • changedInput schema / properties / organisme_id / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club. Si absent, `club_name` est utilise pour effectuer une recherche."New value: +"Identifiant FFBB du club (ex: 1234 ou 'ARA0063058'). Si absent, `club_name` est utilise pour effectuer une recherche."
      • addedOutput schema / $defs / CalendrierMatch / properties / competition_type
        Added value: +{
        +  "default": "poule",
        +  "description": "Type de phase (poule ou élimination).",
        +  "title": "Competition Type",
        +  "type": "string"
        +}
      • addedOutput schema / $defs / CalendrierMatch / properties / lieu_complet
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Adresse formatée complète : 'Nom Salle - Adresse, CP Ville'.",
        +  "title": "Lieu Complet"
        +}
      • addedOutput schema / $defs / CalendrierMatch / properties / nom_salle
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nom de la salle (libelle).",
        +  "title": "Nom Salle"
        +}
    • Changedffbb_last_result2 fields changed
      • changedInput schema / properties / organisme_id / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club (organisme_id)"New value: +"Identifiant FFBB du club (organisme_id, ex: 1234 ou 'ARA0063058')"
    • Changedffbb_next_match2 fields changed
      • changedInput schema / properties / organisme_id / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / organisme_id / description
        Previous value: -"Identifiant FFBB du club (organisme_id)"New value: +"Identifiant FFBB du club (organisme_id, ex: 1234 ou 'ARA0063058')"
  9. 2 tool updatesv1.4.0
    • Changedffbb_bilan5 fields changed
      • addedOutput schema / $defs
        Added value: +{
        +  "BilanResponse": {
        +    "description": "Réponse structurée et typée pour le bilan d'une équipe.",
        +    "properties": {
        +      "_meta": {
        +        "additionalProperties": true,
        +        "description": "Métadonnées de fraîcheur et de cache.",
        +        "title": "Meta",
        +        "type": "object"
        +      },
        +      "bilan_total": {
        +        "$ref": "#/$defs/BilanTotal",
        +        "description": "Totaux cumulés toutes phases."
        +      },
        +      "categorie": {
        +        "description": "Catégorie d'âge/genre.",
        +        "title": "Categorie",
        +        "type": "string"
        +      },
        +      "club": {
        +        "description": "Nom officiel du club.",
        +        "title": "Club",
        +        "type": "string"
        +      },
        +      "equipes_bilan": {
        +        "additionalProperties": true,
        +        "description": "Bilans ventilés par numéro d'équipe.",
        +        "title": "Equipes Bilan",
        +        "type": "object"
        +      },
        +      "phase_courante": {
        +        "anyOf": [
        +          {
        +            "$ref": "#/$defs/PhaseBilan"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Détails de la dernière phase en cours."
        +      },
        +      "phases": {
        +        "description": "Liste de toutes les phases jouées.",
        +        "items": {
        +          "$ref": "#/$defs/PhaseBilan"
        +        },
        +        "title": "Phases",
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "club",
        +      "categorie",
        +      "bilan_total"
        +    ],
        +    "title": "BilanResponse",
        +    "type": "object"
        +  },
        +  "BilanTotal": {
        +    "description": "Statistiques cumulées d'une équipe (victoires, défaites, paniers).",
        +    "properties": {
        +      "difference": {
        +        "default": 0,
        +        "description": "Différence de paniers (marqués - encaissés).",
        +        "title": "Difference",
        +        "type": "integer"
        +      },
        +      "gagnes": {
        +        "default": 0,
        +        "description": "Nombre de matchs gagnés.",
        +        "title": "Gagnes",
        +        "type": "integer"
        +      },
        +      "match_joues": {
        +        "default": 0,
        +        "description": "Nombre de matchs joués.",
        +        "title": "Match Joues",
        +        "type": "integer"
        +      },
        +      "nuls": {
        +        "default": 0,
        +        "description": "Nombre de matchs nuls.",
        +        "title": "Nuls",
        +        "type": "integer"
        +      },
        +      "paniers_encaisses": {
        +        "default": 0,
        +        "description": "Total des paniers encaissés.",
        +        "title": "Paniers Encaisses",
        +        "type": "integer"
        +      },
        +      "paniers_marques": {
        +        "default": 0,
        +        "description": "Total des paniers marqués.",
        +        "title": "Paniers Marques",
        +        "type": "integer"
        +      },
        +      "perdus": {
        +        "default": 0,
        +        "description": "Nombre de matchs perdus.",
        +        "title": "Perdus",
        +        "type": "integer"
        +      }
        +    },
        +    "title": "BilanTotal",
        +    "type": "object"
        +  },
        +  "PhaseBilan": {
        +    "description": "Bilan détaillé pour une phase de compétition spécifique.",
        +    "properties": {
        +      "competition": {
        +        "description": "Nom de la compétition.",
        +        "title": "Competition",
        +        "type": "string"
        +      },
        +      "difference": {
        +        "default": 0,
        +        "description": "Différence de paniers.",
        +        "title": "Difference",
        +        "type": "integer"
        +      },
        +      "gagnes": {
        +        "default": 0,
        +        "description": "Matchs gagnés.",
        +        "title": "Gagnes",
        +        "type": "integer"
        +      },
        +      "match_joues": {
        +        "default": 0,
        +        "description": "Matchs joués dans cette phase.",
        +        "title": "Match Joues",
        +        "type": "integer"
        +      },
        +      "nuls": {
        +        "default": 0,
        +        "description": "Matchs nuls.",
        +        "title": "Nuls",
        +        "type": "integer"
        +      },
        +      "numero_equipe": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Numéro de l'équipe (ex: '1', '2').",
        +        "title": "Numero Equipe"
        +      },
        +      "paniers_encaisses": {
        +        "default": 0,
        +        "description": "Paniers encaissés.",
        +        "title": "Paniers Encaisses",
        +        "type": "integer"
        +      },
        +      "paniers_marques": {
        +        "default": 0,
        +        "description": "Paniers marqués.",
        +        "title": "Paniers Marques",
        +        "type": "integer"
        +      },
        +      "perdus": {
        +        "default": 0,
        +        "description": "Matchs perdus.",
        +        "title": "Perdus",
        +        "type": "integer"
        +      },
        +      "phase_terminee": {
        +        "default": false,
        +        "description": "Indique si la phase est terminée.",
        +        "title": "Phase Terminee",
        +        "type": "boolean"
        +      },
        +      "phase_type": {
        +        "default": "poule",
        +        "description": "Type de phase (poule ou élimination).",
        +        "title": "Phase Type",
        +        "type": "string"
        +      },
        +      "position": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Position actuelle au classement.",
        +        "title": "Position"
        +      },
        +      "poule_id": {
        +        "description": "ID de la poule.",
        +        "title": "Poule Id",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "competition",
        +      "poule_id"
        +    ],
        +    "title": "PhaseBilan",
        +    "type": "object"
        +  }
        +}
      • removedOutput schema / additionalProperties
        Removed value: -true
      • addedOutput schema / properties
        Added value: +{
        +  "result": {
        +    "anyOf": [
        +      {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      {
        +        "$ref": "#/$defs/BilanResponse"
        +      }
        +    ],
        +    "title": "Result"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "result"
        +]
      • changedOutput schema / title
        Previous value: -"ffbb_bilanDictOutput"New value: +"ffbb_bilanOutput"
    • Changedffbb_club7 fields changed
      • addedInput schema / properties / date_debut
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Date de début de filtrage au format YYYY-MM-DD (ex: '2026-05-01').",
        +  "title": "Date Debut"
        +}
      • addedInput schema / properties / date_fin
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Date de fin de filtrage au format YYYY-MM-DD (ex: '2026-05-31').",
        +  "title": "Date Fin"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Nombre maximum de matchs de calendrier à retourner (pagination/limite).",
        +  "title": "Limit"
        +}
      • addedOutput schema / $defs
        Added value: +{
        +  "CalendrierMatch": {
        +    "description": "Structure de données typée représentant un match de calendrier.",
        +    "properties": {
        +      "adresse": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Adresse complète de la salle.",
        +        "title": "Adresse"
        +      },
        +      "adresse_salle": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Adresse de la salle.",
        +        "title": "Adresse Salle"
        +      },
        +      "competition_nom": {
        +        "default": "",
        +        "description": "Nom de la compétition associée.",
        +        "title": "Competition Nom",
        +        "type": "string"
        +      },
        +      "date": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Date et heure du match en ISO format.",
        +        "title": "Date"
        +      },
        +      "equipe1": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Nom de l'équipe 1 (domicile).",
        +        "title": "Equipe1"
        +      },
        +      "equipe2": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Nom de l'équipe 2 (extérieur).",
        +        "title": "Equipe2"
        +      },
        +      "id": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "string"
        +          }
        +        ],
        +        "description": "ID unique de la rencontre.",
        +        "title": "Id"
        +      },
        +      "is_last_match": {
        +        "default": false,
        +        "description": "Indique s'il s'agit du dernier match joué.",
        +        "title": "Is Last Match",
        +        "type": "boolean"
        +      },
        +      "is_next_match": {
        +        "default": false,
        +        "description": "Indique s'il s'agit du prochain match à venir.",
        +        "title": "Is Next Match",
        +        "type": "boolean"
        +      },
        +      "joue": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "boolean"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Indique si le match a été joué (1 ou True) ou non (0 ou False).",
        +        "title": "Joue"
        +      },
        +      "num_journee": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "string"
        +          }
        +        ],
        +        "default": "",
        +        "description": "Numéro de la journée de championnat.",
        +        "title": "Num Journee"
        +      },
        +      "played": {
        +        "default": false,
        +        "description": "Indique si le match est déjà joué.",
        +        "title": "Played",
        +        "type": "boolean"
        +      },
        +      "salle": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Nom de la salle de sport ou dictionnaire d'informations.",
        +        "title": "Salle"
        +      },
        +      "salle_details": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Détails enrichis de la salle de sport.",
        +        "title": "Salle Details"
        +      },
        +      "score_equipe1": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Score de l'équipe 1.",
        +        "title": "Score Equipe1"
        +      },
        +      "score_equipe2": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Score de l'équipe 2.",
        +        "title": "Score Equipe2"
        +      },
        +      "ville": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "description": "Ville où se situe la salle.",
        +        "title": "Ville"
        +      }
        +    },
        +    "required": [
        +      "id"
        +    ],
        +    "title": "CalendrierMatch",
        +    "type": "object"
        +  }
        +}
      • addedOutput schema / properties / result / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "items": {
        +      "$ref": "#/$defs/CalendrierMatch"
        +    },
        +    "type": "array"
        +  }
        +]
      • removedOutput schema / properties / result / items
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • removedOutput schema / properties / result / type
        Removed value: -"array"
  10. 12 tool updatesv1.3.2
    • Addedffbb_bilan
    • Addedffbb_bilan_saison
    • Addedffbb_club
    • Addedffbb_get
    • Addedffbb_last_result
    • Addedffbb_lives
    • Addedffbb_next_match
    • Addedffbb_resolve_team
    • Addedffbb_saisons
    • Addedffbb_search
    • Addedffbb_team_summary
    • Addedffbb_version
  11. 12 tool updatesv1.3.1
    • Removedffbb_bilan
    • Removedffbb_bilan_saison
    • Removedffbb_club
    • Removedffbb_get
    • Removedffbb_last_result
    • Removedffbb_lives
    • Removedffbb_next_match
    • Removedffbb_resolve_team
    • Removedffbb_saisons
    • Removedffbb_search
    • Removedffbb_team_summary
    • Removedffbb_version
  12. 22 tool updatesv1.2.0
    • Addedffbb_bilan
    • Addedffbb_bilan_saison
    • Addedffbb_club
    • Addedffbb_get
    • Removedffbb_get_competition
    • Removedffbb_get_lives
    • Removedffbb_get_organisme
    • Removedffbb_get_poule
    • Removedffbb_get_saisons
    • Addedffbb_last_result
    • Addedffbb_lives
    • Removedffbb_multi_search
    • Addedffbb_next_match
    • Addedffbb_resolve_team
    • Addedffbb_saisons
    • Addedffbb_search
    • Removedffbb_search_competitions
    • Removedffbb_search_organismes
    • Removedffbb_search_rencontres
    • Removedffbb_search_salles
    • Addedffbb_team_summary
    • Addedffbb_version
  13. 10 tool updatesv0.1.0
    • First observedffbb_get_competition
    • First observedffbb_get_lives
    • First observedffbb_get_organisme
    • First observedffbb_get_poule
    • First observedffbb_get_saisons
    • First observedffbb_multi_search
    • First observedffbb_search_competitions
    • First observedffbb_search_organismes
    • First observedffbb_search_rencontres
    • First observedffbb_search_salles

TDQS

A3.6/5.0

Scored across 18 tools

Disambiguation2/5

Several tools have strongly overlapping purposes, especially ffbb_bilan, ffbb_bilan_saison, and ffbb_team_summary, which all return team bilan data. ffbb_resolve_team and ffbb_find_team_candidates also serve nearly the same disambiguation role, making it easy for an agent to select the wrong tool despite the extensive 'use X instead of Y' notes.

Naming Consistency3/5

All tools share the ffbb_ prefix and snake_case, which is good, but the pattern is mixed: some are noun-style (ffbb_bilan, ffbb_lives, ffbb_head_to_head) while others are verb-style (ffbb_search, ffbb_get, ffbb_resolve_team, ffbb_explain_tiebreak_rules). The naming is readable but not predictable enough to infer tool purpose from the name alone.

Tool Count4/5

18 tools is slightly over the ideal 3-15 range, but the scope is broad: search, team resolution, results, standings, regulations, live feeds, and head-to-head analysis. Each subdomain has a small dedicated cluster, so the count feels justified rather than bloated.

Completeness4/5

The server covers the main read-only FFBB query domain well: search, team info, results, schedules, standings, regulations, and live data. Minor gaps exist—such as no dedicated standalone 'get standings for competition X' tool outside ffbb_club/ffbb_get—but most real user queries can be answered with the available surface.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides access to comprehensive sports data from 5 major leagues (NBA, NFL, MLB, EPL, NHL) including teams, players, games, statistics, standings, injuries, and betting odds through 67+ endpoints. Enables users to query sports information and analytics through natural language.
    12
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Gives your MCP host (Claude Desktop, Cursor, Continue, Zed) access to live scores, match details, standings, top scorers, knockout brackets and player stats across football, basketball, cricket and tennis. Backed by the free public SportScore API — no key, no signup, CORS-open.
    8
    307 npm
    12
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Provides comprehensive NBA statistics via Model Context Protocol, enabling queries for player stats, game scores, team info, and advanced analytics through natural language.
    21
    10
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to access comprehensive sports data including football, basketball, American football, and hockey leagues via 11 tools, with no API key required.
    MIT