feat(mcp): add hook management tools to the MCP server#156
Conversation
There was a problem hiding this comment.
Pull request overview
Adds hook visibility and (local-only) hook management to the SproutGit MCP server so external agents can list effective hooks, inspect hook-run audit history, and (when mutating tools are enabled) create/update/delete/toggle local hooks and trigger a hook run via the same execution path as the app UI.
Changes:
- Extend shared types with hook-run audit-log records and a structured hook-run outcome.
- Add MCP tools for listing hooks and hook runs, and for local hook CRUD + run_hook (all mutating actions gated by
mutatingToolsEnabled()). - Bridge MCP tool handlers to the existing main-process hook/DB code paths and add test coverage.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/types/src/hooks.ts | Adds HookRunRecord (audit log row) and HookRunOutcome (run result) types consumed by MCP/app code. |
| packages/mcp-server/src/tools.ts | Registers new hook tools and implements MCP handlers (read + gated write/run). |
| packages/mcp-server/src/context.ts | Extends McpServerContext with hook read/write/run functions. |
| packages/mcp-server/src/tests/tools.test.ts | Updates test context shape to include hook functions (throws by default). |
| packages/mcp-server/src/tests/http-server.test.ts | Verifies the new tools appear in the MCP tool list. |
| docs/agent-instructions.md | Documents the MCP server tool surface, including hook tools and trust boundary. |
| app/src/main/mcp-bridge.ts | Wires MCP context hook functions to existing IPC/main-process implementations. |
| app/src/main/ipc/workspace.ts | Adds listHookRuns() for reading hook-run audit log via workspace DB. |
| app/src/main/ipc/hooks.ts | Extracts hook CRUD and MCP run entry point (runHookForMcp), and makes hook execution return a structured outcome. |
| app/src/main/ipc/tests/hooks.test.ts | Adds tests for extracted local hook CRUD functions and MCP run-hook trust/disabled/not-found/window cases. |
Adds list_hooks, list_hook_runs, create/update/delete/toggle_local_hook, and run_hook MCP tools so an agent can inspect and manage a workspace's lifecycle hooks without going through the app UI. Local-hook writes and run_hook reuse the exact same validation/execution paths as the existing HOOK_CREATE/UPDATE/ DELETE/TOGGLE IPC handlers and the Run Hook dialog. Repo hooks stay read-only and there is no trust-granting tool anywhere in the MCP surface — run_hook refuses to execute an untrusted repo hook, matching the app's own gating. Closes #153
2f864f3 to
0f321a8
Compare
|
Thanks for the review — addressed all three:
Also rebased onto main to pick up #142 (which landed |
Type
Summary
.sproutgit/local-hooks.json) through new MCP tools, and trigger a hook run through the same execution path as the Run Hook dialog.sproutgit.hooks.json) remain read-only through MCP, and there is no way to grant or bypass hook trust over MCP — an untrusted repo hook simply refuses to run (status: 'not_run'), same as the app UI.Why
Closes #153 — hooks provision a worktree (copy
.env, install deps, etc.), but agents previously had no visibility into or control over them, making it hard for an orchestrating agent to ensure a worker worktree was set up correctly, or for an agent to self-diagnose a broken worktree.Breaking changes
None — this only adds new MCP tools; no existing IPC/tool contracts changed.
Test plan
app/src/main/ipc/__tests__/hooks.test.tscovering the extractedcreateLocalHook/updateLocalHook/deleteLocalHook/toggleLocalHookfunctions (dependsOn rename cascade, repo-hook-id no-ops, duplicate-name rejection) and a dedicatedrunHookForMcpsuite proving:not_runresult,not_runinstead of throwing.packages/mcp-servertests (tools.test.ts,http-server.test.ts) for the new context shape and tool list.pnpm lint && pnpm typecheck && pnpm testall pass locally (per-package, isolated from a flaky/resource-contended full parallelturborun caused by other concurrent agents on this machine — verified each affected package's suite passes cleanly on its own:mcp-server,app,types,database,git).context.mutatingToolsEnabled()to a real per-workspace Settings toggle — deferred to PR lifecycle depth: draft/ready, per-check results, merge — for humans and agents #138/Wire SproutGit's MCP server into every integrated agent session #145 per the issue, same as the existingcreate_worktree/remove_worktreetools. All new write/run tools are gated by this same (currently always-false) flag.Deferred / out of scope
mutatingToolsEnabled()(PR lifecycle depth: draft/ready, per-check results, merge — for humans and agents #138/Wire SproutGit's MCP server into every integrated agent session #145) — new hook write/run tools use the exact same gate as the existing worktree-mutating tools, so this is consistent with current behavior, not a regression.Documentation for the full MCP tool set (this repo had none before) is now in docs/agent-instructions.md under "MCP server (agent-facing tools)".