Atlas Scolaire
by DanyVilela
README.md
# Atlas Scolaire — MCP server
2025 brevet and baccalauréat results for the 10,098 collèges and lycées of France
métropolitaine, served to AI assistants over the Model Context Protocol — with one
rule built into every response: **a school's success index never travels without its
social intake (IPS), the intake's spread, and the ministry's value-added.** Read
alone, the success index measures who a school admits more than what it does.
The data comes from [atlas-scolaire.fr](https://atlas-scolaire.fr), which joins six
open datasets — five published by the French education ministry, plus the Base adresse
nationale — under Licence Ouverte 2.0.
## Connect
- **Endpoint:** `https://mcp.atlas-scolaire.fr/mcp` (Streamable HTTP, no authentication)
- **Claude.ai / Claude Desktop:** Settings → Connectors → Add custom connector, then paste the endpoint.
- **Claude Code:** `claude mcp add --transport http atlas-scolaire https://mcp.atlas-scolaire.fr/mcp`
## Tools
| Tool | What it returns |
|---|---|
| `search_schools` | Identities only (UAI, name, commune, page): many schools share a name. |
| `get_school` | One school, results (each with its national percentile) with intake and value-added. |
| `compare_schools` | 2–5 schools in the order given, no computed winner. |
| `schools_in_area` | A commune or département, 25 per page (`page`), ranked by success index within each exam by default; `sort` also takes `value_added` (results net of the intake) or `name`. Filters: type, sector, `exam` (only schools with a published result for it, and the exam the ranking uses), teaching options. |
| `schools_near` | Schools near an address or a point, nearest first by default, 25 per page; `sort` also takes `success_index`, `value_added` or `name`. Same filters. |
| `similar_intake_schools` | Schools of the same type with a comparable IPS, nearest first, up to 10. |
| `area_overview` | Area aggregates, each result median paired with its median IPS. |
A response that holds several schools states the reading note (`how_to_read`) and the
attribution once, at its top level; `get_school` carries both on its single record.
Plus two resources (`atlas://methodology`, `atlas://sources`) and one prompt
(`choose_a_school`).
Lists can be ordered by results, as the site's own tables are, one exam at a time: a
list ordered by success index or value-added gives each school its `rank` among the
schools ranked on the same exam (`ranked_on`) — ranks restart for each exam, and no rank
compares a brevet with a bac, or one bac with another — and every exam carries the
school's national `success_index_percentile`. What never happens is a
result travelling alone: every ranked school carries its IPS, the IPS standard
deviation and its value-added in the same record.
## Evaluation
A pilot comparing four conditions (no tools, web, web + a naive server with the same data, web + this server) is written up in [`evals/RESULTS.md`](evals/RESULTS.md), with the plan in [`evals/PLAN.md`](evals/PLAN.md).
## Data and licence
Data: [`/donnees/etablissements.v1.json`](https://atlas-scolaire.fr/donnees/etablissements.v1.json),
Licence Ouverte 2.0 — the six sources are listed at
[atlas-scolaire.fr/#sources](https://atlas-scolaire.fr/#sources). Code: MIT.
## Development
```bash
npm install
npm test # unit tests over a hand-built fixture: no data file, no network
LIVE=1 npm test # also downloads and indexes the live data file
npm run check # tsc
npm run fetch-data # download the data file into data/ (git-ignored)
npm run dev # fetch-data, then wrangler dev on http://localhost:8787/mcp
npm run deploy # fetch-data, then wrangler deploy
```
The data file is not fetched at request time: `npm run fetch-data` downloads it, checks
its version, and wrangler bundles it into the Worker, which builds its index once at
start-up. **A data refresh on the site therefore reaches this server only through a
redeploy** — `npm run deploy` downloads the current file first.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues