webuntis-mcp
This server gives AI assistants read-only access to a child's WebUntis school data, including timetables, homework, exams, absences, messages, and school info.
Fetch student timetable for any date range (default current week)
Get today's or tomorrow's schedule (tomorrow skips weekends)
Fetch timetable for any class, after listing available classes
List all classes at the school
Get pending homework with due dates
Get upcoming exams and tests
Get registered absences with reasons, status, and notes
Detect timetable changes (cancellations, substitutions, room/teacher swaps)
Get school messages and announcements for a specific date
Get school metadata: period times, holidays, last data import
All tools are read-only; uses TOTP auth; no cloud, no telemetry
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., "@webuntis-mcpWhat's on my child's school schedule tomorrow?"
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.
🏫 webuntis-mcp
MCP server for the WebUntis school platform. Timetables, homework, exams, and absences for parents.
💡 What Is This?
An MCP (Model Context Protocol) server that gives AI assistants read-only access to your child's school data on WebUntis. Works with any school that uses WebUntis, anywhere in Europe.
Ask your AI assistant things like:
"What's on the schedule tomorrow?"
"Are there any cancellations this week?"
"Does my child have homework due?"
"When is the next school holiday?"
All data stays on your machine. No cloud service, no telemetry, no account needed beyond your existing WebUntis parent login.
Related MCP server: schoolsoft-mcp-server
🚀 Quick Start
1️⃣ Install
# With uv (recommended)
uv tool install git+https://github.com/toughIQ/webuntis-mcp.git
# With pip
pip install git+https://github.com/toughIQ/webuntis-mcp.gitGuided Setup (recommended)
Run the setup wizard to find your school, test your credentials, and generate the config:
# Interactive (walks you through each step)
webuntis-mcp setup
# Non-interactive (for scripts and AI agents)
webuntis-mcp setup --school "My School" --username "parent@example.com" --secret "ABCDEF1234567890" --jsonThe setup command searches the public WebUntis school directory, tests your login, resolves your child's name and class, and saves the credentials to ~/.config/webuntis-mcp/config.env (chmod 600).
2️⃣ Get Your QR Code Secret
You'll need this during setup. To find it:
Log in to WebUntis in your browser (e.g.
yourschool.webuntis.com)Go to Profile (bottom left)
Click the "Freigaben" tab (or "Shares" in English)
Click "Zugriff über Untis Mobile" (or "Access via Untis Mobile")
Copy the Schlüssel / Key value (a 16-character code like
ABCDEF1234567890)
3️⃣ Add to Your AI Client
After running webuntis-mcp setup, your credentials are stored in the config file. The MCP entry only needs the command, no env vars:
Claude Code / Claude CLI:
claude mcp add webuntis-mcp webuntis-mcpCursor / Windsurf / Other MCP Clients:
Add to your MCP settings:
{"mcpServers": {"webuntis-mcp": {"command": "webuntis-mcp"}}}See AGENTS.md for detailed instructions per client.
If you prefer not to use the setup wizard, pass credentials as env vars:
{
"mcpServers": {
"webuntis-mcp": {
"command": "webuntis-mcp",
"env": {
"WEBUNTIS_SERVER": "yourschool.webuntis.com",
"WEBUNTIS_SCHOOL": "yourschool",
"WEBUNTIS_USERNAME": "parent@example.com",
"WEBUNTIS_SECRET": "ABCDEF1234567890",
"WEBUNTIS_STUDENT": "kid1"
}
}
}
}You can find all values in the WebUntis QR code dialog (Profile > Freigaben > Untis Mobile).
4️⃣ Verify
Ask your AI assistant: "What's on the school schedule today?"
If it returns a timetable, you're set.
🛠️ Tools
Tool | Description |
| Student timetable for a date range (default: current week) |
| Today's schedule with all details |
| Tomorrow's schedule (skips weekends) |
| Timetable for any class at the school (default: student's own class) |
| List all classes at the school (use with |
| Pending homework assignments with due dates |
| Upcoming exams and tests |
| Registered absences with reason, status, and notes |
| Timetable changes: cancellations, substitutions, room and teacher swaps |
| School messages and announcements for a specific date |
| School metadata: period times, holidays, last data import |
All tools are read-only. No data is modified on WebUntis.
🔑 Authentication
This server uses the 2017 mobile API with per-request TOTP authentication, the same mechanism the official Untis Mobile app uses. Each API call generates a fresh one-time password from your QR code secret.
What this means:
No browser login, no SSO flow, no session management
No password stored (unless you choose to provide one)
Works even if your school uses external SSO (Microsoft, Google, Bildungsportal)
The secret is a static key that doesn't expire until you regenerate it
What you need:
Config Variable | Where to Find It | Example |
| QR code dialog: "Url" field |
|
| QR code dialog: "Schule" field |
|
| QR code dialog: "Benutzer" field |
|
| QR code dialog: "Schlüssel" field |
|
| Your child's first name |
|
If you have multiple children at the same school, WEBUNTIS_STUDENT selects which child's data to show. It matches against the first name.
🔒 Security and Privacy
Credentials never leave your machine. They are passed as environment variables to the MCP process and used only to authenticate with your school's WebUntis server.
No telemetry, no analytics, no cloud. This is a local tool.
Read-only. This server cannot modify any data on WebUntis.
No credentials in the code. Ever. The repository contains zero secrets.
MIT licensed. You can read every line of code.
Store your credentials securely. Environment variables in your MCP client config are readable by the MCP process only. Do not commit them to version control. Do not share your QR code secret.
🐍 Using as a Python Library
The WebUntisClient class works standalone, without MCP. Use it to build your own scripts, notification services, or integrations.
from webuntis_mcp.client import WebUntisClient
client = WebUntisClient(
server="yourschool.webuntis.com",
school="yourschool",
username="parent@example.com",
secret="ABCDEF1234567890",
student="kid1",
)
client.login()
# Get tomorrow's timetable
from datetime import date, timedelta
tomorrow = date.today() + timedelta(days=1)
periods = client.get_timetable(tomorrow, tomorrow)
for p in periods:
print(f"{p.start_time} {p.subject} in {p.room} ({p.teacher})")
# Check for homework
homework = client.get_homework(days_ahead=7)
for hw in homework:
print(f"Due {hw.date_due}: [{hw.subject}] {hw.text[:80]}")
# Check absences
absences = client.get_absences()
for a in absences:
print(f"{a.start_date}: {a.reason} ({a.excuse_status})")
# List all classes and get another class's timetable
klassen = client.get_klassen()
for k in klassen:
print(f"{k.name} ({k.long_name})")
other_class = client.get_class_timetable(class_name="2a", start_date=tomorrow, end_date=tomorrow)
for p in other_class:
print(f"{p.start_time} {p.subject} in {p.room}")
# School info
info = client.get_school_info()
print(f"School: {info.school_name}, Year: {info.school_year}")
print(f"Last data import: {info.last_import}")Use cases for the library:
Build a Telegram or Signal bot that alerts you about schedule changes
Create a dashboard showing the week's timetable
Write a cron job that emails you when homework is assigned
Integrate school data into Home Assistant or other automation platforms
🏗️ Architecture
How It Works
The server authenticates with your school's WebUntis instance using TOTP
It resolves your child's internal student ID from the parent account
Each tool call uses per-request TOTP authentication (same as the official mobile app)
The first call fetches master data (subjects, teachers, rooms, classes) and caches it
Subsequent calls are fast since only timetable data needs to be fetched
API Endpoints Used
All calls go through the 2017 mobile API (/WebUntis/jsonrpc_intern.do), the same endpoint the official Untis Mobile app uses:
getUserData2017, getTimetable2017, getHomeWork2017, getExams2017, getStudentAbsences2017, getMessagesOfDay2017
Parent Account Limitations
WebUntis uses role-based access control. Parent accounts (type 12, "Legal Guardian") have restricted access compared to student or teacher accounts:
Feature | Status | Notes |
Own child's timetable | ✅ Works | Via student ID from login response |
Own child's class timetable | ✅ Works | Includes all groups and subjects |
Any class's timetable | ✅ Works | Use |
Homework | ✅ Works | Via 2017 mobile API |
Exams | ✅ Works | Via 2017 mobile API |
Absences | ✅ Works | Read-only via 2017 mobile API |
Teacher list | ❌ Blocked | Teacher names come from timetable data instead |
Student list | ❌ Blocked | Student ID comes from login response instead |
Substitution list | ❌ Blocked | Changes are visible in timetable period data |
Messages/Announcements | ✅ Works | Via |
What This Server Does NOT Do
No write operations. It cannot create absences, send messages, or modify any data.
No notifications. It provides data on request. Your AI agent or a separate tool handles delivery (Telegram, email, calendar, etc.).
No calendar integration. The agent can read schedule data and use other tools to create calendar events.
🔧 Setup Command
The webuntis-mcp setup command helps you configure the server without editing JSON files manually.
Interactive Mode
webuntis-mcp setupWalks you through:
Searching for your school by name or city
Entering your credentials (username + QR code secret)
Testing the login
Selecting your child (if multiple, shows name and class)
Saving credentials to
~/.config/webuntis-mcp/config.env(asks Y/n, default: save)
Non-Interactive Mode
For scripts and AI agents:
webuntis-mcp setup \
--school "Example School" \
--username "parent@example.com" \
--secret "ABCDEF1234567890" \
--student "kid1" \
--jsonSaves the config file automatically and returns a JSON status object:
{
"status": "ok",
"server": "example.webuntis.com",
"school": "example",
"student": "kid1",
"class": "1A",
"config_file": "~/.config/webuntis-mcp/config.env",
"mcp_config": {
"mcpServers": {
"webuntis-mcp": {
"command": "webuntis-mcp"
}
}
}
}On error, returns {"status": "error", "error": "..."} with a non-zero exit code.
AI agents can run the setup command and then add the simple mcp_config entry to the user's settings. No env vars needed since credentials are in the config file.
❓ FAQ
Q: Does this work with any school? A: Yes, any school that uses WebUntis. The server and school name differ per institution, but the API is the same everywhere.
Q: Do I need a student account? A: No. A parent (legal guardian) account is sufficient for all features this server provides.
Q: Does my school use SSO? Will this still work? A: Yes. The TOTP authentication bypasses SSO entirely. It uses the same mechanism as the official Untis Mobile app.
Q: What if I have multiple children at the same school?
A: Set WEBUNTIS_STUDENT to the first name of the child you want data for. Currently, each MCP instance supports one child. For multiple children, run multiple instances with different configs.
Q: Is my password needed? A: No. The QR code secret (TOTP key) is sufficient for all read operations. Your password is never required.
Q: How often can I query the API? A: WebUntis has rate limiting. Normal usage (a few queries per hour) is fine. Avoid polling more frequently than every 10 minutes.
Q: Can the school see that I'm using this? A: WebUntis logs API access. Your queries appear as Untis Mobile app requests. This is the same as using the official app.
📋 Configuration Reference
The recommended way to configure is webuntis-mcp setup, which creates the config file automatically.
Config file (created by setup): ~/.config/webuntis-mcp/config.env
WEBUNTIS_SERVER=yourschool.webuntis.com
WEBUNTIS_SCHOOL=yourschool
WEBUNTIS_USERNAME=parent@example.com
WEBUNTIS_SECRET=ABCDEF1234567890
WEBUNTIS_STUDENT=kid1All configuration variables:
Variable | Required | Description |
| Yes | WebUntis server hostname (e.g. |
| Yes | School short name as shown in QR code dialog |
| Yes | Your login (usually email address) |
| Yes | 16-character TOTP key from QR code dialog |
| Yes | Child's first name (for student resolution) |
| No | Login password (not needed for read-only, reserved for future write support) |
Environment variables take precedence over the config file. This allows overriding individual values without editing the file.
🙏 Acknowledgments
This project was inspired by and learned from:
BetterUntis by SapuSeven (MIT License). His clean implementation of the 2017 mobile API, per-request TOTP authentication, and masterData caching taught us the modern way to talk to WebUntis. The API patterns, method signatures, and response parsing in our code are directly informed by studying his Kotlin source. No code was copied.
homeassistant-WebUntis by Jonas (MIT License). His work on TOTP authentication for parent accounts and timetable change detection was invaluable during early API exploration.
python-webuntis (BSD License). The original Python WebUntis library, useful as an API reference.
⚖️ Disclaimer
This project is not affiliated with, endorsed by, or connected to Untis GmbH or the WebUntis platform in any way. WebUntis is a registered trademark of Untis GmbH.
This tool accesses the WebUntis API as an end user, using the same authentication mechanism as the official Untis Mobile application. It performs read-only operations with the user's own credentials. Use responsibly and in accordance with your school's acceptable use policies.
Available Tools
11 toolsget_absencesC
Fetch registered absences for the student.
Shows absence records with dates, times, reasons, excuse status, and any notes attached.
Args: start_date: Start date in YYYY-MM-DD format (default: school year start) end_date: End date in YYYY-MM-DD format (default: school year end)
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It describes the return fields (dates, times, reasons, excuse status, notes), which is useful, but doesn't disclose behavior like whether it requires authentication, whether it returns empty vs error for no records, or pagination. No readOnly hint either.
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?
Well-structured: purpose first, then what records contain, then parameter explanations. Concise and front-loaded. The Args block is slightly redundant with the schema but adds format details.
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?
Output schema exists, so return values needn't be explained. The description covers the purpose and parameters adequately, but with zero annotations and no explicit usage context, it leaves some gaps for an agent deciding when and how to call this.
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 by explaining start_date and end_date. It does add the YYYY-MM-DD format and default values (school year start/end), which is valuable. However, with 0% schema coverage, the description could do more to clarify parameter behavior.
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 (Fetch) and resource (registered absences for the student), and elaborates on the record contents. It distinguishes itself reasonably from siblings like get_timetable or get_homework, though it doesn't explicitly contrast with any 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?
No guidance on when to use this tool versus alternatives. It's a straightforward data-fetch tool, but the description doesn't say when absences data is relevant or whether it's scoped to a particular student or all students.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_changesA
Detect timetable changes like cancellations, substitutions, and room swaps.
Filters the timetable for lessons that have been modified from the original schedule.
Args: start_date: Start date in YYYY-MM-DD format (default: today) end_date: End date in YYYY-MM-DD format (default: start + 4 days)
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It does explain the filtering behavior and the default date window (today through start+4 days), which is useful, but it says nothing about permissions, rate limits, or whether results are sorted or paginated.
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?
Front-loaded with the purpose before the filtering detail, and the args block is compact. The 'Filters the timetable...' sentence is mildly redundant with the opening but earns its place by clarifying scope.
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?
An output schema exists, so return values need not be described. For a two-optional-parameter read tool this covers what an agent needs to invoke it; the only gap is the absence of any behavioral caveats that annotations would normally have supplied.
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, and it does: it names both parameters, specifies the YYYY-MM-DD format, and explains the default behavior of each. That is meaningfully more than the bare schema provides.
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 ('Detect') and resource ('timetable changes') and enumerates concrete change types (cancellations, substitutions, room swaps). The phrase 'modified from the original schedule' separates it from get_timetable, so an agent can pick it without opening the sibling schema.
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 conveys when to use it implicitly ('filters the timetable for lessons that have been modified'), but never names an alternative such as get_timetable or get_today, nor states when NOT to use it. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_class_timetableA
Fetch a class timetable. Can show any class at the school, not just the student's own.
Useful for seeing religious instruction, split groups, comparing schedules between classes, or checking a friend's class. Use list_classes to discover available class names.
Args: class_name: Class name like '1a', '2b', '3c' (default: student's own class) start_date: Start date in YYYY-MM-DD format (default: today) end_date: End date in YYYY-MM-DD format (default: start + 4 days)
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | ||
| class_name | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Fetch' plus 'can show any class at the school' conveys read-only scope and that access is not restricted to the student's own class, and the defaults describe fallback behavior. However, it says nothing about permissions, invalid class-name handling, or range limits.
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?
Front-loaded with the core action in the first sentence, then scope, then use cases, then a clean Args block. The 'Useful for...' list is longer than strictly needed but each item maps to a real scenario, so little is wasted.
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?
An output schema exists, so return values need not be explained. All three parameters are covered with formats and defaults, and the discovery path (list_classes) is given. Only error/edge-case behavior is absent, which is a minor gap for a read-only fetch.
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 — and it does, documenting all three parameters with the YYYY-MM-DD format, example class names, and semantic defaults (student's own class, today, start + 4 days). It notably out-documents the schema, whose defaults are empty strings. No constraints on maximum range or invalid input are given.
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 and resource ('Fetch a class timetable') and immediately scopes it against the obvious sibling by noting it 'Can show any class at the school, not just the student's own' — which is the distinction from get_timetable. An agent can pick between the two without opening either schema.
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?
Gives concrete use cases (religious instruction, split groups, comparing schedules, checking a friend's class) and routes to list_classes for discovering valid class names. It does not state an explicit when-not condition or name get_timetable directly as the alternative, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_examsA
Fetch upcoming exams and tests.
Args: days_ahead: Number of days to look ahead (default: 30)
| Name | Required | Description | Default |
|---|---|---|---|
| days_ahead | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. 'Fetch' reasonably implies a read-only retrieval and 'upcoming' adds a time-scoping constraint, but it does not explicitly state read-only safety, permissions, rate limits, or 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?
Very short and front-loaded: the purpose is stated in one sentence, followed by a compact Args section. Every element earns its place with no 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?
An output schema exists, so return values do not need explanation. The description covers the tool's purpose and its one parameter; the main gap is missing usage guidance relative to siblings, but for a simple read tool this is mostly 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?
The single parameter has 0% schema description coverage, so the description must compensate. It explains that days_ahead is the number of days to look ahead and restates the default of 30, which gives adequate semantic meaning for invocation.
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 and resource: 'Fetch upcoming exams and tests.' This clearly distinguishes the content from siblings like get_homework, get_absences, or get_timetable, but it does not explicitly differentiate itself from those alternatives by naming when each should be used.
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 no explicit guidance on when to use this tool versus siblings such as get_timetable, get_today, or get_tomorrow. The days_ahead default is mentioned, but there are no inclusion or exclusion criteria, prerequisites, or alternative-routing hints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_homeworkB
Fetch pending homework assignments.
Returns homework with subject, teacher, description text, and due date.
Args: days_ahead: Number of days to look ahead (default: 14)
| Name | Required | Description | Default |
|---|---|---|---|
| days_ahead | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It conveys that this is a read of pending assignments and lists the return fields, but says nothing about auth requirements, whether completed homework is excluded, or how the window interacts with the pending filter. Adequate but thin for an annotation-free tool.
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?
Short and front-loaded: the one-line purpose leads, followed by return fields and the argument note. The 'Args:' block is slightly verbose for a single optional parameter but wastes little space.
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, return values need not be re-explained, and the sole optional parameter is documented. The only remaining gap is the absence of any safety/permission context for an annotation-free tool, which is minor for a read-only fetch.
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 for the single parameter, and it does: days_ahead is explained as 'Number of days to look ahead (default: 14)'. It adds real meaning beyond the bare integer schema, though it doesn't clarify whether the window filters the pending set or the due-date range.
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 (fetch) and resource (pending homework assignments) and enumerates the returned fields, so the agent knows exactly what it retrieves. It does not, however, distinguish itself from the many sibling read tools (get_exams, get_timetable, get_today), so it stops short of a 5.
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?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives among the siblings. The word 'pending' hints at scope but the description never says when this tool is the right choice versus get_exams or get_timetable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messagesB
Fetch messages of the day from the school.
Returns announcements, notices, and information messages published by the school for a specific date.
Args: target_date: Date in YYYY-MM-DD format (default: today)
| Name | Required | Description | Default |
|---|---|---|---|
| target_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a read-only fetch and discloses the nature of the returned content, but says nothing about authentication, pagination, volume, or whether historical dates are supported. For a simple read tool this is adequate but thin.
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?
Purpose and content are front-loaded in the first two sentences, and the Args block is compact. Slightly redundant phrasing ('messages of the day' followed by a restatement of what is returned), but nothing wasteful enough to impede selection.
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?
An output schema exists, so return-value explanation is not required, and the single parameter is well documented. However, for a tool sitting in a dense sibling cluster, the absence of any disambiguation guidance leaves a real gap an agent must resolve on its own.
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 schema's default is an empty string, so the description does the heavy lifting: it specifies the YYYY-MM-DD format and states the default is today. That fully compensates for the single undocumented parameter, though it does not say what happens on an invalid date.
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 ('Fetch messages of the day from the school') and enumerates the content types returned (announcements, notices, information messages). This makes it distinguishable from siblings like get_homework or get_exams, though it never explicitly contrasts itself with the closest siblings (get_changes, 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?
There is no guidance on when to use this tool versus alternatives. Siblings such as get_changes and get_school_info could plausibly surface overlapping school communications, yet the description offers no routing criteria or exclusions. Usage must be inferred entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_school_infoA
Fetch school metadata including period times, holidays, and last data import.
Useful for understanding the school's schedule structure and upcoming free days.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the returned content categories, which implies a safe read, but says nothing about permissions, caching/refresh behavior, or whether 'last data import' can be stale — context an agent would want for a freshness-sensitive field.
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 short sentences, front-loaded with the resource and its contents, followed by a brief use case. No filler or repetition.
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, return-value detail is not required, and the description covers scope and a use case for a zero-param read tool. Only the lack of any routing guidance relative to the many sibling tools leaves a small gap.
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 takes zero parameters, so the schema has nothing to document and the baseline is 4. No parameter meaning is missing or misrepresented.
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 (Fetch) and resource (school metadata) and enumerates the payload (period times, holidays, last data import). It is distinguishable from siblings like get_timetable or get_today, though it never explicitly contrasts itself with them.
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 second sentence implies usage ('understanding the school's schedule structure and upcoming free days') but gives no when-not conditions and does not point to any alternative sibling for schedule-level vs class-level data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_timetableA
Fetch the student's timetable for a date range.
Returns lessons with subject, room, teacher, and any changes (cancellations, substitutions, room swaps).
Args: start_date: Start date in YYYY-MM-DD format (default: today) end_date: End date in YYYY-MM-DD format (default: start + 4 days)
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. 'Fetch' implies a read-only operation, and the description adds useful detail about returned lesson fields and change types (cancellations, substitutions, room swaps), but it omits permissions, authentication context, and any rate-limit or error 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 front-loaded with purpose and return content, then uses a compact Args section for parameters. Every sentence and argument line adds useful information without 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 definition is adequate for a simple two-parameter read tool and benefits from an output schema, so return values needn't be fully explained. However, with ten sibling tools, the description does not disambiguate from get_today, get_tomorrow, or get_class_timetable, leaving an important selection gap.
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 entirely. It documents both parameters with format (YYYY-MM-DD) and defaults (today; start + 4 days), adding exactly the semantics the schema lacks.
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 a specific verb 'Fetch' and resource 'the student's timetable for a date range,' and it enumerates the returned lesson fields and change types. However, it does not differentiate this tool from siblings like get_today, get_tomorrow, or get_class_timetable, which likely handle narrower or class-specific cases.
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 no explicit guidance on when to use this tool versus alternatives such as get_today, get_tomorrow, or get_class_timetable. The date-range defaults imply a multi-day fetch, but the agent receives no when-to-use or when-not-to-use instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_todayA
Fetch today's schedule with all details.
Shows all lessons for today including any cancellations, substitutions, room changes, and teacher changes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that results include cancellations, substitutions, room changes, and teacher changes, which signals the data is change-annotated rather than a raw timetable. It does not say whether this is purely read-only, whether it needs authentication, or how it relates to get_changes, which also appears to surface changes.
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?
Short and front-loaded, with the core purpose in the first sentence. The second sentence largely restates 'all details' by enumerating change types, which is mild redundancy but still adds specificity.
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?
An output schema exists, so return-value explanation is not required. The description is sufficient for a no-argument read tool, though clarifying its relationship to get_timetable and get_changes would remove the remaining ambiguity.
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 takes no parameters, so there is nothing for the description to disambiguate. Baseline 4 applies for a zero-parameter definition.
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 (fetch) and resource (today's schedule) with a clear temporal scope that an agent can distinguish from get_tomorrow or get_timetable. It does not, however, explicitly articulate how it differs from similar siblings such as get_timetable or get_changes.
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?
Usage is implied by the name and the word 'today', but the description never states when to prefer this over get_timetable, get_changes, or get_tomorrow. No exclusions or prerequisites are given, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tomorrowA
Fetch tomorrow's schedule.
Shows all lessons for the next school day. If tomorrow is a weekend, returns the next Monday's schedule.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It helpfully discloses that weekends return Monday's schedule, but does not mention permissions, side effects, or that the operation is read-only beyond the implied 'Fetch'.
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 front-loaded with the core purpose and includes a useful edge-case note. It is efficient, though the second sentence slightly restates the first before adding the weekend exception.
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 read tool with an output schema, the description is nearly complete. It covers the main behavior and the weekend edge case, with the only minor gap being explicit usage alternatives.
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?
There are zero parameters, so the baseline is 4. The schema is empty and fully described by its name, and the description does not need to add parameter details.
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: fetching tomorrow's schedule. It is clearly different from get_today by focusing on tomorrow, though it does not explicitly name sibling tools for comparison.
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?
Usage is implied by the tool name and the weekend fallback behavior, but there is no explicit guidance on when to use this instead of get_today, get_timetable, or get_class_timetable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_classesA
List all classes at the school for the current school year.
Returns class names that can be used with the get_class_timetable tool to fetch any class's schedule.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose the scope (current school year) and that it returns class names, but says nothing about permissions, pagination, or whether results are exhaustive/cached for a zero-parameter read.
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 short sentences with the purpose front-loaded and the downstream chaining detail second. No filler and no redundancy with the schema.
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?
An output schema exists, so the description needn't document return values, and it correctly stays out of that. For a simple zero-param read tool it is essentially complete, with only minor gaps around freshness and ordering left unstated.
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 takes zero parameters, so the baseline is 4. The description adds nothing parameter-related because there is nothing to disambiguate, and the schema fully covers the empty argument object.
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 and resource ('List all classes'), adds a scope ('current school year'), and clarifies that the output is class names. It points at the downstream sibling get_class_timetable, so an agent can place it in the workflow, though it doesn't contrast itself against the other list-like siblings.
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 second sentence gives a clear use context: the returned class names feed get_class_timetable to fetch a schedule. That is an actionable usage hint, but there are no explicit when-not-to-use conditions or alternatives to this call itself.
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.
11 tool updates
v0.1.0- First observed
get_absences - First observed
get_changes - First observed
get_class_timetable - First observed
get_exams - First observed
get_homework - First observed
get_messages - First observed
get_school_info - First observed
get_timetable - First observed
get_today - First observed
get_tomorrow - First observed
list_classes
TDQS
Scored across 11 tools
get_today and get_tomorrow are essentially convenience wrappers around get_timetable with fixed date ranges, and get_changes overlaps with get_timetable (whose description already promises cancellations/substitutions/room swaps). Descriptions provide useful context, but an agent must still reason about when to prefer the specialized tool over the general one.
Nearly every tool follows the get_<noun> pattern (get_timetable, get_homework, get_exams, etc.), with list_classes as the only variant, which is still a clean verb_noun convention. No mixing of camelCase/snake_case or vague verbs.
11 tools is well-scoped for a school information server, with each covering a distinct data domain (timetable, homework, exams, absences, messages, metadata). No padding or redundancy at the count level.
The surface covers the core student life domains: schedules, classes, homework, exams, absences, messages, and school metadata. Grades/report cards and any write operations (e.g., excusing absences) are absent, but read-only coverage is largely complete.
Maintenance
Related MCP Connectors
GDPR-compliant calendar access for AI assistants: read, create, edit, RSVP. Google, MS 365, Apple.
Your personal data for AI — Telegram, bank, courses, Zoom & more, scoped to you.
- OpenOakOAuthorg.openoak
Secure AI access to OpenOak tasks, notes, and Kanban boards.
Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables accessing IServ school platform features such as timetable, exercises, messenger, and more via natural language, without exposing credentials to agents.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to securely access a guardian's SchoolSoft data—such as schedules, lunch menus, assignments, news, and subjects—using a BankID-authenticated session without exposing credentials.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI clients to access and query WebUntis school data, including timetables, homework, exams, absences, and more via MCP tools.-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to look up daily and weekly Dutch school schedules from student or parent accounts, including first-class drop-off and last-class pick-up times, through natural-language questions.MIT