mcp-asterisk-socle
by Bamba4700
README.md
# Module 1 — Socle Framework MCP & Sécurité
Serveur MCP sécurisé pour la supervision d'un PBX Asterisk.
**Responsables :** Khadim GUEYE, Gnilane NIANE
**Projet :** Supervision Asterisk via Model Context Protocol
Ce module fournit le socle sur lequel se branchent :
- **Module 2** — Outils de supervision Asterisk (ARI/AMI)
- **Module 3** — Pipeline vocal Speech-to-Speech
---
## Démarrage rapide
```bash
git clone https://github.com/Bamba4700/mcp-asterisk-socle.git
cd mcp-asterisk-socle
docker compose up -d
```
Trois conteneurs démarrent :
| Service | Port | Rôle |
|---|---|---|
| `keycloak-db` | interne | Base PostgreSQL de Keycloak |
| `keycloak` | 8080 | Serveur d'identité (realm importé automatiquement) |
| `mcp-server` | 8000 | Le serveur MCP |
Console Keycloak : http://localhost:8080 (`admin` / `admin`)
Endpoint MCP : http://localhost:8000/mcp
---
## Comptes de test
| Utilisateur | Mot de passe | Rôle |
|---|---|---|
| `admin_demo` | `admin` | `admin` — accès complet |
| `superviseur_demo` | `admin` | `superviseur` — lecture, analyse, écoute |
| `operateur_demo` | `admin` | `operateur` — lecture seule |
---
## Obtenir un jeton JWT
```bash
source load_secret.sh # récupère le client_secret depuis Keycloak
curl -s -X POST http://localhost:8080/realms/mcp-asterisk/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=mcp-server" \
-d "client_secret=$KC_CLIENT_SECRET" \
-d "username=admin_demo" \
-d "password=admin"
```
Le jeton est valable **5 minutes**.
---
## Ajouter un outil (Modules 2 et 3)
Créez votre fichier dans `src/tools/`, puis importez-le dans `src/server.py`.
### Outil de lecture (RBAC seul)
```python
from fastmcp.server.dependencies import CurrentAccessToken
from src.server import mcp
from src.security.rbac import require_role
from src.hitl.sanitizer import sanitize
@mcp.tool()
def list_active_channels(token=CurrentAccessToken()) -> dict:
"""Liste les canaux actifs du PBX."""
require_role(token, "operateur")
resultat = ... # votre code ARI/AMI
return sanitize(resultat)
```
### Outil de pilotage (RBAC + confirmation humaine)
```python
from fastmcp import Context
from src.hitl.confirmation import demander_confirmation
@mcp.tool()
async def hangup_channel(
channel_id: str,
ctx: Context,
token=CurrentAccessToken(),
) -> str:
"""Raccroche un canal Asterisk."""
require_role(token, "admin")
await demander_confirmation(
ctx, f"Confirmez le raccrochage du canal {channel_id} ?"
)
... # votre code ARI/AMI
return sanitize(f"Canal {channel_id} raccroche.")
```
### Règles à respecter
1. **Tout outil** appelle `require_role(token, "...")` en première ligne
2. **Tout outil de pilotage** appelle `demander_confirmation(...)` avant d'agir
3. **Toute sortie** passe par `sanitize(...)` avant d'être retournée
---
## Sécurité implémentée
| Exigence (cahier des charges A.6) | Implémentation |
|---|---|
| RBAC 3 rôles | `src/security/rbac.py` |
| Jetons JWT via Keycloak (OIDC) | `src/security/auth.py` — `JWTVerifier` |
| Interdiction du token passthrough | Le jeton n'authentifie que la session MCP |
| Consentement humain obligatoire | `src/hitl/confirmation.py` — primitive Elicitation |
| Sorties = entrées non fiables | `src/hitl/sanitizer.py` |
---
## Avertissement
Cette configuration est destinée au **développement local**.
Avant tout déploiement réel : changer les mots de passe (`admin`/`admin`,
`POSTGRES_PASSWORD`), activer HTTPS, et remplacer `start-dev` par `start`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues