Skip to content

✨ WP14: console MCP tool metadata (annotations + parameter descriptions) - #19

Merged
Wuesteon merged 3 commits into
mainfrom
wp14-console-tool-metadata
Aug 6, 2026
Merged

✨ WP14: console MCP tool metadata (annotations + parameter descriptions)#19
Wuesteon merged 3 commits into
mainfrom
wp14-console-tool-metadata

Conversation

@Wuesteon

@Wuesteon Wuesteon commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Closes #13.

Gives the console's MCP wrapper tools the WP13 treatment: honest ToolAnnotations (readOnlyHint/destructiveHint/idempotentHint, openWorldHint=False on all six tools), 100% inputSchema parameter-description coverage (34/34 properties), and when-to-use guidance + sibling cross-references in every description. Contract pinned in console/tests/test_mcp_tool_metadata.py (45 tests, wire-name asserts via model_dump(by_alias=True), holds on both mcp majors).

Structural (behavior-preserving): memory_add/memory_search were defined twice (stdio + HTTP mount) with drift-prone duplicated docstrings; they now register from a shared mcp_tools.register_memory_tools, so surface parity is structural. Handler bodies verbatim; schema-minus-metadata proven identical to main by dump-diff.

Deliberate divergences from core (recorded in the WP14 packet section):

  • memory_search is readOnlyHint=False here — the console wrapper appends a search event row (+ prunes past cap) and creates the namespace store file on first touch; core's search has no event log so its True stays truthful.
  • memory_review_queue carries idempotentHint=True (lazy expiry is idempotent); aligning core is a recorded follow-up.
  • No ge=1 minimums copied from core — that would be a behavior change, out of scope for a metadata packet.

Verification (all run, not assumed):

  • mcp 1.28.1 (console/.venv): 198 passed (153 baseline + 45 new), 0 failures
  • mcp 2.0.0 (scratch venv, editable installs resolving to this branch): 198 passed, 0 skips
  • Live stdio wire check on BOTH majors: real subprocess server + mcp.client.stdio session, list_tools verified annotations + full description coverage
  • Core untouched: git diff main --stat -- src/ tests/ bench/ empty; core suite 319 passed
  • Glama precondition (WP14: console MCP tool metadata (annotations + parameter descriptions) #13): lean-memory-console is NOT independently listed (Glama keys on the GitHub repo, both packages ship from one repo) — packet done anyway as hygiene/parity; recorded

🤖 Generated with Claude Code

https://claude.ai/code/session_01B1GNoTx3qTPrb8GQcxooWj

Wuesteon and others added 3 commits August 6, 2026 22:27
The console half of core's WP13 contract (tests/test_mcp_tool_metadata.py),
written first and RED: 41 of 45 fail against main.

Enumerates the console wrapper tools dynamically from BOTH surfaces — the
stdio server the plugin runs (observe_mcp.build_mcp) and the Docker HTTP mount
(routes.mcp._build_http_mcp) — so a future tool cannot ship without metadata,
and asserts per surface:

* ToolAnnotations declared, expected readOnly/destructive/idempotent hints,
  openWorldHint False everywhere (local SQLite is a closed world). Read via
  model_dump(by_alias=True) so the camelCase wire names hold on BOTH mcp
  majors (1.x fields are camelCase; 2.0 renamed them snake_case with
  camelCase aliases).
* 100% inputSchema parameter-description coverage.
* A "Use ..." when-to-use sentence in every description, namespace defined as
  an isolation key wherever it appears, siblings cross-referenced, and the
  non-obvious side effects disclosed (extraction, supersession, the console
  event log, lazy proposal expiry).
* Surface parity extended from names/signatures (§6.3) to descriptions,
  inputSchema and annotations — the two surfaces must send identical metadata.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B1GNoTx3qTPrb8GQcxooWj
Gives the console's six wrapper tools the treatment core got in WP13
(v0.2.3): honest ToolAnnotations, a described parameter on every schema
property (34/34 across both surfaces), and a when-to-use sentence plus
sibling cross-references in every description. This is all a directory
(Glama) or an agent ever sees of a tool.

memory_add + memory_search move into mcp_tools.register_memory_tools, the
module that already owns the four maintenance tools, and both surfaces
register from there. Previously each surface defined them separately with
diverging one-line docstrings ("observing wrapper" / "HTTP wrapper"); shared
registration makes §6.3 parity structural instead of aspirational — metadata
cannot drift because there is one definition.

Annotations chosen per tool (openWorldHint=False on all six — every call
touches only local SQLite under the console data root):

* memory_add — readOnly False, destructive False (ADD-only spine: writes
  supersede, never erase), idempotent False (each call writes new facts).
* memory_search — readOnly True: it never adds, supersedes or deletes a fact.
  It does append one observability row to the console event log, which the
  description discloses.
* memory_maintenance_run — readOnly False (apply=True claims the lease and
  writes), destructive False, idempotent False.
* memory_maintenance_status — readOnly True: a pure model-free ledger read.
* memory_review_queue — readOnly False: listing lazily EXPIRES overdue
  proposals, which is a write. destructive False.
* memory_review_decide — readOnly False, destructive False (approvals
  supersede rather than erase), idempotent False.

Metadata only: tool names, parameters, handler bodies and return payloads are
unchanged, and the generated inputSchema is structurally identical to main
(diffed with descriptions stripped) — no k/limit minimums were added, unlike
WP13.

Console 198 passed (153 baseline + 45 new); core 319 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B1GNoTx3qTPrb8GQcxooWj
… tools (WP14 review)

Review findings on the WP14 metadata work.

CRITICAL — `memory_search` claimed `readOnlyHint=True` while the console
wrapper writes. MCP's `readOnlyHint` means "does not modify its ENVIRONMENT",
and `gateway.search()` unconditionally appends a 'search' row to `_events.db`
(pruning past CAP=10 000) and creates the namespace store file on first touch.
Clients use the hint to auto-approve calls without confirmation, so a false
True is the worst-case direction — and the branch already applied the correct
standard to `memory_review_queue` ("listing lazily EXPIRES overdue proposals").
Now `readOnlyHint=False` / `destructiveHint=False` / `idempotentHint=False`,
with the docstring leading with the write instead of "read-only with respect to
memory". One standard, no telemetry carve-out; core's `memory_search` stays
`True` because core has no event log.

IMPORTANT — restored the WP13 first-call model-download disclosure, dropped in
the console port. `ConsoleConfig.models` defaults to "auto" and `_build_memory`
upgrades to SentenceTransformerEmbedder/CrossEncoderReranker whenever
`sentence_transformers` imports, and that embedder is lazy — so on a
`lean-memory[models]` install the first `memory_add`/`memory_search` blocks for
minutes on a ~1.2 GB download with nothing in the tool metadata saying so.

Minors: scoped the module docstring's metadata-parity claim to the console's two
surfaces (descriptions deliberately diverge from core's); `idempotentHint=True`
on `memory_review_queue` (expiry is idempotent — a re-poll is safe); moved the
orphaned annotation-baseline comment above the first `@mcp.tool`; de-duplicated
the superset paragraph, leaving observe_mcp.py as its one home.

Contract test pins all of it: EXPECTED_HINTS updated, the "read-only" assert
replaced with "never adds, supersedes or deletes" + "not read-only", and the
core `download` assert ported. Both new asserts verified to fail when the fix is
reverted.

Recorded in the WP14 packet row: the two deliberate core divergences, the
skipped `ge=1` on k/limit (metadata-only — a minimum would reject `k=0`), and
the dual-major evidence.

Console suite: 198 passed on mcp 1.28.1, 198 passed on a scratch venv pinned to
mcp==2.0.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B1GNoTx3qTPrb8GQcxooWj
@Wuesteon
Wuesteon merged commit 9586b59 into main Aug 6, 2026
6 checks passed
@Wuesteon
Wuesteon deleted the wp14-console-tool-metadata branch August 6, 2026 15:04
Wuesteon added a commit that referenced this pull request Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WP14: console MCP tool metadata (annotations + parameter descriptions)

1 participant