feat(mcp): add resummarize_meeting tool - #589
Conversation
Wraps `minutes resummarize --json` as an MCP tool: preview-first (model invocation disclosed), apply writes with backup + automatic derived-view refresh, --ingest only with apply, and sensitivity: restricted refused unless include_restricted (logged override). Recovers the CLI's structured failure envelope from stdout on non-zero exit. Regenerates the MCP tool catalogs and manifest for the new 37-tool count (and corrects the long-standing 7→8 resource count on the same line).
a3064bc to
fd37628
Compare
silverstein
left a comment
There was a problem hiding this comment.
Approved. This completes the resummarize arc (CLI in #526, derived-view invalidation in #573, MCP tool here), and the security posture is right.
Verified independently, not taken on trust:
- Build clean, vitest 72/72.
- mcp_tools_test.mjs: 12/12. Worth noting for anyone reading later, a fresh worktree shows 4 failures purely because there is no built CLI binary at target/debug/minutes (ENOENT plus empty-JSON parses). Pointing the harness at a real binary gives a clean 12/12, and main gives 10/10 on the same harness, so the delta is exactly your 2 new checks.
- Guards read correctly in the handler: validatePathInDirectory against the effective meetings dir, restricted refusal, ingest gated to apply, and preview disclosing that the model is invoked.
The detail I want to call out as the right call: the restricted check parses frontmatter and refuses before invoking the CLI. That means a restricted meeting never has derived content sent to a model without an explicit, logged override, rather than refusing after the fact. Same for declining fuzzy search-term resolution. An agent passing a near-miss string that silently resummarizes the wrong meeting, at model cost, is exactly the failure mode worth designing out.
On your caveat about search_indexed not being in the --json derived_views payload: inferring from the absence of the 'search index:' warning prefix is a reasonable read of what derived.rs emits, and preferring a real boolean if one appears is the right hedge. A tiny CLI follow-up to add the field explicitly would be welcome whenever you feel like it, no rush.
Also appreciate that you ran an adversarial review on your own diff first and listed what it caught, including correcting the pre-existing resource miscount you happened to touch. Merging.
Three merged features in three days on your own roadmap. Thank you.
|
Thanks! Almost done with the full implementation plan:
So the Tauri button is the last substantial piece, but |
What
Adds the MCP
resummarize_meetingtool — the follow-up to #526 (resummarize CLI) and #573 (derived-view invalidation) that was scoped as a separate PR in the #523 discussion. MCP clients can now re-run the AI pass on an edited meeting/memo, preview-first, with apply inheriting backup creation and automatic derived-view refresh from the core path.Design decisions
validatePathInDirectory, same asget_meeting/ingest_meeting).sensitivity: restrictedrefused unlessinclude_restricted: true. Preview output is derived from the transcript, so the tool refuses before invoking the CLI, mirroringget_meeting's stub-and-logged-override posture.--ingestonly honored withapply. The knowledge log is append-only; the flag is inert in preview and the response says so instead of passing it through.process_audio) rather than a job — the jobs queue is audio-specific, and the CLI runs resummarize inline.runMinutesnow preserves both streams on the thrown error so the tool can surfacestage+errorrather than just the stderr text. Verified against a live resolve failure.One caveat worth knowing
The CLI's
--jsonderived_viewsblock doesn't include asearch_indexedfield (only the human output has it), so the tool infers search-refresh success from the absence of a"search index:"warning — the exact prefixderived.rsemits. It prefers a real boolean if one ever appears in the JSON. Happy to add the field to the CLI payload in a tiny follow-up if you'd rather have it explicit; I kept this PR TypeScript-only.Review process
An independent adversarial model review of the diff found 1 Major + 2 Minor, all fixed before this PR: the envelope-recovery gap above (confirmed empirically — the structured error was unrecoverable from the thrown message alone), test names that overstated what they assert (renamed; this harness has no MCP protocol client, so registration/schema/guard are checked against the built server and the shared validator), and a pre-existing "7 resources" miscount in the manifest's long_description (corrected to 8 on the same line the tool-count bump touches).
Testing
npm run buildclean; vitest 72/72;mcp_tools_test.mjs12/12 (2 new checks)npm --prefix site run check:llmsandsync_site_release_version.mjs --checkboth green (37 tools; catalogs, manifest, and release constants regenerated together)