edupage-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@edupage-mcpWhat homework and exams does my daughter have this week?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
edupage-mcp
An MCP server that lets an agent read a family's school life from EduPage, the school system used across Slovakia, Czechia and beyond: timetables with substitutions, homework and exams, grades, messages from teachers, notices, absences, school events and the canteen menu. It can also send a message to a teacher and order or cancel school meals.
EduPage has no public API, so this builds on the community
edupage-api library, which logs in
the way the website does. One login covers every child and every school on a
parent account; the schools are discovered automatically.
Tools
Tool | Input | Output |
| — | Account type, every school (subdomain, school year, email) and every student with class and school |
|
| Per student: today's lessons, homework and exams due soon, recent messages and notices, last week's grades, today's lunch |
|
| Lessons by day: period, times, subject, teachers, room, group, |
|
| Homework and announced exams by due date, with subject, teacher, details, attachments, done state |
|
| Messages and chats, newest first, replies nested, attachments, read-receipt requests |
|
| The whole timeline: grades, homework, events, absences, payments, sign-up forms, substitutions... |
|
| Marks with weight, points, class average, teacher; per-subject weighted averages |
|
| Absences with periods and excused state, excuse notes, day totals |
|
| Trips, exams, school events, holidays and days off |
|
| The substitution plan for the student's class (or the whole school) and missing teachers |
|
| Canteen menus per meal with dishes, allergens and portions; what is ordered; deadlines; credit |
|
| Bell schedule, school email, the student's class teachers and home room |
|
| Teachers with the |
|
| Sends a new message to one or more teachers |
|
| Orders, changes or cancels a canteen meal before the deadline |
|
| Finishes a login that EduPage wanted a second factor for |
✏️ changes something in EduPage. Set EDUPAGE_READ_ONLY=true to remove these
two tools entirely.
student is a first name, full name, student ID or school subdomain, matched
without regard to case or accents; it can be left out when the account has a
single student. Dates are YYYY-MM-DD, or today, tomorrow, yesterday.
Related MCP server: Edupage MCP Server
Setup
1. Install and configure
You need uv; it fetches Python 3.12+ for you if necessary.
git clone https://github.com/frizzy/edupage-mcp.git
cd edupage-mcp
cp .env.example .env # then fill it in
uv syncVariable | Required | Default | Purpose |
| yes | — | The username you sign in to EduPage with (usually an email) |
| yes | — | Your EduPage password |
| no | discovered | Comma-separated schools, e.g. |
| no |
| IANA timezone that "today" is judged in |
| no |
|
|
| no | — | Keep sessions in this file (mode 600) so a two-factor login survives restarts |
| no |
| How old a session may get before it is refreshed |
| no |
| Seconds to wait for EduPage |
Without EDUPAGE_SUBDOMAINS, the server logs in through
portal.edupage.org and then finds every school a parent account belongs to.
Set it if your account only works at one school's address, or to limit the
agent to some of your schools.
2. Verify the login
set -a && source .env && set +a
uv run edupage-mcp --checkThis logs in, prints what the account reaches and exits, so problems surface before you wire anything up:
OK: logged in as you@example.com (parent account)
Timezone: Europe/Bratislava
2 school(s):
- myschool https://myschool.edupage.org 2026/2027
- otherschool https://otherschool.edupage.org 2026/2027
2 student(s):
- Jana Nováková class IV.A at myschool
- Peter Novák class I.A at otherschoolIf EduPage asks for a second factor, --check waits for you to approve the
login in the EduPage app (or to type the emailed code).
3. Register with the agent
By default the server speaks MCP over stdio, run on the same machine as the
client (to host it on another machine, see
Running on a Raspberry Pi). Replace
/path/to/edupage-mcp with the directory you cloned into. For Claude Code:
claude mcp add edupage \
--env EDUPAGE_USERNAME=you@example.com \
--env EDUPAGE_PASSWORD=your-edupage-password \
-- uv --directory /path/to/edupage-mcp run edupage-mcpOr, as raw config for any host that takes the standard mcpServers shape:
{
"mcpServers": {
"edupage": {
"command": "uv",
"args": ["--directory", "/path/to/edupage-mcp", "run", "edupage-mcp"],
"env": {
"EDUPAGE_USERNAME": "you@example.com",
"EDUPAGE_PASSWORD": "your-edupage-password"
}
}
}
}Then ask things like "What does Jana have tomorrow, and is any homework due?", "Summarise this week's messages from school in English" or "Did anyone get a grade today?".
Hermes Agent
Hermes Agent reads MCP servers from
mcp_servers in ~/.hermes/config.yaml. It gives a stdio server only the
environment variables listed under its env, so the credentials have to be
listed there. Keep the values themselves in ~/.hermes/.env:
# ~/.hermes/.env
EDUPAGE_USERNAME=you@example.com
EDUPAGE_PASSWORD=your-edupage-passwordThen add one of these to ~/.hermes/config.yaml.
From a local checkout (if Hermes can't find uv, use the full path that
command -v uv prints):
mcp_servers:
edupage:
command: "uv"
args: ["--directory", "/path/to/edupage-mcp", "run", "edupage-mcp"]
env:
EDUPAGE_USERNAME: "${EDUPAGE_USERNAME}"
EDUPAGE_PASSWORD: "${EDUPAGE_PASSWORD}"With Docker, and nothing to install:
mcp_servers:
edupage:
command: "docker"
args: ["run", "-i", "--rm", "-e", "EDUPAGE_USERNAME", "-e", "EDUPAGE_PASSWORD",
"ghcr.io/frizzy/edupage-mcp:latest"]
env:
EDUPAGE_USERNAME: "${EDUPAGE_USERNAME}"
EDUPAGE_PASSWORD: "${EDUPAGE_PASSWORD}"Over HTTP, to an always-on server (the Pi service
or Docker Compose), with EDUPAGE_MCP_TOKEN=<token>
added to ~/.hermes/.env:
mcp_servers:
edupage:
url: "http://127.0.0.1:8766/mcp"
headers:
Authorization: "Bearer ${EDUPAGE_MCP_TOKEN}"Check the connection with hermes mcp test edupage; it should list sixteen
tools (fourteen when read-only). Then run /reload-mcp in an open chat, or
start a new one. The tools show up as mcp__edupage__get_briefing and so on.
A daily cron job that calls get_briefing replaces a hand-written summary
script.
To give the agent read access only, set EDUPAGE_READ_ONLY: "true" under
env (or in the service's env file); the two write tools then disappear.
Running with Docker
A multi-arch image (amd64 and arm64, so a Raspberry Pi works too) is published
as ghcr.io/frizzy/edupage-mcp. To build it yourself instead, run
docker build -t edupage-mcp . in a checkout and use that name below.
Check your credentials first, using a .env file filled in from
.env.example:
docker run --rm -it --env-file .env ghcr.io/frizzy/edupage-mcp --checkAs a stdio server
The agent starts a fresh container for each session and talks to it over
stdin/stdout, so -i is required. A bare -e NAME forwards that variable from
the agent's own environment, which keeps the password out of the command line.
For Claude Code:
claude mcp add edupage \
--env EDUPAGE_USERNAME=you@example.com \
--env EDUPAGE_PASSWORD=your-edupage-password \
-- docker run -i --rm -e EDUPAGE_USERNAME -e EDUPAGE_PASSWORD ghcr.io/frizzy/edupage-mcpAlways on, over HTTP
docker-compose.yml runs the streamable-HTTP server with
a restart policy, a health check, a read-only filesystem and a small volume
for cached sessions:
cp .env.example .env # fill in your credentials
echo "MCP_AUTH_TOKEN=$(openssl rand -hex 32)" >> .env
docker compose up -dIt listens on http://127.0.0.1:8766/mcp on this machine only. Connect with the
header Authorization: Bearer <MCP_AUTH_TOKEN>, just as for the
Pi service. To open it to your network, change
the port mapping to "8766:8766"; the security notes for the Pi apply. Use
docker compose logs -f for logs, and
docker compose pull && docker compose up -d to update.
Running on a Raspberry Pi
The same server can run as an always-on service on a Pi (or any systemd Linux
box), speaking MCP's streamable-HTTP transport and guarded by a bearer token.
By default it listens on 127.0.0.1 only, for an agent harness running on the
Pi itself; --lan opens it to your home network or Tailscale instead. It uses
port 8766, so it can run alongside
icloud-calendar-mcp on 8765.
Requirements on the Pi: 64-bit Raspberry Pi OS (Bookworm or later),
SSH access from your machine, rsync, and uv:
ssh pi@raspberrypi.local 'curl -LsSf https://astral.sh/uv/install.sh | sh'Deploy from this directory on your machine:
deploy/deploy.sh pi@raspberrypi.local # agent on the Pi itself
deploy/deploy.sh --lan pi@raspberrypi.local # clients elsewhere on the networkThat copies the project to ~/edupage-mcp on the Pi (never .git or .env)
and runs deploy/install.sh there, which:
installs the dependencies into a local
.venvwithuv sync --frozen;on the first run, creates
/etc/edupage-mcp.env(root-only, mode 600) from your local.env— sent once and then deleted on the Pi — or by prompting if you have none, and generates a randomMCP_AUTH_TOKEN;checks the EduPage login with
--check;installs and starts a hardened
edupage-mcpsystemd service on port 8766, with sessions cached in/var/lib/edupage-mcp, and prints the URL and token to give your agent.
Run the same command again to deploy an update; the configuration is kept.
--lan only matters on the first install; to switch afterwards, change
MCP_HOST in the env file (127.0.0.1 or 0.0.0.0) and restart.
Connect the agent. Any MCP client that supports streamable HTTP needs two
things: the URL http://127.0.0.1:8766/mcp (or http://raspberrypi.local:8766/mcp
with --lan) and the header Authorization: Bearer <token>. For Claude Code:
claude mcp add --transport http edupage http://127.0.0.1:8766/mcp \
--header "Authorization: Bearer <token>"For clients that only launch local commands (such as Claude Desktop's
mcpServers config), bridge with
mcp-remote:
{
"mcpServers": {
"edupage": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://raspberrypi.local:8766/mcp", "--allow-http",
"--header", "Authorization:Bearer <token>"]
}
}
}Day to day, on the Pi:
Task | Command |
Logs |
|
Status |
|
Change settings or rotate the token |
|
Health check (no token needed) |
|
Uninstall |
|
Security notes. The token guards your EduPage account: anyone holding it
can read your children's grades, messages and absences, and (unless
read-only) send messages as you. On the default localhost bind nothing off the
Pi can connect, and the token keeps other local processes out. With --lan,
traffic is plain HTTP, so keep it on a network you trust or on Tailscale
(which encrypts it); don't port-forward it to the internet. To listen only on
the tailnet, set MCP_HOST to the Pi's Tailscale IP. MCP_ALLOWED_HOSTS
optionally restricts accepted Host headers as a DNS-rebinding defence. The
server refuses to bind beyond loopback without a token of at least 32
characters.
You can also run HTTP mode by hand anywhere:
MCP_AUTH_TOKEN=$(openssl rand -hex 32) uv run edupage-mcp --transport http --host 0.0.0.0Two-factor login
If the account has two-factor authentication on, a login pauses until it is
confirmed. The tool that triggered it returns an error saying so; approve the
login in the EduPage app and have the agent call complete_login, or tell the
agent the code EduPage emailed and it passes it as code. --check does the
same interactively.
Sessions are refreshed in place rather than by logging in again, so a
confirmed login keeps working while the server runs. Set
EDUPAGE_SESSION_FILE (the Pi service and Docker Compose do) to keep it
across restarts too.
How it works
Sessions. Each school is a separate EduPage session. The server logs in on first use, refreshes a session older than
EDUPAGE_SESSION_TTL_MINUTES, and retries a failed read once with a fresh session. Writes are never retried, so a message is never sent twice.Several children. A parent's timeline mixes every child at a school. Items addressed only to another child (their class, their courses) are filtered out, and the session is switched to the right child before reading grades or the canteen.
Where the data comes from. Timetables come from EduPage's timetable service, one request for the whole range. Messages, notices, homework, events and absences come from the timeline, fetched fresh (and cached for a minute so
get_briefingdoesn't repeat itself). Grades and substitutions come fromedupage-api; the canteen from the menu page.Times. EduPage stores school-local times without an offset; they come back as ISO 8601 in
EDUPAGE_TIMEZONE.Language. EduPage content is whatever the school wrote, usually Slovak or Czech. Field names are in English; the agent can translate the rest.
Every tool returns {"status": "error", "error": "..."} rather than raising, so
the agent can read the problem and correct itself: missing credentials, a
rejected password or a captcha, an ambiguous student or teacher name (with the
choices listed), a date it cannot read, a meal past its deadline.
Limitations
get_absencesis built from the absence and excuse notices on the timeline, not EduPage's attendance page, so it can miss entries a school records without a notice.get_eventslists events that were announced on the timeline; EduPage's full calendar can hold more.Replying inside an existing message thread, excusing an absence, signing forms and uploading attachments are not supported yet.
send_messageandorder_mealfollow the requests the EduPage web app makes; canteens differ, so check the result in the app the first time.EduPage can change its pages at any time. Anything that stops parsing shows up as a tool error rather than wrong data.
Development
uv run pytestThe suite uses a fake Edupage object and invented JSON shaped like
EduPage's, so nothing touches the network. It covers configuration, school
discovery, student and teacher name matching, sibling filtering, session retry
and two-factor login, the session cache, every parser (timetable, timeline,
homework, events, absences, meals, grades), the service logic behind each
tool, the MCP tool schemas and read-only mode, and the HTTP bearer-token
middleware.
Layout
src/edupage_mcp/
server.py MCP tool definitions and CLI entry point
service.py What each tool does: filtering, windows, summaries
client.py EduPage sessions, school discovery, the raw requests
parsing.py EduPage JSON -> plain dicts
http_app.py Streamable-HTTP transport with bearer-token auth
config.py Environment configuration
Dockerfile Container image (stdio by default)
docker-compose.yml Always-on HTTP server in Docker
deploy/
deploy.sh Copy to a Pi over SSH and install/update there
install.sh Install or update the systemd service (runs on the Pi)
edupage-mcp.service systemd unit templateEdupageService is importable on its own if you want the EduPage logic
without the MCP layer.
License
MIT. Not affiliated with EduPage or asc Applied Software Consultants.
Available Tools
16 toolscomplete_loginComplete two-factor loginA
Finish an EduPage login that asked for a second factor. After the user approves the login in the EduPage app, call this with no code; if EduPage emailed a code instead, pass it as code. school is only needed if several schools are waiting.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | ||
| school | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explains the behavioral nuance of the two-factor process: the tool can complete the login either via user approval (no code) or via email code (with code), and the optionality of 'school' based on multiple pending schools. This goes beyond just saying 'complete login' and gives the agent critical operational context. However, since no annotations are provided, the description carries the burden, and it does not disclose what happens after completion (e.g., whether it sets a session, returns tokens, or requires prior state), so a 4 is appropriate rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, three sentences, with no wasted words. It front-loads the main purpose and then provides conditional guidance in a logical order. Every sentence earns its place, covering the essential usage scenarios without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (a two-step authentication flow) and the absence of annotations, the description covers the essential usage scenarios and parameter semantics. However, it does not mention what the output schema looks like or what the tool returns (though an output schema exists, so the description doesn't need to explain that). It also doesn't mention error cases (e.g., invalid code, no pending login), but for a well-scoped tool with clear parameters, this is a minor gap. A 4 is justified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning the schema only provides types and defaults (nullable strings) with no semantic meaning. The description fully compensates by explaining the meaning of 'code' (the emailed code vs. null when approved) and 'school' (needed if multiple schools are waiting). This is essential for correct invocation, so the description provides high value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: completing a two-factor login for EduPage. It uses a specific verb ('Finish') and identifies the resource ('EduPage login'), and it distinguishes the tool from siblings—all siblings are read-only or content operations, whereas this is an authentication step, so there is no confusion about which tool to use.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: after the user approves the login, call with no 'code'; if a code was emailed, pass it as 'code'. It also clarifies when 'school' is needed (only if several schools are waiting), which gives clear context for parameter usage and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_absencesGet absencesARead-only
Absences recorded for a student since since (default the start of the school year): each absence with the affected periods and whether it is excused, plus excuse notes and reminders, with totals of days absent and days not yet excused.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ||
| student | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds value by detailing what the response includes (periods, excused status, notes, reminders, totals) and the default behavior of the `since` parameter, which goes beyond the schema. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, but it packs several details into a moderate length. It is reasonably front-loaded, stating the main purpose before diving into nuances. Could be slightly more succinct, but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not spell out every return field, so it is adequate for a read-only query with optional parameters. It covers the essential semantics and defaults, though it does not mention edge cases like empty results. Overall complete enough for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the `since` parameter's default (start of school year) and implies that `student` refers to the student whose absences are queried. However, it does not elaborate on the format or optionality of `student`, leaving some ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool retrieves absences for a student, and lists the key elements (periods, excused status, notes, reminders, totals). It is immediately distinguishable from siblings like get_grades or get_timetable because it is specifically about absences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that this tool is used when you need absence records, but it offers no explicit guidance on when to use this tool versus alternatives such as get_briefing or other query tools. There is no mention of exclusions or preferred alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountGet account overviewARead-only
Who is on this EduPage login: the account type (parent or student), every school it reaches (subdomain, school year, email) and every student with their class and school. Call this first to learn the names to pass as student to the other tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only nature is covered. The description adds useful behavioral context by detailing what information is returned and emphasizing that this is the initial discovery step for other tools.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundant wording. It front-loads the core purpose and then provides essential usage guidance, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with annotations and an output schema, the description is fully sufficient. It explains what the tool returns, why it should be called first, and how the results relate to other tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter semantics to document. The baseline of 4 applies, and the description appropriately focuses on the tool's output and usage rather than parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: it identifies the account type, schools, and students associated with the EduPage login. It also distinguishes itself from sibling tools by explaining that it provides the names needed for other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Call this first' and explains that it is used to learn the student names to pass to other tools. This gives clear, actionable guidance on when to use the tool, even without listing alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_briefingGet daily briefingARead-only
One-call overview for every student (or just student): today's lessons with changes and cancellations, homework and exams due in the next days_ahead days (default 3), messages and notices from the last two days, grades from the last week, and today's canteen menu. Sections that fail are listed under warnings instead of failing the whole call.
| Name | Required | Description | Default |
|---|---|---|---|
| student | No | ||
| days_ahead | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses important behavior: sections that fail are collected under `warnings` rather than failing the whole call, and each data category has a specific time window (last two days, last week, next days_ahead). This gives the agent a clear model of partial-failure tolerance and data scoping.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense, single-sentence overview followed by a one-sentence behavioral note. Every listed item earns its place by defining the scope of the briefing, and the core purpose is front-loaded. It remains readable despite enumerating six distinct data categories.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter aggregate tool with an output schema, the description covers the input scope, parameter defaults, data windows, and partial-failure behavior. The main omissions – the exact `student` identifier format and explicit routing to more specific siblings – are minor given the output schema likely documents the return structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden and does so well: it explains `student` as an optional scope ('for every student (or just `student`)') and `days_ahead` with its default and meaning ('due in the next `days_ahead` days'). The only gap is that the expected format of `student` (ID, name, etc.) is unspecified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource ('briefing') and frames it as a 'one-call overview', then enumerates exactly which data categories it returns: lessons, homework/exams, messages/notices, grades, and canteen menu. By positioning itself as an aggregate, it implicitly distinguishes itself from the sibling get_* tools even without naming one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies an aggregate use case ('one-call overview') and shows the agent this is the tool to use for a consolidated daily snapshot. However, it never explicitly states when to prefer this over get_timetable, get_grades, or get_meals, nor does it give any when-not-to-use guidance. Alternatives are left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_eventsGet school eventsARead-only
School calendar events for a student between start_date (default today) and end_date (default 30 days later): exams, trips, excursions, school events, parents' evenings, holidays and days off, as announced on the timeline, with the subject, teachers and classes involved.
| Name | Required | Description | Default |
|---|---|---|---|
| student | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true and openWorldHint=true, and the description aligns: it's a read-only operation. The description adds context about the data source ('as announced on the timeline') and the scope of event types, which is not captured in annotations. It doesn't mention pagination or partial results, but the description's detail about event categories helps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, but it's dense. It front-loads the primary concept (school calendar events) and then lists specific event types. It doesn't waste words, though the sentence is somewhat long. The information about timeline and involved parties is useful, so the length is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only retrieval tool with no required parameters and a good output schema (implied by 'has output schema: true'), the description is fairly complete. It covers the date range logic, event categories, and included details (subject, teachers, classes). The main gap is the 'student' parameter semantics, but since the tool is likely used in a context where the student is implied, this is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only explains start_date and end_date defaults (today and +30 days). It doesn't clarify the optional 'student' parameter – how the student is identified (an ID? name?) or whether defaulting to null implies the current student. The description fails to compensate for the low schema coverage, leaving two of three parameters under-documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: retrieving school calendar events (exams, trips, holidays, etc.) for a student within a date range. The specific verb 'get' and resource 'school events' are unambiguous. It distinguishes itself from siblings like get_timetable and get_homework by focusing exclusively on calendar events as announced on the timeline.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: when a user asks about school events, exams, or holidays between dates. It doesn't explicitly state when not to use it or mention alternatives like get_timetable (for schedule) or get_substitutions (for changes). However, the event type list provides some context that this is for broader events rather than daily schedules.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gradesGet gradesARead-only
A student's marks for the current term, newest first, with a per-subject summary (count and weighted average). Marks run 1 (best) to 5; points and percentage marks include max_points and percent. Filter with subject (name or abbreviation) and since. For an earlier term pass school_year (the starting year, e.g. 2025 for 2025/26) and term (1 or 2).
| Name | Required | Description | Default |
|---|---|---|---|
| term | No | ||
| since | No | ||
| student | No | ||
| subject | No | ||
| school_year | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and openWorldHint, but the description adds valuable behavioral context: it specifies the ordering (newest first), the grading scale (1 to 5), the presence of max_points and percent for point/percentage marks, and the per-subject summary. It also explains the term/school_year relationship. This goes well beyond what annotations provide and fully discloses the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded: it starts with the primary purpose and ordering, then details the grading scale, filters, and term selection. Every sentence adds value without redundancy. It is well-structured for quick agent comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description need not explain return values. It covers the core functionality, ordering, filtering, and term handling. The main gap is the unexplained 'student' parameter and the unspecified format of 'since'. These are notable but not critical for a read-only tool, making it fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden of explaining parameters. It explains subject (name or abbreviation), since (as a filter), school_year (starting year), and term (1 or 2) in the context of earlier terms. However, it does not explain the 'student' parameter at all, and the format of 'since' is not specified. It covers most parameters well but misses one and leaves some format details ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: returning a student's marks for the current term, newest first, with a per-subject summary. It distinguishes itself from sibling get_* tools by being specifically about grades, and it details the grading scale and output fields. This is a specific verb+resource with clear scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when to use the parameters: it explains that the current term is default and that passing school_year and term fetches an earlier term. It also mentions filtering by subject and since, but it does not explicitly contrast with alternatives like get_homework or get_absences. The usage guidance is strong but lacks explicit sibling differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_homeworkGet homework and examsARead-only
Homework and announced exams (tests, quizzes, oral exams) due between start_date (default today) and end_date (default two weeks later), sorted by due date. kind filters to 'homework' or 'exam' (default 'all'). Items marked done in EduPage are left out unless include_done is true. Each item has the subject, teacher, title, details, due date and any attachments.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | all | |
| student | No | ||
| end_date | No | ||
| start_date | No | ||
| include_done | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses specific behavioral traits beyond the readOnlyHint and openWorldHint annotations: items marked done are excluded unless include_done is true, and each item includes certain fields. This gives agents precise expectations of results and side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the primary purpose and default date range, then compactly covers filters and output. No unnecessary words; every clause adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and five optional parameters, the description adequately covers defaults, filtering behavior, and return contents. The missing context is the 'student' parameter's purpose, which could affect correct usage in multi-student accounts.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though the schema description coverage signal is 0%, the description provides meaningful semantics for start_date, end_date, kind, and include_done, including defaults and filtering effects. The only unresolved parameter is 'student', which is left unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the resource (homework and announced exams), the date range filtering with explicit defaults, and the output format. It distinguishes from sibling tools like get_timetable and get_events by focusing specifically on homework/exam items and their metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on when to use the tool (for homework and exam items due in a date range) and explains default behavior and filters. However, it does not explicitly mention alternatives or exclusions (e.g., when to use get_timetable instead), so it falls short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mealsGet canteen menuARead-only
The school canteen menu for date (default today) and the following days days (1-14), per meal (breakfast, snack, lunch, ...): each menu option with its dishes, allergens and portion sizes, whether a meal is ordered and which menu, the order/cancel deadlines, and the remaining meal credit.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ||
| days | No | ||
| student | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description does not need to repeat that. It adds domain-specific detail such as order/cancel deadlines and remaining meal credit, but otherwise does not go beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence that front-loads the date/days scope before listing the return contents. There is no filler, though the comma-separated field enumeration makes it slightly heavy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Because an output schema exists, the description does not need to explain return values in depth, and it does cover many query semantics. Still, the missing `student` parameter and lack of explicit linkage to order_meal leave the definition incomplete for fully autonomous use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description must carry the parameter documentation burden. It explains `date` and `days` well, including defaults and the 1-14 range, but completely omits the `student` parameter, leaving the agent unable to know how to select a specific student.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (school canteen menu) and the retrieval verb, then enumerates the returned fields: dishes, allergens, portion sizes, order status, deadlines, and meal credit. This makes it clearly distinct from siblings such as order_meal and get_school_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description communicates when to call it by scoping date and days, including the default and valid range. However, it does not explicitly state when to prefer get_meals over alternatives, particularly the sibling order_meal, nor does it provide exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messagesGet messagesARead-only
Messages from teachers and the school (and chats) since since (default 14 days ago), newest first, with replies nested under the message they answer. Each has the author, who it was addressed to (a class, parents of a class, the whole school, or you), the full text, attachments, and confirmation_requested when the sender asked for a read receipt. search filters by text, author or recipient (accent-insensitive).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| search | No | ||
| student | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool read-only and open-world, and the description adds substantial behavioral detail: default time window, newest-first ordering, nested replies, per-message fields, recipient types, and accent-insensitive search. This goes well beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences front-load the core resource and default behavior, then add ordering, nesting, fields, and search semantics. Every sentence contributes useful information with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is thorough for a read-only list tool, especially with an output schema present. It covers defaults, ordering, nesting, fields, and search behavior. The only notable gaps are the undocumented `limit` and `student` parameters, which keep it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains `since` and `search` with meaningful detail, but it does not describe `limit` or `student`. The two documented parameters are handled well, but half the parameters remain unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource ('messages from teachers and the school (and chats)') and the operation (retrieval with filtering and reply nesting). It is specific enough to distinguish from siblings like get_notifications, though it does not explicitly name or contrast a sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by describing its content and filters, but it never explicitly states when to prefer it over get_notifications or send_message, nor does it give exclusions. Usage context is clear but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_notificationsGet notificationsARead-only
Everything on the student's EduPage timeline since since (default 7 days ago), newest first: messages, homework, grades, events, absences, payments, sign-up forms, substitutions and more. Filter with types, using the returned type or type_code values, e.g. ['grade', 'payments_published', 'enrollment']. EduPage's own tips and bookkeeping entries are hidden unless include_system is true. search matches text, author or recipient.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| types | No | ||
| search | No | ||
| student | No | ||
| include_system | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to restate safety. It adds valuable behavioral context: default time window (7 days), ordering (newest first), hidden system entries unless include_system, and search scope. It does not mention pagination or rate limits, but for a read-only feed with an output schema, this is sufficient. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense paragraph that front-loads the core purpose, then adds filtering details, then search. Every sentence adds value, with no filler. It is concise yet comprehensive, and the structure logically flows from what the tool does to how to customize it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (so return structure is documented elsewhere), the description covers the main usage aspects: default time range, type filtering, system inclusion, and search behavior. It lacks explicit pagination or handling of large result sets, and 'student' is ambiguous. However, for a read-only feed with a rich output schema, it is largely complete. The description could mention that results are limited by 'limit' or how to retrieve older items, but it's adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It explains 'since' (default 7 days ago), 'types' (filter using returned type/type_code values with examples), 'search' (matches text, author or recipient), and 'include_system' (shows hidden EduPage tips/bookkeeping). It does not explain 'limit' or 'student', though 'student' is implied in the context of a student's timeline. This is good coverage, but missing two parameters keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns 'Everything on the student's EduPage timeline' with a specific verb (get/list), a resource (notifications/feed), and a time scope ('since', newest first). It lists the kinds of items included (messages, homework, grades, etc.), which distinguishes it from sibling tools like get_grades or get_messages that are specialized. This makes the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear guidance on when to use the tool: to retrieve a combined timeline of all notification types. It explains how to filter with 'types' using returned values, how to include system entries with 'include_system', and that 'search' matches text, author, or recipient. It does not explicitly mention alternatives or when not to use it, but the contrast with specialized siblings is implied by calling it 'everything... and more'. This is strong guidance, though a brief mention of 'use specialized tools for single-type queries' would elevate it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_school_infoGet school infoARead-only
Facts about a school (by subdomain or a student's name): the bell schedule with each period's start and end, the school's email, each student's class with its class teachers and home classroom, and how many teachers, classes, subjects and rooms it has.
| Name | Required | Description | Default |
|---|---|---|---|
| school | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the read-only nature is covered. The description adds valuable behavioral context by specifying the input forms (subdomain or student's name) and the breadth of returned facts, going beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that efficiently packs a list of facts, front-loading the core purpose. It is informative without redundancy, though slightly long due to the enumeration; still, every element earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's scope and parameter usage, and an output schema exists to document return values. It lacks explicit mention of any limitations or prerequisites (e.g., whether student name requires a specific format), but overall it is sufficiently complete for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides zero description for the 'school' parameter (0% coverage), so the description's mention of 'by subdomain or a student's name' is essential. It clarifies the parameter's meaning but leaves ambiguity about the exact format (e.g., whether it's a URL subdomain or a plain string), preventing a perfect score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Facts about a school' and enumerates the exact data returned (bell schedule, email, student class info, counts). It clearly distinguishes from sibling tools like get_timetable or get_grades, which are specialized, making this the aggregator for school-level facts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for school-wide information but does not explicitly state when to prefer this tool over more specific siblings (e.g., 'use get_timetable for period details'). There is no exclusion or alternative guidance, so an agent must infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_substitutionsGet substitutionsARead-only
The school's substitution plan for date (default today): lessons cancelled, moved or taught by someone else, and which teachers are away. Pass a student to see only their class, or a school subdomain (or all_classes: true) for the whole school.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ||
| student | No | ||
| all_classes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so there is no contradiction; the description adds useful scoping behavior (student/whole-school filtering, default date). It does not go deeper into authorization or other operational constraints, but the read-only context lowers the bar, so this is adequate rather than exceptional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, with the core function and default behavior stated first and filter instructions second. Every word adds information, and no irrelevant details are included.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, zero-required-parameter lookup with an output schema, the description covers what is returned and how to scope it. The only notable gap is the unexplained 'school subdomain' reference, but the rest is sufficient for an agent to call the tool successfully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Because schema property descriptions are absent (0% coverage), the description must explain parameters, and it does explain date, student, and all_classes. However, it mentions passing a 'school subdomain' even though the schema exposes no such parameter, which is ambiguous and could lead an agent to invent an unsupported argument.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact resource (the school's substitution plan) and enumerates its contents (cancelled, moved, or substitute-taught lessons and absent teachers), which is specific enough to distinguish it from siblings like get_timetable or get_absences.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains scope options: pass a student for only their class or set all_classes for the whole school, and notes that the date defaults to today. It does not explicitly contrast with sibling tools, but the resource is distinct enough that an agent can infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_timetableGet timetableARead-only
A student's lessons for date (default today) and the following days days (1-31, default 1), grouped by day. Each lesson has its period, start and end time, subject, teachers, classroom and group. Substitutions show the original lesson with cancelled: true next to its replacement with changed: true. homework_ids link a lesson to entries from get_homework. Weekends and holidays have no entries.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ||
| days | No | ||
| student | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnly/openWorld annotations by explaining default values, day grouping, lesson fields, substitution representation with `cancelled: true` and `changed: true`, `homework_ids` linkage, and empty behavior on weekends/holidays. This gives the agent a thorough behavioral model without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, starting with the core function and default behavior, then enumerating returned lesson fields and special cases. Every sentence adds distinct value, with no repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema exists, so return-value details are not required. The description covers grouping, field contents, substitution semantics, homework linkage, and empty-day behavior. The only meaningful gap is the undocumented `student` parameter, which leaves a small but real ambiguity for agents deciding whether to provide it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It does explain `date` (default today) and `days` (1-31, default 1), but it does not clarify the `student` parameter, such as what format it expects or whether it defaults to the current user. Two of three parameters are well covered, but the omission prevents a higher score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: retrieving a student's lessons for a date range, grouped by day. It distinguishes itself from siblings by explaining how substitutions are represented inline and how lessons link to `get_homework`, making its scope evident even without naming alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to get a student's timetable over a date range, with defaults and behavior on weekends/holidays. It does not explicitly state when not to use it or name alternatives like `get_substitutions`, but the substitution-handling description implicitly clarifies its role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_teachersList teachersARead-only
Teachers at a school (by subdomain or a student's name), optionally filtered by query (part of a name, or the abbreviation used in the timetable). Each has a recipient_id for send_message.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| school | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only and open-world aspects, lowering the bar for the description. The description adds useful behavioral context: query matches name fragments or timetable abbreviations, and results expose a recipient_id. It doesn't mention pagination or auth, but for a simple read-only list with an output schema, this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The core function and scope come first, followed by filter semantics, then the actionable recipient_id link. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, filtering, and the send_message use case, and an output schema exists so return values are documented elsewhere. The only notable gap is that school is optional in the schema while the description implies a school context is needed, which could confuse an agent deciding whether to omit it. Overall this is nearly complete for a read-only list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema property descriptions are 0%, so the description carries the burden of explaining parameters. It defines query as 'part of a name, or the abbreviation used in the timetable' and the 'by subdomain or a student's name' parenthetical gives meaning to the school parameter. The phrasing is slightly ambiguous about school, but both parameters receive substantive semantic grounding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Teachers at a school'), adds scope detail ('by subdomain or a student's name'), and explains the query filter. It also ties the tool to send_message via recipient_id, which distinguishes it from the sibling getters. This is far above a bare 'List teachers' tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The recipient_id note gives a clear downstream use case: call this before send_message when you need a teacher recipient. It doesn't explicitly name alternatives or exclusions, but since this is the only teacher-listing tool among siblings, the routing context is strong enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
order_mealOrder or cancel a mealADestructiveIdempotent
Choose a menu for a student's canteen meal on date, or cancel it. meal is 'lunch' (default), 'breakfast', 'snack', ... as returned by get_meals; menu is one of that meal's choosable_menus (e.g. 'A', 'B') or 'cancel'. Only works before the canteen's deadline. Confirm the day and choice with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | ||
| meal | No | lunch | |
| menu | Yes | ||
| student | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description supplements the annotations with useful behavioral facts: it can cancel a meal, is time-limited by the canteen deadline, and requires user confirmation. It does not contradict the annotations, though it could clarify the effect of re-ordering on an existing meal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core behavior, followed by parameter guidance and safety constraints. Every sentence adds value, with no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a basic self-service order: it covers the operation, parameter sources, deadline, and confirmation. However, it leaves out `student` parameter semantics and date format, which are meaningful gaps for correctly invoking the tool in multi-student scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description carries the parameter-documentation burden. It explains `date`, `meal`, and `menu` well, including defaults and allowed sources, but it never describes the `student` parameter or its null/string semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Choose a menu for a student's canteen meal on `date`, or cancel it') with a clear resource and scope. It also differentiates the tool from siblings like `get_meals` by emphasizing the order-or-cancel mutation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage context: it works only before the canteen deadline, and the agent must confirm the day and choice with the user first. It also tells the agent where valid values come from (`get_meals`), which is strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend messageA
Send a new EduPage message from this account to one or more teachers at a school (by subdomain or a student's name). recipients are teacher names or recipient_ids from list_teachers; a name must match exactly one teacher. The message cannot be unsent: confirm the recipients and text with the user before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| school | No | ||
| recipients | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly=false, and the description adds important behavioral detail: the message cannot be unsent, and the agent must confirm recipients and text with the user before calling. It also discloses the exact-match requirement for teacher names, going beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with the core action front-loaded and no filler. The phrase 'by subdomain or a student's name' is slightly dense and ambiguous, but every sentence earns its place and the structure is scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and annotations available, the description covers the essential invocation details: recipient resolution, optional school handling, and irreversibility. It does not describe error behavior or invalid-recipient handling, but those are not strictly needed for a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does well for recipients (teacher names or IDs from list_teachers, requiring exactly one match), but school is only obliquely covered via 'by subdomain or a student's name,' and text receives no added semantics beyond being the message body. Compensation is partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Send'), a specific resource ('new EduPage message'), and the recipient scope ('one or more teachers at a school'). This clearly distinguishes it from the sibling read-only tools such as get_messages and list_teachers, so an agent can identify the correct tool from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear usage context: it is the send action from the current account, appropriate for messaging teachers, and it explains how to resolve recipients via list_teachers. It does not explicitly state when not to use it or name an alternative, but the sibling set makes the choice obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
16 tool updates
v0.1.0- First observed
complete_login - First observed
get_absences - First observed
get_account - First observed
get_briefing - First observed
get_events - First observed
get_grades - First observed
get_homework - First observed
get_meals - First observed
get_messages - First observed
get_notifications - First observed
get_school_info - First observed
get_substitutions - First observed
get_timetable - First observed
list_teachers - First observed
order_meal - First observed
send_message
TDQS
Scored across 16 tools
Every tool targets a distinct EduPage resource or action, and the descriptions clearly separate overlapping areas like get_messages vs. get_notifications and get_timetable vs. get_substitutions. An agent should be able to select the right tool without confusion.
Tool names almost universally follow a snake_case verb_noun pattern, with get_* for reads and imperative verbs like send_, order_, and complete_ for actions. list_teachers is a conventional collection-naming exception rather than an inconsistency.
At 16 tools, the surface is just above the ideal 3-15 range, but the EduPage domain is genuinely broad and each tool covers a meaningful module. The count feels comprehensive rather than bloated.
The set covers nearly every core student/parent workflow: timetable, homework, messages, grades, absences, meals, events, substitutions, school info, and login. A few smaller capabilities are missing, such as toggling homework completion or detailed payment actions, but the main workflows have no dead ends.
Maintenance
Related MCP Connectors
EduPage MCP: timetables, grades, homework, meals, messages, 2FA, multi-school, role-aware.
Messaging tools for AI agents: send messages, manage chats, groups and channels.
Manage an EasyWeek business from AI: bookings, availability, customers, services, orders, messaging.
Email inboxes and calendars for AI agents: send, receive, search, draft and schedule.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceAI learning assistant for families. Manages game time rewards based on school grades, homework, and bonus tasks. Syncs with EduPage/PRONOTE. 78 MCP tools with instruction workflows.1-
- AlicenseAqualityFmaintenanceMCP server that connects Claude to Edupage, a school information system used across Europe. Provides access to timetables, grades, homework, messages, students, teachers, and more.251GPL 3.0
- FlicenseBqualityBmaintenanceEnables parents and students to interact with the Edookit school portal through MCP, including viewing grades, assignments, timetables, attendance, messages, payments, and more, as well as submitting absence excuses and sending messages.21-
- FlicenseNot gradedqualityBmaintenanceConnects AI agents to the École Directe API to access grades, homework, timetables, school life, messages, and documents.-