agoraplus-saintmaur-mcp
# Agora Plus Saint-Maur MCP
Serveur MCP local et non officiel pour consulter le portail familial Agora Plus de Saint-Maur-des-Fossés et encadrer les réservations ou annulations par une confirmation explicite.
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
[](LICENSE)
> **Projet expérimental.** Il dépend d'endpoints internes d'Agora Plus, susceptibles de changer sans préavis. Ce dépôt n'est affilié ni à Agora Plus ni à la ville de Saint-Maur-des-Fossés.
## À quoi sert ce projet ?
Une fois connecté à un client MCP compatible, vous pouvez demander à votre assistant de :
- ouvrir une session Agora Plus et vérifier son état ;
- consulter les inscriptions périscolaires ;
- lire les réservations et les créneaux disponibles sur une période ;
- produire une vue calendrier ou un résumé hebdomadaire ;
- préparer puis, après confirmation, exécuter une réservation ou une annulation.
Le projet ne gère ni paiement, ni compte utilisateur, ni synchronisation Google Calendar.
## Principes de sécurité
Les consultations n'écrivent rien sur le portail. Une réservation ou une annulation suit obligatoirement ce parcours :
1. lecture d'un créneau réellement observé dans Agora Plus ;
2. génération d'un aperçu exact, sans écriture ;
3. émission d'une empreinte et d'un jeton valable cinq minutes, à usage unique ;
4. confirmation explicite transmise par le client MCP ;
5. nouvelle lecture du créneau, revalidation de son identité et de son tarif, puis écriture.
Une action peut être facturée ou soumise à pénalité. Vérifiez toujours l'enfant, la date, l'activité, le créneau et le tarif avant de confirmer.
Les identifiants et cookies restent locaux. Aucun outil MCP n'accepte de mot de passe en argument et le fichier `.env` ne doit jamais être versionné.
Voir [la documentation de sécurité](docs/SECURITY.md) pour les garanties et les limites résiduelles.
## Prérequis
Pour la méthode Docker recommandée :
- Docker avec le plugin Compose ;
- un compte valide sur le portail Agora Plus de Saint-Maur-des-Fossés ;
- un client compatible MCP en transport **stdio**, par exemple Hermes Agent.
Pour une installation sans Docker : Python 3.11 ou plus récent est requis.
## Démarrage rapide avec Docker
### 1. Récupérer le projet
```bash
git clone https://github.com/ghis94/agoraplus-saintmaur-mcp.git
cd agoraplus-saintmaur-mcp
```
### 2. Configurer la connexion
```bash
cp .env.example .env
chmod 600 .env
```
Renseignez ensuite ces variables dans `.env` :
```dotenv
AGORAPLUS_USERNAME=votre-identifiant
AGORAPLUS_PASSWORD=votre-mot-de-passe
```
### 3. Construire l'image
```bash
docker compose build
```
Le service MCP se lance avec :
```bash
docker compose run --rm -T mcp
```
Cette commande attend normalement qu'un client MCP communique avec elle sur stdin/stdout ; l'absence d'interface interactive dans le terminal est donc normale.
### 4. Connecter Hermes Agent
Le script `scripts/run-agora-docker.sh` fournit une commande stdio silencieuse adaptée à Hermes. Il retrouve automatiquement le fichier Compose à partir de son propre emplacement ; le dépôt peut donc être installé où vous le souhaitez.
```bash
hermes mcp add agora \
--command /chemin/absolu/agoraplus-saintmaur-mcp/scripts/run-agora-docker.sh
hermes mcp test agora
```
Une nouvelle session Hermes peut être nécessaire après l'ajout ou la modification d'un serveur MCP.
### 5. Vérifier la première connexion
Demandez d'abord au client d'appeler :
1. `start_login` ;
2. `connection_status` ;
3. `calendar_slots` sur une courte période.
Une découverte réussie des outils ne prouve pas que l'authentification fonctionne. L'état attendu après connexion contient `authenticated: true` et `browser_running: true`.
## Exemples d'utilisation
- « Montre-moi les créneaux Agora Plus du 14 au 18 septembre. »
- « Résume les réservations de la semaine prochaine. »
- « Prépare la réservation de ce créneau, sans l'exécuter. »
Pour une action d'écriture, le client doit afficher l'aperçu puis demander une confirmation séparée. N'appelez pas directement l'outil d'exécution avec `confirmed=true` sans validation humaine.
## Outils MCP disponibles
### Session et informations
- `portal_info` — décrit le portail, le mode de sécurité et la surface d'outils ;
- `initial_config` — lit la configuration publique du portail ;
- `start_login` — ouvre Chromium et tente la connexion automatique ;
- `connection_status` — indique si le navigateur et la session sont utilisables ;
- `session_status` — alias de compatibilité de `connection_status`.
### Consultations
- `inscriptions` — lit les inscriptions périscolaires observées ;
- `peri_inscriptions` — alias de compatibilité de `inscriptions` ;
- `calendar_slots` — lit les créneaux disponibles et sélectionnés sur une période ;
- `reservations_calendar` — construit une vue datée à partir des inscriptions ;
- `weekly_summary` — résume une semaine à partir des inscriptions.
### Actions protégées
- `agora_reservation_preview` — prépare une réservation et retourne son aperçu ;
- `agora_cancellation_preview` — prépare une annulation et retourne son aperçu ;
- `agora_actions_available` — indique si les routes d'écriture sont disponibles ;
- `agora_action_execute` — exécute uniquement l'action correspondant au jeton confirmé.
Le serveur expose actuellement **14 outils**.
## Configuration
**Variables nécessaires à la connexion automatique :**
- `AGORAPLUS_USERNAME` ;
- `AGORAPLUS_PASSWORD`.
**Variables optionnelles :**
- `AGORAPLUS_HEADLESS` — lance Chromium sans interface visible ; Compose force `true` par défaut ;
- `AGORAPLUS_BROWSER_PROFILE` — chemin du profil Chromium ;
- `AGORAPLUS_TIMEOUT` — délai d'attente du navigateur en secondes, `20` par défaut ;
- `AGORAPLUS_PORTAL_URL` — URL du portail, à modifier uniquement pour une instance compatible vérifiée ;
- `VNC_PASSWORD` — active le serveur noVNC du conteneur lorsqu'elle est définie.
Dans le service Compose, le profil Chromium se trouve dans le `/tmp` privé du conteneur et n'est pas conservé après son arrêt. La connexion automatique est donc recréée à chaque nouveau processus MCP.
## MFA, CAPTCHA et noVNC
Le mode headless suffit tant que la connexion automatique aboutit. Pour une intervention manuelle, définissez `VNC_PASSWORD` dans `.env`, puis remplacez explicitement la valeur Compose de `AGORAPLUS_HEADLESS` et publiez noVNC uniquement sur la boucle locale :
```bash
docker compose run --rm -T \
-e AGORAPLUS_HEADLESS=false \
-p 127.0.0.1:6080:6080 \
mcp
```
Ouvrez ensuite `http://127.0.0.1:6080/vnc.html`. N'exposez jamais ce port directement sur Internet.
La procédure détaillée figure dans [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
## Installation locale sans Docker
```bash
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[test]'
python -m playwright install chromium
agoraplus-saintmaur-mcp
```
En installation locale, `AGORAPLUS_HEADLESS` vaut `false` par défaut si la variable est absente.
## Développement et vérification
Après avoir installé les dépendances de test :
```bash
python -m pytest -q
python -m compileall -q src tests
sh -n docker/entrypoint.sh
sh -n scripts/run-agora-docker.sh
docker compose config --quiet
```
Le dépôt contient aussi un lanceur d'audit hors ligne qui bloque le réseau, les sous-processus et les suppressions pendant les tests. Depuis l'environnement virtuel du projet :
```bash
env -i PATH=/usr/bin:/bin HOME="$PWD/temp" PYTHONDONTWRITEBYTECODE=1 \
"$VIRTUAL_ENV/bin/python" tests/run_offline.py
```
Ce garde-fou n'est pas une sandbox système. Il ignore volontairement un test qui supprime de vrais verrous Chromium obsolètes.
Pour vérifier uniquement la structure Compose sans lire `.env` :
```bash
env -i PATH=/usr/bin:/bin HOME="$PWD/temp" COMPOSE_DISABLE_ENV_FILE=1 \
docker compose --env-file /dev/null -f docker-compose.yml \
config --no-env-resolution --services
```
La sortie attendue est `mcp`.
## Limites connues
- Les endpoints utilisés sont internes et peuvent évoluer avec le portail.
- Le code cible l'instance Saint-Maur-des-Fossés ; les autres collectivités ne sont pas garanties compatibles.
- Les tests automatisés utilisent des données fictives et ne valident pas le compte d'un nouvel utilisateur.
- Un résultat d'écriture peut devenir indéterminé si la connexion coupe après l'envoi. Dans ce cas, relisez l'état avant toute nouvelle tentative.
- Certaines erreurs techniques peuvent contenir une URL interne ; ne les publiez pas sans vérification.
- Une réponse d'inscriptions peut rester en mémoire pendant la session pour le payload observé ; relancez la session pour forcer une nouvelle capture.
- Le serveur ne peut pas prouver qu'un humain est à l'origine de `confirmed=true` : cette garantie dépend aussi du client MCP.
## Structure du dépôt
```text
src/agoraplus_saintmaur_mcp/ serveur MCP, navigateur et workflows protégés
tests/ tests unitaires et contrats publics
docker/ point d'entrée du conteneur
docs/ déploiement, sécurité et feuille de route
scripts/ lanceur Docker stdio pour Hermes
```
## Licence
Distribué sous licence [MIT](LICENSE).
TDQS
Scored across 5 tools
Each tool has a distinct purpose: portal_info and initial_config expose metadata/config, start_login and session_status handle authentication, and peri_inscriptions reads data. There is no overlap or ambiguity between them.
Names are readable and snake_case, but they mix noun phrases (portal_info, initial_config) with verb-led commands (start_login) and state descriptors (session_status). This is a mild inconsistency, though still predictable due to the small set.
With 5 tools, the server is well-scoped around portal metadata, configuration, authentication, and data reading. This is an appropriate size for a focused MCP server.
The surface covers the full read-only workflow: config, login, session check, and data retrieval. Minor gaps exist, such as a logout tool or explicit session refresh, but these are not blocking for the stated read-only scope.