ffbb-mcp-server 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ffbb_mcp_server-1.3.0/LICENSE +21 -0
- ffbb_mcp_server-1.3.0/PKG-INFO +174 -0
- ffbb_mcp_server-1.3.0/README.md +143 -0
- ffbb_mcp_server-1.3.0/pyproject.toml +102 -0
- ffbb_mcp_server-1.3.0/setup.cfg +4 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/__init__.py +9 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/__main__.py +6 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/_state.py +72 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/aliases.py +374 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/app_factory.py +99 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/benchmark.py +212 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/cache_strategy.py +77 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/client.py +117 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/dashboard.py +312 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/metrics.py +317 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/prompts.py +622 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/py.typed +0 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/resources.py +54 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/routes.py +259 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/server.py +1123 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/services.py +2912 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp/utils.py +250 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/PKG-INFO +174 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/SOURCES.txt +46 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/dependency_links.txt +1 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/entry_points.txt +2 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/requires.txt +21 -0
- ffbb_mcp_server-1.3.0/src/ffbb_mcp_server.egg-info/top_level.txt +1 -0
- ffbb_mcp_server-1.3.0/tests/test_aliases_robustness.py +128 -0
- ffbb_mcp_server-1.3.0/tests/test_app_factory.py +103 -0
- ffbb_mcp_server-1.3.0/tests/test_audit_feedback.py +66 -0
- ffbb_mcp_server-1.3.0/tests/test_benchmark.py +171 -0
- ffbb_mcp_server-1.3.0/tests/test_cache_config.py +102 -0
- ffbb_mcp_server-1.3.0/tests/test_client.py +96 -0
- ffbb_mcp_server-1.3.0/tests/test_dashboard.py +70 -0
- ffbb_mcp_server-1.3.0/tests/test_feature_ranking_auto.py +113 -0
- ffbb_mcp_server-1.3.0/tests/test_ffbb_club_auto_res.py +115 -0
- ffbb_mcp_server-1.3.0/tests/test_metrics.py +88 -0
- ffbb_mcp_server-1.3.0/tests/test_phase.py +225 -0
- ffbb_mcp_server-1.3.0/tests/test_prompts.py +115 -0
- ffbb_mcp_server-1.3.0/tests/test_refactored_helpers.py +402 -0
- ffbb_mcp_server-1.3.0/tests/test_resolve_log_paths.py +76 -0
- ffbb_mcp_server-1.3.0/tests/test_resources.py +85 -0
- ffbb_mcp_server-1.3.0/tests/test_routes.py +236 -0
- ffbb_mcp_server-1.3.0/tests/test_server.py +153 -0
- ffbb_mcp_server-1.3.0/tests/test_services.py +1374 -0
- ffbb_mcp_server-1.3.0/tests/test_utils.py +136 -0
- ffbb_mcp_server-1.3.0/tests/test_version_tools.py +59 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Nicolas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ffbb-mcp-server
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: MCP Server for FFBB (Fédération Française de Basketball) data
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://github.com/nickdesi/FFBB-MCP-Server
|
|
7
|
+
Project-URL: Repository, https://github.com/nickdesi/FFBB-MCP-Server
|
|
8
|
+
Requires-Python: >=3.14
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: mcp[cli]>=1.27.0
|
|
12
|
+
Requires-Dist: ffbb-data-client<3.0.0,>=2.1.0
|
|
13
|
+
Requires-Dist: httpx>=0.28.0
|
|
14
|
+
Requires-Dist: uvicorn<1.0.0,>=0.30.0
|
|
15
|
+
Requires-Dist: starlette<2.0.0
|
|
16
|
+
Requires-Dist: pydantic<3.0.0,>=2.12.5
|
|
17
|
+
Requires-Dist: cachetools>=5.3.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
22
|
+
Requires-Dist: ruff>=0.15.12; extra == "dev"
|
|
23
|
+
Requires-Dist: mypy>=1.15.0; extra == "dev"
|
|
24
|
+
Requires-Dist: types-cachetools>=7.0.0.20260503; extra == "dev"
|
|
25
|
+
Requires-Dist: types-setuptools; extra == "dev"
|
|
26
|
+
Requires-Dist: pre-commit>=3.7.0; extra == "dev"
|
|
27
|
+
Provides-Extra: docs
|
|
28
|
+
Requires-Dist: mkdocs>=1.6.0; extra == "docs"
|
|
29
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# 🏀 FFBB MCP Server
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<img src="./assets/logo.webp" width="180" alt="Logo FFBB MCP" style="border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1);" />
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<h3 align="center">Serveur MCP pour consulter les données officielles du basket français.</h3>
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
Calendriers, classements, bilans, résultats et scores live FFBB pour assistants IA compatibles MCP.
|
|
42
|
+
<br /><br />
|
|
43
|
+
🌐 <b><a href="https://ffbb.desimone.fr">Site</a></b>
|
|
44
|
+
· 🧩 <b><a href="https://github.com/nickdesi/FFBB-MCP-Server/releases/latest">Extension VS Code</a></b>
|
|
45
|
+
· 📚 <b><a href="https://ffbb.desimone.fr/docs/">Documentation</a></b>
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<img src="https://img.shields.io/badge/Python-3.14%2B-blue?style=for-the-badge&logo=python" alt="Version Python" />
|
|
50
|
+
<img src="https://img.shields.io/badge/version-1.3.0-green?style=for-the-badge" alt="Version" />
|
|
51
|
+
<a href="https://smithery.ai/servers/nickdesi/mcpffbb"><img src="https://smithery.ai/badge/nickdesi/mcpffbb" alt="Badge Smithery" /></a>
|
|
52
|
+
<img src="https://img.shields.io/github/actions/workflow/status/nickdesi/FFBB-MCP-Server/ci.yml?label=CI&style=for-the-badge" alt="Statut CI" />
|
|
53
|
+
<img src="https://img.shields.io/badge/License-Apache--2.0-blue?style=for-the-badge" alt="Licence" />
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Utiliser l'instance publique
|
|
59
|
+
|
|
60
|
+
Endpoint MCP public :
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
https://ffbb.desimone.fr/mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Transport : **Streamable HTTP**.
|
|
67
|
+
|
|
68
|
+
Endpoints utiles :
|
|
69
|
+
|
|
70
|
+
- Dashboard : `https://ffbb.desimone.fr/dashboard`
|
|
71
|
+
- Métriques : `https://ffbb.desimone.fr/metrics.json`
|
|
72
|
+
- Santé : `https://ffbb.desimone.fr/health`
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Installation rapide
|
|
77
|
+
|
|
78
|
+
### VS Code / GitHub Copilot
|
|
79
|
+
|
|
80
|
+
Option recommandée : installer l’extension **FFBB Basketball MCP** depuis les [releases](https://github.com/nickdesi/FFBB-MCP-Server/releases/latest), puis ouvrir Copilot Chat en mode agent.
|
|
81
|
+
|
|
82
|
+
Alternative sans extension : [Installer FFBB MCP](vscode:mcp/install?%7B%22name%22%3A%22ffbb-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fffbb.desimone.fr%2Fmcp%22%7D)
|
|
83
|
+
|
|
84
|
+
### Claude Desktop
|
|
85
|
+
|
|
86
|
+
Ajoutez le serveur dans `claude_desktop_config.json` :
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"ffbb": {
|
|
92
|
+
"httpUrl": "https://ffbb.desimone.fr/mcp"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Cursor / autres clients MCP
|
|
99
|
+
|
|
100
|
+
Configurez un serveur MCP distant :
|
|
101
|
+
|
|
102
|
+
- Type : `Streamable HTTP`
|
|
103
|
+
- URL : `https://ffbb.desimone.fr/mcp`
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Outils principaux
|
|
108
|
+
|
|
109
|
+
| Outil | Usage |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `ffbb_bilan` | Bilan complet d’une équipe, toutes phases confondues. |
|
|
112
|
+
| `ffbb_team_summary` | Résumé agent : bilan, classement courant, dernier résultat, prochain match. |
|
|
113
|
+
| `ffbb_bilan_saison` | Bilan détaillé d’une équipe précise avec `numero_equipe`. |
|
|
114
|
+
| `ffbb_last_result` | Dernier match joué. |
|
|
115
|
+
| `ffbb_next_match` | Prochain match. |
|
|
116
|
+
| `ffbb_club` | Calendrier complet, équipes ou classement d’un club. |
|
|
117
|
+
| `ffbb_search` | Recherche clubs, compétitions, salles, matchs, engagements. |
|
|
118
|
+
| `ffbb_get` | Accès technique à une ressource FFBB par identifiant. |
|
|
119
|
+
| `ffbb_lives` | Matchs en direct. |
|
|
120
|
+
| `ffbb_saisons` | Saisons disponibles. |
|
|
121
|
+
| `ffbb_version` | Version et diagnostic runtime. |
|
|
122
|
+
|
|
123
|
+
La référence complète est dans [`docs/TOOLS_REFERENCE.md`](docs/TOOLS_REFERENCE.md).
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Architecture en bref
|
|
128
|
+
|
|
129
|
+
```mermaid
|
|
130
|
+
flowchart LR
|
|
131
|
+
A[Client MCP] -->|Streamable HTTP| B[FFBB MCP Server]
|
|
132
|
+
B --> C[Services métier + cache]
|
|
133
|
+
C --> D[ffbb-data-client]
|
|
134
|
+
D --> E[API officielle FFBB]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Points clés :
|
|
138
|
+
|
|
139
|
+
- serveur Python 3.10+ basé sur `mcp[cli]`, `starlette` et `uvicorn` ;
|
|
140
|
+
- agrégation métier pour limiter le nombre d'appels et réduire le contexte LLM ;
|
|
141
|
+
- cache TTL adapté aux données live, calendriers et classements ;
|
|
142
|
+
- dashboard, métriques JSON et healthcheck intégrés.
|
|
143
|
+
|
|
144
|
+
Détails : [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) et [`docs/PERFORMANCE.md`](docs/PERFORMANCE.md).
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Développement local
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
uv sync --extra dev
|
|
152
|
+
uv run ruff format .
|
|
153
|
+
uv run ruff check --fix .
|
|
154
|
+
uv run mypy src
|
|
155
|
+
uv run pytest
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Voir [`CONTRIBUTING.md`](CONTRIBUTING.md) pour les règles de contribution.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Documentation
|
|
163
|
+
|
|
164
|
+
- [Exemples d’usage](docs/EXAMPLES.md)
|
|
165
|
+
- [Référence des outils](docs/TOOLS_REFERENCE.md)
|
|
166
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
167
|
+
- [Performance et cache](docs/PERFORMANCE.md)
|
|
168
|
+
- [Déploiement Coolify](docs/COOLIFY_DEPLOYMENT.md)
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
<p align="center">
|
|
173
|
+
<i>Projet non officiel, non affilié à la Fédération Française de BasketBall.</i>
|
|
174
|
+
</p>
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# 🏀 FFBB MCP Server
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="./assets/logo.webp" width="180" alt="Logo FFBB MCP" style="border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1);" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h3 align="center">Serveur MCP pour consulter les données officielles du basket français.</h3>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Calendriers, classements, bilans, résultats et scores live FFBB pour assistants IA compatibles MCP.
|
|
11
|
+
<br /><br />
|
|
12
|
+
🌐 <b><a href="https://ffbb.desimone.fr">Site</a></b>
|
|
13
|
+
· 🧩 <b><a href="https://github.com/nickdesi/FFBB-MCP-Server/releases/latest">Extension VS Code</a></b>
|
|
14
|
+
· 📚 <b><a href="https://ffbb.desimone.fr/docs/">Documentation</a></b>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<img src="https://img.shields.io/badge/Python-3.14%2B-blue?style=for-the-badge&logo=python" alt="Version Python" />
|
|
19
|
+
<img src="https://img.shields.io/badge/version-1.3.0-green?style=for-the-badge" alt="Version" />
|
|
20
|
+
<a href="https://smithery.ai/servers/nickdesi/mcpffbb"><img src="https://smithery.ai/badge/nickdesi/mcpffbb" alt="Badge Smithery" /></a>
|
|
21
|
+
<img src="https://img.shields.io/github/actions/workflow/status/nickdesi/FFBB-MCP-Server/ci.yml?label=CI&style=for-the-badge" alt="Statut CI" />
|
|
22
|
+
<img src="https://img.shields.io/badge/License-Apache--2.0-blue?style=for-the-badge" alt="Licence" />
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Utiliser l'instance publique
|
|
28
|
+
|
|
29
|
+
Endpoint MCP public :
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
https://ffbb.desimone.fr/mcp
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Transport : **Streamable HTTP**.
|
|
36
|
+
|
|
37
|
+
Endpoints utiles :
|
|
38
|
+
|
|
39
|
+
- Dashboard : `https://ffbb.desimone.fr/dashboard`
|
|
40
|
+
- Métriques : `https://ffbb.desimone.fr/metrics.json`
|
|
41
|
+
- Santé : `https://ffbb.desimone.fr/health`
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Installation rapide
|
|
46
|
+
|
|
47
|
+
### VS Code / GitHub Copilot
|
|
48
|
+
|
|
49
|
+
Option recommandée : installer l’extension **FFBB Basketball MCP** depuis les [releases](https://github.com/nickdesi/FFBB-MCP-Server/releases/latest), puis ouvrir Copilot Chat en mode agent.
|
|
50
|
+
|
|
51
|
+
Alternative sans extension : [Installer FFBB MCP](vscode:mcp/install?%7B%22name%22%3A%22ffbb-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fffbb.desimone.fr%2Fmcp%22%7D)
|
|
52
|
+
|
|
53
|
+
### Claude Desktop
|
|
54
|
+
|
|
55
|
+
Ajoutez le serveur dans `claude_desktop_config.json` :
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"ffbb": {
|
|
61
|
+
"httpUrl": "https://ffbb.desimone.fr/mcp"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Cursor / autres clients MCP
|
|
68
|
+
|
|
69
|
+
Configurez un serveur MCP distant :
|
|
70
|
+
|
|
71
|
+
- Type : `Streamable HTTP`
|
|
72
|
+
- URL : `https://ffbb.desimone.fr/mcp`
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Outils principaux
|
|
77
|
+
|
|
78
|
+
| Outil | Usage |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `ffbb_bilan` | Bilan complet d’une équipe, toutes phases confondues. |
|
|
81
|
+
| `ffbb_team_summary` | Résumé agent : bilan, classement courant, dernier résultat, prochain match. |
|
|
82
|
+
| `ffbb_bilan_saison` | Bilan détaillé d’une équipe précise avec `numero_equipe`. |
|
|
83
|
+
| `ffbb_last_result` | Dernier match joué. |
|
|
84
|
+
| `ffbb_next_match` | Prochain match. |
|
|
85
|
+
| `ffbb_club` | Calendrier complet, équipes ou classement d’un club. |
|
|
86
|
+
| `ffbb_search` | Recherche clubs, compétitions, salles, matchs, engagements. |
|
|
87
|
+
| `ffbb_get` | Accès technique à une ressource FFBB par identifiant. |
|
|
88
|
+
| `ffbb_lives` | Matchs en direct. |
|
|
89
|
+
| `ffbb_saisons` | Saisons disponibles. |
|
|
90
|
+
| `ffbb_version` | Version et diagnostic runtime. |
|
|
91
|
+
|
|
92
|
+
La référence complète est dans [`docs/TOOLS_REFERENCE.md`](docs/TOOLS_REFERENCE.md).
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Architecture en bref
|
|
97
|
+
|
|
98
|
+
```mermaid
|
|
99
|
+
flowchart LR
|
|
100
|
+
A[Client MCP] -->|Streamable HTTP| B[FFBB MCP Server]
|
|
101
|
+
B --> C[Services métier + cache]
|
|
102
|
+
C --> D[ffbb-data-client]
|
|
103
|
+
D --> E[API officielle FFBB]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Points clés :
|
|
107
|
+
|
|
108
|
+
- serveur Python 3.10+ basé sur `mcp[cli]`, `starlette` et `uvicorn` ;
|
|
109
|
+
- agrégation métier pour limiter le nombre d'appels et réduire le contexte LLM ;
|
|
110
|
+
- cache TTL adapté aux données live, calendriers et classements ;
|
|
111
|
+
- dashboard, métriques JSON et healthcheck intégrés.
|
|
112
|
+
|
|
113
|
+
Détails : [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) et [`docs/PERFORMANCE.md`](docs/PERFORMANCE.md).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Développement local
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv sync --extra dev
|
|
121
|
+
uv run ruff format .
|
|
122
|
+
uv run ruff check --fix .
|
|
123
|
+
uv run mypy src
|
|
124
|
+
uv run pytest
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Voir [`CONTRIBUTING.md`](CONTRIBUTING.md) pour les règles de contribution.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Documentation
|
|
132
|
+
|
|
133
|
+
- [Exemples d’usage](docs/EXAMPLES.md)
|
|
134
|
+
- [Référence des outils](docs/TOOLS_REFERENCE.md)
|
|
135
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
136
|
+
- [Performance et cache](docs/PERFORMANCE.md)
|
|
137
|
+
- [Déploiement Coolify](docs/COOLIFY_DEPLOYMENT.md)
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
<p align="center">
|
|
142
|
+
<i>Projet non officiel, non affilié à la Fédération Française de BasketBall.</i>
|
|
143
|
+
</p>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=82.0.1", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ffbb-mcp-server"
|
|
7
|
+
version = "1.3.0"
|
|
8
|
+
description = "MCP Server for FFBB (Fédération Française de Basketball) data"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.14"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
dependencies = [
|
|
13
|
+
"mcp[cli]>=1.27.0",
|
|
14
|
+
"ffbb-data-client>=2.1.0,<3.0.0",
|
|
15
|
+
"httpx>=0.28.0",
|
|
16
|
+
"uvicorn>=0.30.0,<1.0.0",
|
|
17
|
+
"starlette<2.0.0",
|
|
18
|
+
"pydantic>=2.12.5,<3.0.0",
|
|
19
|
+
"cachetools>=5.3.0",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/nickdesi/FFBB-MCP-Server"
|
|
24
|
+
Repository = "https://github.com/nickdesi/FFBB-MCP-Server"
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
dev = [
|
|
28
|
+
"pytest>=8.0.0",
|
|
29
|
+
"pytest-asyncio>=0.23.0",
|
|
30
|
+
"pytest-cov>=4.1.0",
|
|
31
|
+
"ruff>=0.15.12",
|
|
32
|
+
"mypy>=1.15.0",
|
|
33
|
+
"types-cachetools>=7.0.0.20260503",
|
|
34
|
+
"types-setuptools",
|
|
35
|
+
"pre-commit>=3.7.0",
|
|
36
|
+
]
|
|
37
|
+
docs = [
|
|
38
|
+
"mkdocs>=1.6.0",
|
|
39
|
+
"mkdocs-material>=9.5.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
ffbb-mcp = "ffbb_mcp.server:main"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
where = ["src"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-data]
|
|
49
|
+
"*" = ["website/*", "website/css/*"]
|
|
50
|
+
|
|
51
|
+
[tool.pytest.ini_options]
|
|
52
|
+
asyncio_mode = "auto"
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
addopts = "--cov=ffbb_mcp --cov-fail-under=65"
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 88
|
|
58
|
+
target-version = "py314"
|
|
59
|
+
exclude = [
|
|
60
|
+
".agent",
|
|
61
|
+
".git",
|
|
62
|
+
".venv",
|
|
63
|
+
".mypy_cache",
|
|
64
|
+
".ruff_cache",
|
|
65
|
+
"ffbb-data-client_Ref",
|
|
66
|
+
"external",
|
|
67
|
+
"external/**",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = ["E", "F", "I", "UP", "B", "SIM", "RUF", "ASYNC", "TCH"]
|
|
72
|
+
ignore = ["E501"]
|
|
73
|
+
|
|
74
|
+
[tool.ruff.format]
|
|
75
|
+
quote-style = "double"
|
|
76
|
+
indent-style = "space"
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
disallow_untyped_defs = false
|
|
80
|
+
warn_return_any = false
|
|
81
|
+
warn_unused_configs = true
|
|
82
|
+
ignore_missing_imports = true
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
[tool.ruff.lint.per-file-ignores]
|
|
86
|
+
"tests/*" = ["S101", "RUF059", "F821"]
|
|
87
|
+
"tools/*" = ["S110"]
|
|
88
|
+
"src/ffbb_mcp/prompts.py" = ["RUF001", "RUF003"]
|
|
89
|
+
"src/ffbb_mcp/cache_strategy.py" = ["RUF003"]
|
|
90
|
+
"src/ffbb_mcp/server.py" = ["RUF001"]
|
|
91
|
+
|
|
92
|
+
[[tool.mypy.overrides]]
|
|
93
|
+
module = ["cachetools"]
|
|
94
|
+
ignore_missing_imports = true
|
|
95
|
+
|
|
96
|
+
[[tool.mypy.overrides]]
|
|
97
|
+
module = "starlette.middleware.base"
|
|
98
|
+
ignore_missing_imports = true
|
|
99
|
+
|
|
100
|
+
[[tool.mypy.overrides]]
|
|
101
|
+
module = "ffbb_mcp.services"
|
|
102
|
+
disable_error_code = ["attr-defined"]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""FFBB MCP Server — Fédération Française de Basketball."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError
|
|
4
|
+
from importlib.metadata import version as _pkg_version
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
__version__ = _pkg_version("ffbb-mcp-server")
|
|
8
|
+
except PackageNotFoundError:
|
|
9
|
+
__version__ = "unknown"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
import asyncio
|
|
9
|
+
|
|
10
|
+
from cachetools import TLRUCache, TTLCache
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _read_positive_int_env(key: str, default: int) -> int:
|
|
14
|
+
val_str = os.environ.get(key)
|
|
15
|
+
if val_str is not None:
|
|
16
|
+
try:
|
|
17
|
+
val = int(val_str)
|
|
18
|
+
if val > 0:
|
|
19
|
+
return val
|
|
20
|
+
except ValueError:
|
|
21
|
+
pass
|
|
22
|
+
return default
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class _ServiceState:
|
|
27
|
+
inflight_bilan: dict[str, asyncio.Task[Any]] = field(default_factory=dict)
|
|
28
|
+
inflight_calendrier: dict[str, asyncio.Task[Any]] = field(default_factory=dict)
|
|
29
|
+
inflight_poule: dict[str, asyncio.Task[Any]] = field(default_factory=dict)
|
|
30
|
+
inflight_detail: dict[str, asyncio.Task[Any]] = field(default_factory=dict)
|
|
31
|
+
inflight_search: dict[str, asyncio.Task[Any]] = field(default_factory=dict)
|
|
32
|
+
|
|
33
|
+
# Caches in-memory globaux
|
|
34
|
+
cache_lives: TTLCache[Any, Any] | None = None
|
|
35
|
+
cache_search: TTLCache[Any, Any] | None = None
|
|
36
|
+
cache_competition: TTLCache[Any, Any] | None = None
|
|
37
|
+
cache_organisme: TTLCache[Any, Any] | None = None
|
|
38
|
+
cache_saisons: TTLCache[Any, Any] | None = None
|
|
39
|
+
cache_calendrier: TTLCache[Any, Any] | TLRUCache[Any, Any] | None = None
|
|
40
|
+
cache_bilan: TLRUCache[Any, Any] | None = None
|
|
41
|
+
cache_classement: TLRUCache[Any, Any] | None = None
|
|
42
|
+
cache_poule: TLRUCache[Any, Any] | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
state = _ServiceState()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def reset_service_state() -> None:
|
|
49
|
+
global state
|
|
50
|
+
state.inflight_bilan.clear()
|
|
51
|
+
state.inflight_calendrier.clear()
|
|
52
|
+
state.inflight_poule.clear()
|
|
53
|
+
state.inflight_detail.clear()
|
|
54
|
+
state.inflight_search.clear()
|
|
55
|
+
if state.cache_lives is not None:
|
|
56
|
+
state.cache_lives.clear()
|
|
57
|
+
if state.cache_search is not None:
|
|
58
|
+
state.cache_search.clear()
|
|
59
|
+
if state.cache_competition is not None:
|
|
60
|
+
state.cache_competition.clear()
|
|
61
|
+
if state.cache_organisme is not None:
|
|
62
|
+
state.cache_organisme.clear()
|
|
63
|
+
if state.cache_saisons is not None:
|
|
64
|
+
state.cache_saisons.clear()
|
|
65
|
+
if state.cache_calendrier is not None:
|
|
66
|
+
state.cache_calendrier.clear()
|
|
67
|
+
if state.cache_bilan is not None:
|
|
68
|
+
state.cache_bilan.clear()
|
|
69
|
+
if state.cache_classement is not None:
|
|
70
|
+
state.cache_classement.clear()
|
|
71
|
+
if state.cache_poule is not None:
|
|
72
|
+
state.cache_poule.clear()
|