Offer courses and rooms as MCP resources, with two German prompts

A course or room can now be attached to a message rather than fetched:
schulcloud://courses/<id> and schulcloud://rooms/<id> carry exactly what
get_course and get_room return. Deliberately coarse — a picker lists every
resource at once, which suits some twenty courses and not a thousand files.

Two prompts, in German because the school is: zusammenfassung summarises a
course or room, and pruefungsvorbereitung prepares for an exam with practice
questions and a study plan. Each embeds the overview and says where material
hides and what cannot be read.

Claude Code shaped the details, read from its bundle rather than its docs.
It splits prompt arguments on whitespace and drops extra words, so words
arrive joined with "_", and courses match by fragments, whole words first,
so LF1 is not ambiguous with LF10. Its @ autocomplete shows a resource's
description, so the description carries the name. Errors are ProtocolError,
because McpError's message prefix is doubled by the client.

Verified in interactive Claude Code: @-mention, autocomplete and the prompt
commands. 157 tests. Smoke 67/67 live; 69/69 and 67/67 on the local instance.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-09-16 20:19:16 +02:00
parent 3e44e66dde
commit 9d0272c622
13 changed files with 809 additions and 53 deletions

View File

@@ -51,6 +51,23 @@ files and returns **images inline** for Claude to look at. Image-only PDFs —
scans with no text layer, which are common in this account — are reported as
such rather than as an empty result.
**Attach a course instead of asking for it.** Every course and room is also an
MCP resource (`schulcloud://courses/<id>`, `schulcloud://rooms/<id>`) holding
the same overview `get_course` and `get_room` return. In Claude Code, type `@`
and part of the course name.
**Two ready-made prompts**, in German because the school is:
| | |
|---|---|
| `zusammenfassung` *kurs* [*fokus*] | summarise a course or room: topics, tasks, key material, each with its source |
| `pruefungsvorbereitung` *kurs* [*thema*] [*datum*] | prepare for an exam: scope, explanations, practice questions, a study plan |
In Claude Code they run as `/mcp__schulcloud__zusammenfassung Mathe_10b`.
Claude Code splits arguments on spaces and drops extra words, so join words
with `_` (`Lineare_Funktionen`) and skip an optional argument with `-`. *kurs*
is any unambiguous part of a course or room name, or its id.
## The CLI
```bash
@@ -130,7 +147,7 @@ src/
core/ client, types, board assembly, crawler, extraction, paths
store/ Postgres: crawl generations, diffs, full-text search
indexer/ crawl → persist → mirror bytes → extract text → index
mcp/ MCP server and tools
mcp/ MCP server, tools, resources and prompts
http/ express app, bearer auth, /api for the CLI
cli/ CLI config, API client, sync engine
bin/ http, stdio and cli entry points
@@ -157,9 +174,9 @@ npm run typecheck
```
`npm run smoke` starts the HTTP server, connects a real MCP client over
Streamable HTTP and exercises every tool against the live account — 55 checks (57 with the index)
Streamable HTTP and exercises every tool against the live account — 67 checks (69 with the index)
covering the auth gate, the protocol handshake, every content chain, file
extraction, `api_get`'s guard rails and error handling.
extraction, resources and prompts, `api_get`'s guard rails and error handling.
## Upstream