osiris-mcp-server
The server provides tools to query Dutch university Osiris course catalogs, enabling you to browse, search, and retrieve detailed information about courses, minors, and academic programs from institutions like TU/e, TU Delft, Radboud, Twente, and Wageningen.
List reference data: faculties, course types, academic years, categories/levels, blocks, timeslots, units, lecturers, languages, and education types.
Get course structure: see the sections and fields a course can contain.
Search and list courses: perform full-text searches with optional filters (faculty, course type, category, year, etc.) or list courses by faculty and type.
Retrieve course details: get course headers (id, code, name, ECTS, etc.) or full details (content, exams, lecturers, materials) by course code or internal ID.
Explore minors: search for minors (coherent packages/certificates) with filters, and retrieve full minor details by code or ID.
Multi-institution support: override the default institution (TU/e) with a short code (e.g.,
tue,tudelft,rug,ut) on any tool call.
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., "@osiris-mcp-serversearch for courses about machine learning at TU Delft"
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.
osiris-mcp-server
An MCP server exposing Dutch university Osiris course catalogs as tools. It
reads from the public, read-only Osiris Student API that universities publish
at https://<host>.osiris-student.nl/ (e.g. TU/e, TU Delft, Radboud,
Twente, Wageningen).
Quick start
Requires Python 3.11+ and uv.
uv sync
uv run osiris # run the MCP server over stdioThe server targets TU/e (tue) by default and accepts an institution code
per call, e.g. tue, tudelft, rug, ut:
search_courses("4DM00", institution="tudelft")
get_course("4DM00", institution="tue")Related MCP server: University Course Catalog MCP Server
Usage with MCP clients
Add the server to your MCP client configuration.
{
"mcpServers": {
"osiris": {
"command": "uv",
"args": ["run", "--directory", "/path/to/osiris-mcp-server", "osiris"]
}
}
}For clients that support environment variables (e.g. OSIRIS_LANGUAGE,
OSIRIS_TIMEOUT), pass them via the env key.
Tools
Tool | Description |
| Faculties/departments, code + name |
| Course types (Bachelor College, Graduate School, ...) |
| Academic years in the catalog |
| Course categories/levels |
| Period/block tokens (e.g. |
| Timeslots (e.g. |
| Coordinating units (capaciteitsgroep/sectie) |
| Lecturer names |
| Instruction languages |
| Education types (e.g. |
| Sections/fields a course contains |
|
|
| Course header (id, code, name, ECTS, course_type, owner, level, year, blocks) |
| Full detail: content, exams, lecturers, materials, deep link, ... |
| Full detail by internal course id |
| Full-text search with filters |
| Search minors (coherent packages, certificates) |
| Full minor detail: study programme, entrance requirements, ... |
| Full minor detail by internal minor id |
The list_courses and search_courses tools accept the same filters; every
one is optional except faculty for list_courses:
Filter | Description |
| Faculty code (e.g. |
| Course-type code or full name (default |
| Category/level (e.g. |
| Start year ( |
| Block token (e.g. |
| Timeslot code, prefix match (e.g. |
| Coordinating unit (capaciteitsgroep/sectie) |
| Lecturer name |
| Instruction language (name or 2-letter code) |
| Education type (e.g. |
| Only courses with places available ( |
Search results include a blocks list per course with the offering periods:
block token, dates, timeslots, location and availability — plus lecturers,
education_type, faculty and coordinating unit.
search_minors accepts the same year, faculty and education_type filters;
results include startmoments (academic year + block the minor can be started)
and study_programs (degree programmes the minor serves).
Configuration
Variable | Default | Purpose |
| (unset) | Optional search-index header |
| (unset) | Optional search-index header |
|
| Content language ( |
|
| HTTP timeout in seconds |
Most institutions serve a sensible default index without OSIRIS_RELEASE_VERSION
or OSIRIS_MANIFEST. Only set them to pin a specific Elasticsearch index
version (e.g. one extracted from a university's Osiris app bundle).
Development
uv run pytest # unit tests (offline)
uv run pytest -m e2e # live tests against the configured catalog (default TU/e)
uv run ruff check .
uv run ruff format --check .
uv run mypy srcLicense
The code is MIT licensed; see LICENSE.
The course data comes from the relevant university's Osiris API and is owned by that institution. This project is not affiliated with or endorsed by any university, and the MIT license does not cover the underlying course data.
Available Tools
10 toolsget_available_yearsC
List academic years in the catalog.
| Name | Required | Description | Default |
|---|---|---|---|
| institution | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, but it only states 'List academic years in the catalog.' It doesn't mention whether the optional institution parameter affects results, whether the list is ordered (chronological vs reverse), whether it returns only years with available catalog data, or what the output schema contains. The presence of an output schema helps, but behavioral expectations remain underspecified.
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 short sentence with no wasted words. However, it is arguably under-specified rather than genuinely concise - it achieves brevity by omitting useful context rather than by tight editing of informative content.
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?
Despite having an output schema which reduces the burden on the description for return values, the tool has an unused optional parameter, no annotations, and zero schema coverage. The description doesn't clarify the meaning or effect of the institution parameter or how the list is ordered/filtered. For a simple 1-parameter tool this is functional but incomplete.
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 doesn't mention the institution parameter at all. The parameter is optional with a default of null, but the description provides zero guidance on what it does or how it filters the academic years. With a single parameter and no coverage, the description should have explained this.
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 ('List') with a clear resource ('academic years in the catalog'). It clearly distinguishes itself from siblings like get_categories and list_courses by specifying the exact resource being fetched. It could be slightly more specific about the catalog context but is otherwise clear.
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 is provided on when to use this tool versus alternatives. It doesn't mention that this is likely a prerequisite step before querying courses or categories, nor does it contrast with sibling tools. The tool name suggests it feeds into filtered lookups, but this is merely implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_categoriesC
List course categories/levels.
| Name | Required | Description | Default |
|---|---|---|---|
| institution | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does not state whether institution is a filter or free-form, whether results are paginated, what the output structure looks like, or any side effects. Given there's no destructive/write risk here (it's a list operation), the main gap is lack of detail on output contents and filtering 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 exceptionally short (one clause) with zero wasted words. However, this is under-specification rather than genuine conciseness — the brevity comes at the cost of the clarity dimensions. There's nothing unclearly phrased, but there's also almost nothing there.
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?
While the tool has an output schema (which helps) and only 1 optional parameter, the description leaves too much ambiguous: what categories vs levels mean, how institution affects results, and how this relates to the 9 sibling tools exploring the same course domain. For an exploratory/list tool in a crowded sibling space, this level of terseness is inadequate.
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 has 1 optional parameter (institution) with 0% description coverage and no enums. The description fails to explain what institution does — is it a filter, a scoping operand, or optional context? The schema shows it defaults to null, but the description provides zero guidance on how to populate it or what difference it makes to results. With an optional string param, the agent needs to know if it's required for meaningful results.
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 'List course categories/levels' gives a verb+resource but is vague about what 'categories/levels' actually means in this system. With siblings like list_faculties, list_course_types, and get_course_structure, it's unclear how categories/levels differ from course_types or the structure/faculty dimensions. The ambiguity between 'categories' and 'levels' (slash suggests they may be synonyms or distinct concepts) makes the purpose unclear and fails to distinguish from 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?
No guidance is given on when to use this tool vs alternatives like list_course_types or list_faculties. The semantic overlap with list_course_types ('categories' vs 'types') is significant and undocumented. No context about whether this is a top-level navigation call or whether it should be filtered by institution, or what prerequisites apply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_courseB
Get the header for a course code.
Args:
code: course code, e.g. "4DM00".
year: start year or range; most recent offering by default.
institution: institution code (e.g. "tue"); defaults to the configured one.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| year | No | ||
| institution | 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. The description explains default behavior (most recent offering, configured institution) which is valuable, but it doesn't clarify what 'header' means in terms of data returned, whether the operation is read-only, what happens with invalid course codes, or error behavior. The default-value disclosure is helpful but incomplete for a no-annotation 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?
The description is concise and efficient. It front-loads the purpose in the first sentence, then uses a clear Argus-style list for parameters. It's about the right length with minimal waste, though the parameter detail could arguably be tighter.
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 has an output schema (which explains return values), no annotations, and 3 well-documented parameters, the description is reasonably complete. It explains defaults and parameter semantics. The main gap is not clarifying what 'header' means relative to sibling tools, and the tool could benefit from mentioning its relationship to get_course_details and get_course_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 must carry parameter documentation. The description does explain all three parameters: code (with example '4DM00'), year (start year or range, defaults to most recent), and institution (code, defaults to configured one). This adds meaning beyond the schema, which only provides titles and types. However, it could be more detailed about the year range format.
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 this gets 'the header for a course code', specifying the verb (get) and resource (course header). It distinguishes from siblings like get_course_structure, get_course_details, and get_course_details_by_id by focusing on 'header', though it doesn't explicitly differentiate from siblings. The title and name align well with the purpose.
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 useful parameter context (defaults for year and institution) but doesn't explicitly state when to use this vs alternatives. Siblings like get_course_details and get_course_structure exist, and the description doesn't clarify the distinction between 'header' and these other views. There's no when/when-not guidance, though the default behavior for year and institution is helpful context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_detailsB
Get full course details (content, exams, lecturers, materials, ...).
Args:
code: course code, e.g. "4DM00".
institution: institution code (e.g. "tue"); defaults to the configured one.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| institution | 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 full burden. It only states the tool returns details; it doesn't disclose what happens with invalid course codes, the structure of the returned data, error behavior, or whether it performs network/quota operations. An output schema exists, so some return structure is covered, but behavioral aspects remain undisclosed.
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 purpose, followed by the parameter list. Arg documentation is efficient. Minor waste: the trailing ellipsis in the field list is slightly vague but acceptable.
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 a rich sibling set and no annotations, the description omits differentiation guidance and behavioral detail. The output schema exists which off-loads return-value documentation, but the missing sibling/substitution guidance and error/edge-case behavior make this only partially 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?
Expanded schema would have 2 params with inputs documented in code: 'code' gets an example ('4DM00'), and 'institution' is explained (e.g. 'tue') with its default behavior noted. Given 0% schema description coverage, the description compensates well by giving type hints, examples, and defaults.
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+resource ('Get full course details') and enumerates the content (content, exams, lecturers, materials). However, it doesn't distinguish from sibling tools like get_course or get_course_details_by_id, making it somewhat unclear which sibling this replaces or complements.
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 when-to-use guidance or excluded cases are given. With siblings get_course, get_course_details_by_id, and get_course_structure present, the agent gets no help choosing among them. No alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_details_by_idA
Get full course details by internal Osiris course id.
Args:
id: internal course id, as returned by ``list_courses`` or
``search_courses``.
institution: institution code (e.g. "tue"); defaults to the configured one.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| institution | 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. The description does not mention what the 'full course details' include, whether it performs network calls, requires authentication, has rate limits, or what errors occur for invalid ids. Given zero annotation coverage, this is a notable gap for what is likely a data-fetching 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?
The description is efficient, with a one-sentence purpose followed by a compact Args block. Every sentence adds value; the format mirrors standard docstring conventions which are readable and front-loaded. Slight redundancy with the parameter section of the schema is acceptable given the low schema coverage.
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 which presumably covers the return structure, reducing the need to describe return values. The description's blend of purpose and parameter guidance is well-suited for the tool's moderate complexity (2 params, 1 required). The main gap is behavioral (auth/permissions), but otherwise it is reasonably complete for the tool category.
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 does so meaningfully. It explains id as 'internal course id' returned by list_courses/search_courses, and clarifies institution as a code (e.g. 'tue') with a default. This adds real semantic value beyond the bare schema types (integer/string/null).
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 'Get full course details by internal Osiris course id', a clear verb+resource+scope. It distinguishes from siblings like list_courses and search_courses by noting it retrieves full details via the internal id, though it doesn't explicitly name why it differs from get_course/get_course_details.
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 Args section clearly indicates that 'id' should be the value 'as returned by list_courses or search_courses', providing explicit guidance on prerequisite tool usage and how to obtain the identifier. It does not list when-not-to-use or exclusion conditions, but the prerequisite chain is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_structureB
Describe the sections and fields a course can contain.
| Name | Required | Description | Default |
|---|---|---|---|
| institution | 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 disclosure burden. It tells you this returns descriptive/schema information (not actual course data), which is useful context. However, it doesn't state whether the institution parameter affects the returned structure, whether the output is identical for all institutions, or how exhaustive the structure description is.
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 clear sentence with zero wasted words. It front-loads the purpose and is appropriately sized for what appears to be a simple introspection tool.
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?
While the description is short, it has an output schema (which can explain return values) and only one optional parameter. Given the simplicity of the tool, the description adequately covers the core purpose. The main gap is the mysterious institution parameter, but with an output schema present, completeness is reasonably high.
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 has one optional parameter (institution) with 0% description coverage. The description entirely omits what the 'institution' parameter does, which could be relevant—whether the course structure varies by institution. The description adds no parameter-level meaning beyond what the schema provides (which is just name/type).
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 'Describe the sections and fields a course can contain' uses a clear verb (describe) and resource (course sections/fields). It distinguishes reasonably from siblings like list_courses and get_course, which return actual data, while this returns the structural schema of a course.
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 explicit guidance on when to use this versus alternatives. It's implied that you'd call this to understand course structure before calling list_courses/get_course, but this is not stated. No exclusions or alternative tool mentions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_coursesA
List course codes for a faculty and course type.
Args:
faculty: faculty code, e.g. "EE".
course_type: "BC" (Bachelor College) or "GS" (Graduate School).
year: start year ("2025") or range ("2025-2026"); all years by default.
institution: institution code (e.g. "tue"); defaults to the configured one.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | ||
| faculty | Yes | ||
| course_type | No | BC | |
| institution | 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 burden. It's a list/read operation and nothing in the description suggests mutation, which is consistent. However, it doesn't disclose return format or pagination behavior, and the description is essentially just parameter documentation without richer behavioral context.
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 organized in an Args list format that's easy to scan. Every sentence contributes value. Could arguably be slightly tighter, but the parameter examples earn their 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?
There's an output schema present, so return values needn't be explained. With 4 params at 0% schema coverage, the description handles all of them well with examples and defaults. For a straightforward list operation with a present output schema, this is reasonably complete. Given the schema covers the output, the description is adequate for a tool at this complexity.
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 fully compensate. It does this well: each parameter gets an explanatory note with examples (faculty 'EE', course_type 'BC'/'GS', year format '2025-2026'), and enumerates the values for course_type. The default behaviors for year and institution are also documented. This adds real meaning beyond the bare 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 it lists course codes for a faculty and course type, with a specific verb (list) and resource (courses). It distinguishes from siblings like search_courses and get_course by focusing on codes for a faculty+course_type combination. However, it doesn't explicitly contrast with search_courses, so it's not a perfect 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?
The Args section provides implicit guidance on what parameters mean, and the faculty+course_type scoping implies when to use it. However, there's no explicit statement of when NOT to use it versus search_courses or get_course, which are natural alternatives, so guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_course_typesC
List course types (e.g. Bachelor College, Graduate School).
| Name | Required | Description | Default |
|---|---|---|---|
| institution | 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. It does not explain what the returned data looks like, whether results depend on the institution parameter, what happens when institution is null, or whether this is a read-only operation. The description adds minimal behavioral context.
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 efficient sentence that front-loads the main verb and purpose. It's appropriately brief for a tool with a single optional parameter, though the examples are a slightly loose addition.
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 tool is relatively simple (1 optional param, output schema present). The description covers the core purpose but misses guidance on how institution affects results and how this taxonomy relates to get_categories/get_course_structure. Given the sibling overlap, slightly more detail would be warranted.
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 is 0% schema description coverage and only one parameter (institution). The description doesn't explain what 'institution' means or how it filters results, nor what behavior results from null vs provided values. However, with only one parameter and a default of null, the burden is modest.
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 clear verb+resource: 'List course types' with illustrative examples of what constitutes a course type. While it names siblings like list_courses, it doesn't explicitly differentiate from them, though the examples (Bachelor College, Graduate School) provide reasonable clarity on 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?
No guidance on when to use this tool versus alternatives like get_categories, get_course_structure, or list_faculties. The context signals show siblings that overlap thematically (course taxonomy), yet the description provides no when-to-use or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_facultiesC
List faculties (code + name).
| Name | Required | Description | Default |
|---|---|---|---|
| institution | 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. It only states the output is 'code + name' with no mention of ordering, pagination, error behavior, default institution behavior, or whether institution filters or returns all when null.
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 clean, front-loaded sentence with zero waste. It conveys the core purpose efficiently, though it could afford slightly more detail given how short it is.
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?
There is an output schema present, which covers return values. The tool is relatively simple with one optional parameter, but with 0% schema coverage and a poorly documented parameter, the absence of any explanation of the institution semantics leaves a meaningful gap for a fairly fundamental filtering behavior.
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 itself only declares a nullable 'institution' with default null. The description does not explain what the institution parameter filters by, what null means (all institutions?), or the format of the institution value needed. The low coverage means the description should compensate but doesn't.
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?
'List faculties (code + name)' uses a clear verb and resource with output detail. It implies a simple listing tool but doesn't distinguish it from sibling tools like list_courses, get_categories, or get_available_years, though the distinct resource (faculties) provides some differentiation.
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 vs alternatives. The optional 'institution' parameter hints at scoping but there's no explicit when-to-use or when-not-to-use context, nor exclusions or relationship to sibling tools like list_courses which may depend on faculty selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_coursesB
Search courses with optional filters.
Args:
keyword: free-text search on code or name.
faculty: filter by faculty code or full name.
course_type: filter by course-type code or full name.
category: filter by category/level.
year: filter by academic year.
limit: max results (1-100).
offset: pagination offset.
institution: institution code (e.g. "tue"); defaults to the configured one.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | ||
| limit | No | ||
| offset | No | ||
| faculty | No | ||
| keyword | No | ||
| category | No | ||
| course_type | No | ||
| institution | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does not state whether this is a read-only operation, what the pagination behavior returns, result ordering, or how the default institution resolution works. 'defaults to the configured one' adds some context about the institution parameter but little else.
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?
Arg-style list with each parameter on its own line, clear and scannable. Content is directly useful. Slightly verbose per-item phrasing but overall efficient and front-loaded with the purpose statement.
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?
Despite no annotations, the description documents all 8 parameters with semantic detail including format examples and default behavior. It covers pagination via limit/offset. An output schema exists but is not shown, and the description doesn't describe return semantics, which is acceptable given output schema presence. Reasonably complete for a filterable search 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 description coverage is 0%, so the description must fully compensate. It adds meaning beyond the bare parameter names: keyword is 'free-text search on code or name,' faculty accepts 'code or full name,' course_type accepts 'code or full name,' limit encodes value range (1-100), and institution mentions an example ('tue') and default behavior. This is solid semantic enrichment.
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 clear verb (Search) and resource (courses) with optional filters. It lists filter fields explicitly. However, it doesn't differentiate from sibling tools like list_courses or get_course beyond the word 'Search,' leaving some ambiguity about when this vs list_courses 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?
It communicates this is a search with filters but provides no explicit guidance on when to prefer this over siblings like list_courses or get_course. The usage context is implied by 'Search' + filter params, but no exclusions or alternative tool mentions are given.
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.
10 tool updates
v0.1.0- First observed
get_available_years - First observed
get_categories - First observed
get_course - First observed
get_course_details - First observed
get_course_details_by_id - First observed
get_course_structure - First observed
list_course_types - First observed
list_courses - First observed
list_faculties - First observed
search_courses
TDQS
Scored across 10 tools
Most tools are clearly distinct: list/get operations separate by resource (years, categories, faculties, course_types, courses). The main ambiguity is between get_course (header), get_course_details (full details), and get_course_details_by_id (full details by internal id) — get_course_details and get_course_details_by_id return the same data but keyed differently, and get_course's 'header' vs details boundary could cause misselection.
The set follows a consistent get_/list_ verb prefix pattern (get_available_years, get_categories, list_courses, get_course, search_courses). Minor deviations exist: search_courses uses a different verb while other exploration tools use get_/list_, and get_course_details_by_id introduces the '_by_id' suffix that isn't used elsewhere.
Ten tools is within the ideal range for a catalog/query server. Each tool earns a place: three discovery tools (years, categories, faculties/course_types), course listing/search, and course retrieval at different granularities.
The tool surface is strong for a read-only catalog: discovery (faculties, years, course types, categories), search, listing, and multi-level retrieval (header vs full details). The main gap is that get_course_details_by_id is redundant with get_course_by_code — agents could hit dead ends if they don't know which lookup path to use; a by-code variant of full details is also missing from the direct route.
Maintenance
Related MCP Connectors
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Search GitHub, npm, PyPI, StackOverflow, ArXiv from one MCP — built for coding agents.
Find, compare, and audit software for AI agents. Scored registry of tools and MCP servers.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server for querying a university course catalog. Enables searching courses, checking prerequisites, and looking up instructors via natural language.-
- FlicenseNot gradedqualityDmaintenanceMCP server that exposes a university course catalog to LLMs, enabling course search, prerequisite lookup, instructor details, and department directory through natural language.-
- AlicenseNot gradedqualityDmaintenanceEnables querying academic data such as subjects, degrees, locations, and schedules from Universitat Jaume I via MCP tools.MIT
- AlicenseNot gradedqualityAmaintenanceMCP server exposing NTNU course data (search, schedules, grades, semesters) as tools for LLM agents.16 npmMIT