feat(mcp): add a per-call dry run to every mutating tool #135
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/YT-81-mcp-dry-run"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Every mutating MCP tool now takes
dry_run: trueand reports what it would do without writing anything, the per-call equivalent of the CLI's process-wide--dry-run. The gate lives in the single choke point every tool already funnels through (YouTrackMcpServer::dispatch, formerlyrun_tool): a tool registers as read-only (run_tool), mutating (run_mutation), or mutating-with-its-own-preview (run_previewable_mutation), and the puregatefunction turns the caller's flag plus that policy into run / preview / reject. The preview is a JSON envelope shaped like the CLI's:dry_run,applied, the tool name, and the same redactedLogArgsargument summary the tool-call log records.dry_runon a read-only tool is rejected with an error naming the tool rather than silently ignored, so the mistake surfaces instead of returning a fake preview of a read. That requires every argument type to capture the field, soLogArgs::is_dry_runhas no default body: a new arg type will not compile until it answers.delete_articleanddelete_issue_attachmentget their own argument types so they can advertisedry_runin their schemas while the read-onlyget_article/get_issue_attachmentdo not.The client is resolved before the dry-run branch on purpose: an auth or account-setup failure has to surface as a failure, not be masked by a preview of a call that would never have worked.
apply_commandpreviews differently. A skipped call is a weak preview for the command language, where the dangerous case is a syntactically valid command that means something other than intended. Underdry_runit now posts to/api/commands/assist, YouTrack's own parser, and returns the parsed interpretation plus any parse errors, having applied nothing.yt issue apply --dry-runprints the same parse instead of only skipping the POST. The endpoint is absent from the public REST reference, so its request and response shape is recorded next to the newapi::assist_command, following the convention used for thevcsIntegrationSettingsendpoints.Guards: the router-driven tests assert that all 17 mutating tools advertise
dry_runand that none of the 22 read-only tools do, so adding a mutating tool without a preview fails the suite.#YT-81