A comprehensive educational series demonstrating MCP (Model Context Protocol) development across 7 phases: foundations, primitives, bidirectional communication, stateless transports, authentication, extensions, and production hardening.
Strong pedagogical server with 21 well-named tools across 4 phases. Tool names follow verb_noun convention (add, create, update, delete, search, view, checkout). All tools have descriptions (avg ~120 chars, within 10-1024 baseline). Input schemas present with typed parameters and descriptions. However, output schemas are not documented in the source code provided, only input schemas are visible. Error handling is present but recovery guidance is sparse. Tool annotations (readOnlyHint, destructiveHint) are declared in the Risk field but not visible in actual schema definitions. Composition is excellent: tools chain well (e.g., create_note → update_note → delete_note; create_basket → add_item → checkout). Stateless-core pattern is well-executed across phases.
Add two integers. The simplest possible side-effect-free tool.
Add `qty` of `sku` to the basket named by `basket_id`. Rehydrates from the shared store (so any instance can serve this), merges the line, writes it back.
Add an item to a previously opened basket, identified by its handle.
Finalize a basket: mark it checked_out and return a receipt. Once checked out, the basket cannot be modified.
Count to n, emitting progress + log messages back to the client.
Open a new, empty basket and return its handle. The returned `basket_id` is the application handle. The model must keep it and pass it back on every subsequent call — it is the ONLY link between this call and the next, and (crucially) it works no matter which instance serves the next call. There is no session, no cookie, no Mcp-Session-Id.
Output schemas not documented in source code. Only input schemas are visible; return types and response structures are not declared in tool definitions.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) declared in Risk field but not visible in actual schema definitions. Should be present in tool registration for LLM optimization.
Error recovery guidance sparse. Tools like update_note and remove_item mention error conditions but do not provide actionable recovery steps for LLMs.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Create a note and return it (including its server-minted id). The id is an explicit handle — the stateless-core pattern from Phase 0. Pass it back to `note://{id}` resources or to update/delete tools.
Delete a note by handle. No-op (still ok) if it doesn't exist.
Use the host's LLM to draft text, ask the user to approve/edit it, then save. Demonstrates sampling + elicitation in sequence.
Return a personalized greeting. Resources are addressed by URI, not called like functions -- the client fetches them by resolving the template.
Generate a greeting instruction in a chosen style.
Create a basket and return its handle. Store NOTHING on the connection.
Remove a SKU entirely from the basket. Errors if the basket is unknown.
Save a document to the workspace. Demonstrates server->client elicitation (asking the user to choose a root and confirm overwrite).
Save a document to the real filesystem under a granted root. Demonstrates elicitation + roots together, with actual file I/O.
Search notes by substring in title/body, optionally filtered by tag. Returns structured results (query, count, hits) so the caller gets machine-readable data, not just prose.
Use the host's LLM to summarize a note. Demonstrates server->client sampling (the server asks the host to run its model).
Update a note's title and/or body, identified by its handle. Raises if `note_id` is unknown — surfaced to the client as an error *result* (is_error=True), not a transport failure, so the model can recover.
Fetch a basket by handle and return its current state.
List the roots (folders) the client granted us, and how many documents we have saved. Demonstrates server->client roots/list request.
Return the server instance's identity: instance_id, store backend, and stateless_http flag.
where_can_i_work has vague naming and description. Does not clearly convey that it lists granted roots and document counts. Consider rename to list_granted_roots or describe_workspace.
Deprecated Roots pattern used in Phase 2 (save_document, save_to_disk, where_can_i_work, draft_and_save). Roots were removed in 2026-07-28 spec. Migrate to file/dir parameters or resource URIs.