Skip to main content
Glama
ClasseViva MCP

ClasseViva MCP

by leoron04
README.md
<p align="center">
  <img src="docs/banner.svg" alt="ClasseViva MCP" width="860"/>
</p>

<h1 align="center">ClasseViva MCP</h1>

<p align="center">
  <strong>Il tuo registro Spaggiari, dentro Claude.</strong><br/>
  Server MCP remoto multi-utente con login OAuth — open source, gratis, self-hostable.
</p>

<p align="center">
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"/></a>
  <a href="https://workers.cloudflare.com/"><img src="https://img.shields.io/badge/Cloudflare-Workers-F38020?logo=cloudflare&logoColor=white" alt="Cloudflare Workers"/></a>
  <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-remote%20server-412991" alt="MCP"/></a>
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white" alt="TypeScript"/></a>
  <img src="https://img.shields.io/badge/Made%20in-Italy-009246?labelColor=CE2B37" alt="Made in Italy"/>
  <a href="https://github.com/leoron04/classeviva-mcp/actions"><img src="https://img.shields.io/github/actions/workflow/status/leoron04/classeviva-mcp/ci.yml?label=CI" alt="CI"/></a>
</p>

> ⚠️ **Progetto non ufficiale.** Non è affiliato, sponsorizzato né approvato da Gruppo Spaggiari Parma S.p.A. Usa l'API **non documentata** dell'app ClasseViva (`web.spaggiari.eu/rest/v1`), solo in **lettura**, e può smettere di funzionare in qualsiasi momento. Vedi [Disclaimer](#disclaimer).

---

## Come si usa in Claude

1. Apri Claude (web, desktop o app) → **Impostazioni → Connettori → Aggiungi connettore personalizzato**.
2. Nome: `ClasseViva` — URL:
   ```
   https://classeviva-mcp.ronchfx.workers.dev/mcp
   ```
3. Lascia **vuoti** Client ID e Client Secret (la registrazione OAuth è automatica).
4. Premi **Connetti**: si apre una pagina di login in italiano. Inserisci codice utente (o email) e password di ClasseViva. Se hai più profili (es. genitore) puoi indicare il codice profilo.
5. Fatto. Puoi chiedere cose come: *«Che voti ho preso questa settimana?»*, *«Media in matematica?»*, *«Cosa c'è in agenda per domani?»*.

Per scollegarti rimuovi il connettore. Se cambi la password di ClasseViva, ricollega il connettore.

Preferisci la tua istanza? Vai a [Self-hosting](#self-hosting).

---

## Funzionalità (11 tool, sola lettura)

| | Tool | Cosa fa |
|---|---|---|
| 👤 | `get_profile` | Nome, scuola, città — utile per verificare il login |
| 📊 | `get_grades` | Voti con medie per materia e generale (`materia`, `periodo`, `ultimi`) |
| 📅 | `get_agenda` | Compiti e verifiche tra `dal` e `al` (default: oggi → +14 gg) |
| 📖 | `get_lessons` | Argomenti delle lezioni (default: ultimi 7 giorni) |
| 🚪 | `get_absences` | Assenze, ritardi, uscite + quante da giustificare |
| 📢 | `get_noticeboard` | Circolari della bacheca (**non** le segna come lette) |
| 📝 | `get_notes` | Note disciplinari, annotazioni, richiami, sanzioni |
| 📚 | `get_subjects` | Materie e docenti |
| 🗓️ | `get_periods` | Trimestri / quadrimestri con le date |
| 🗂️ | `get_didactics` | Materiali condivisi dai docenti (Didattica) |
| 🏫 | `get_calendar` | Giorni di lezione e vacanze in un intervallo |

Date in formato `YYYY-MM-DD` (fuso `Europe/Rome`). ClasseViva espone **solo l'anno scolastico in corso**. I voti blu/annullati non entrano nelle medie.

---

## Come funziona (OAuth)

```mermaid
sequenceDiagram
  participant Claude
  participant MCP as ClasseViva MCP<br/>/mcp
  participant Auth as /authorize<br/>(pagina di login)
  participant Spaggiari as Spaggiari<br/>API non ufficiale
  Claude->>MCP: tools/list (senza token)
  MCP-->>Claude: 401 + resource_metadata
  Claude->>Auth: OAuth 2.1 + PKCE (+ DCR)
  Note over Auth: l'utente inserisce le<br/>credenziali ClasseViva
  Auth->>Spaggiari: login di verifica
  Spaggiari-->>Auth: ok / errore
  Auth-->>Claude: authorization code
  Claude->>MCP: code → access token
  Note over MCP: credenziali cifrate<br/>nelle props del grant
  Claude->>MCP: get_grades / get_agenda / …
  MCP->>Spaggiari: richiesta in lettura
  Spaggiari-->>MCP: dati
  MCP-->>Claude: risposta tool
```

---

## Sicurezza e privacy

- **OAuth 2.1 con PKCE**, Dynamic Client Registration e discovery standard, tramite [`@cloudflare/workers-oauth-provider`](https://github.com/cloudflare/workers-oauth-provider).
- Dopo il login, username e password **non sono salvati in chiaro**: restano solo nelle *props* del grant, **cifrate con AES-GCM** (chiave avvolta dal token). Nel KV di Cloudflare ci sono hash dei token e blob cifrati.
- Il server **non tiene una copia** di voti o agenda: ogni domanda viene girata a ClasseViva in quel momento. La sessione Spaggiari (~90 min) vive solo in memoria e si rinnova da sola.
- Nel database l'utente è uno **pseudonimo** (HMAC dell'username), non l'username in chiaro.
- Login protetto da **CSRF**, cookie `__Host-`, controllo `Origin`, no-iframe, CSP restrittiva, rate limit (IP + username) e tetto ai fallimenti.
- **Nessun log** di credenziali o dati personali. Access token ~1 ora; il grant scade dopo 60 giorni di inutilizzo.

**Limiti onesti.** Spaggiari non offre un login delegato: il server *deve* poter usare la tua password per parlare con l'API. Devi fidarti di chi gestisce l'istanza e del codice (tutto qui, open source). L'API è **non ufficiale** e può cambiare o essere bloccata. L'istanza pubblica è pensata per **uso personale e tra amici consapevoli**; se gestisci i dati di altri (soprattutto minorenni) sei responsabile secondo il **GDPR** — in quel caso **self-hosta** la tua copia e non riusare l'istanza pubblica come servizio generico.

---

## Self-hosting

Account Cloudflare gratuito + Node.js ≥ 20.

```bash
git clone https://github.com/leoron04/classeviva-mcp.git
cd classeviva-mcp
npm install
npx wrangler login

# 1. KV per OAuth — copia l'id in wrangler.toml ([[kv_namespaces]])
npx wrangler kv namespace create OAUTH_KV

# 2. Chiave per gli pseudonimi utente (consigliata)
openssl rand -hex 32 | npx wrangler secret put SUBJECT_KEY

# 3. Pubblica
npx wrangler deploy
```

Il connettore sarà `https://classeviva-mcp.<tuo-sottodominio>.workers.dev/mcp`. Opzionale: `PUBLIC_URL` in `wrangler.toml` se usi un dominio personalizzato.

### Variabili e binding

| Nome | Tipo | Descrizione |
|---|---|---|
| `OAUTH_KV` | KV (obbligatorio) | Client, grant e token OAuth (hash + props cifrate) |
| `LOGIN_LIMITER` | Rate limit | 5 tentativi di login/min per IP e username |
| `SUBJECT_KEY` | secret | ≥ 32 caratteri, pseudonimi utente |
| `ALLOWED_USERS` | secret | opzionale: username ClasseViva ammessi, separati da virgola. Se impostato, l'istanza diventa privata |
| `PUBLIC_URL` | var | URL pubblico canonico |
| `CLASSEVIVA_BASE_URL` | var | API alternativa (es. mock locale) |
| `CLASSEVIVA_USER` / `PASS` / `IDENT` / `MCP_SECRET` | secret (legacy) | Solo modalità single-user deprecata |

### Modalità legacy (deprecata)

La v1 esponeva `/mcp/<MCP_SECRET>` con un solo utente nei secret del Worker. Resta disponibile se imposti tutti i secret legacy, altrimenti risponde 404. Preferisci OAuth: verrà rimossa.

---

## Sviluppo locale

```bash
cp .dev.vars.example .dev.vars   # punta al mock Spaggiari
npm install
node test/mock-spaggiari.mjs &   # :9999 — qualsiasi password tranne "wrong"
npm run dev                      # http://localhost:8787
CLASSEVIVA_USER=S1234567X CLASSEVIVA_PASS=prova npm run test:e2e -- http://localhost:8787
```

`test/e2e-oauth.mjs` copre discovery, DCR, login, PKCE, token, refresh, `initialize`, `tools/list` e i tool. Contro un deploy reale usa le tue credenziali da env e **non** stampa dati personali. In CI gira solo contro il mock: `npm run test:local`.

### Struttura

```
src/worker.ts       OAuthProvider (/authorize, /token, /register, /mcp) + legacy
src/authorize.ts    login: CSRF, rate limit, verifica Spaggiari, grant
src/pages.ts        HTML (login, home, errori)
src/mcp.ts          server MCP (Streamable HTTP, stateless)
src/tools.ts        gli 11 tool
src/classeviva.ts   client API + rinnovo sessione
src/clients.ts      cache in-memory delle sessioni
src/legacy.ts       /mcp/<MCP_SECRET> (deprecato)
```

---

## FAQ

**Le mie credenziali finiscono in chat / nel README?** No. Restano cifrate nel grant OAuth; non sono nel codice né nell'URL del connettore.

**Devo aggiornare qualcosa ogni 90 minuti?** No. Il server rinnova da solo la sessione Spaggiari alla richiesta successiva.

**Funziona con ChatGPT / altri client?** Se il client supporta MCP remoto con OAuth 2.1 (PKCE + DCR), sì. È pensato e testato con Claude.

**Posso usarlo per tutta la scuola?** Tecnicamente sì, ma **non** è consigliato sull'istanza pubblica: privacy (GDPR) e ToS Spaggiari. Self-hosta e ottieni il consenso.

**Ho cambiato la password di ClasseViva.** Scollega e ricollega il connettore in Claude.

---

## Disclaimer

Progetto personale open source, **non ufficiale** e **non affiliato** a Gruppo Spaggiari Parma S.p.A. né alle scuole. «ClasseViva» e «Spaggiari» sono marchi dei rispettivi titolari. Usa un'API interna non documentata (la stessa dell'app mobile; la `Z-Dev-ApiKey` nel codice è quella pubblica dell'app, già presente in altri progetti open source) che può cambiare o essere bloccata. L'uso potrebbe non essere conforme ai termini di Spaggiari: usalo **a tuo rischio**, solo con account di cui hai diritto, e solo in lettura. Il software è fornito «così com'è», senza garanzie — vedi [LICENSE](LICENSE).

---

## Credits

- Autore: **Leonardo Ronchi** ([RonchFX](https://github.com/leoron04) / Parallax Studios)
- Librerie: [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk), [Cloudflare workers-oauth-provider](https://github.com/cloudflare/workers-oauth-provider), [Wrangler](https://developers.cloudflare.com/workers/)
- Ispirazione dalle API reverse-engineerate usate da progetti come Classeviva.py (non affiliati)

Segnalazioni di sicurezza: vedi [SECURITY.md](SECURITY.md). Contributi: [CONTRIBUTING.md](CONTRIBUTING.md).

---

## English

**ClasseViva MCP** is an unofficial, open-source remote MCP server that connects the Italian school e-register **ClasseViva (Spaggiari)** to **Claude** (and other OAuth-capable MCP clients). Multi-user: each person signs in with their own credentials on an OAuth 2.1 (PKCE + dynamic client registration) login page. Credentials are **never stored in plaintext** — only inside the grant props, encrypted by `@cloudflare/workers-oauth-provider`. All **11 tools are read-only** (grades with averages, agenda, lessons, absences, noticeboard, notes, subjects, periods, teaching materials, calendar).

- **Quick start in Claude:** Settings → Connectors → Add custom connector → URL `https://classeviva-mcp.ronchfx.workers.dev/mcp`.
- **Self-host:** free Cloudflare Workers plan — create `OAUTH_KV`, set `SUBJECT_KEY`, `wrangler deploy` (see above).
- **Privacy note:** the public instance is for personal / friends use; for other people’s data (esp. minors) self-host and follow GDPR.
- **Disclaimer:** not affiliated with Gruppo Spaggiari Parma S.p.A.; undocumented API may break; use only with accounts you are allowed to access, at your own risk.

License: [MIT](LICENSE) © 2026 Leonardo Ronchi / RonchFX · Parallax Studios