Skip to content

feat(mcp): add hook management tools to the MCP server#156

Merged
liam-russell merged 1 commit into
mainfrom
claude/hooks-mcp-tools
Jul 7, 2026
Merged

feat(mcp): add hook management tools to the MCP server#156
liam-russell merged 1 commit into
mainfrom
claude/hooks-mcp-tools

Conversation

@liam-russell

Copy link
Copy Markdown
Contributor

Type

  • feat — new feature or user-visible capability

Summary

  • Agents connected via the SproutGit MCP server can now list effective hooks (local + repo merged, with source/trigger/enabled/trusted state) and read the hook-run audit log for a worktree.
  • Agents can create, update, delete, and toggle local hooks (.sproutgit/local-hooks.json) through new MCP tools, and trigger a hook run through the same execution path as the Run Hook dialog.
  • Repo hooks (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

  • Added tests in app/src/main/ipc/__tests__/hooks.test.ts covering the extracted createLocalHook/updateLocalHook/deleteLocalHook/toggleLocalHook functions (dependsOn rename cascade, repo-hook-id no-ops, duplicate-name rejection) and a dedicated runHookForMcp suite proving:
    • an untrusted repo hook refuses to run and grants no trust as a side effect,
    • a disabled hook refuses to run,
    • an unknown hookId reports a clear not_run result,
    • no open workspace window reports not_run instead of throwing.
  • Updated packages/mcp-server tests (tools.test.ts, http-server.test.ts) for the new context shape and tool list.
  • pnpm lint && pnpm typecheck && pnpm test all pass locally (per-package, isolated from a flaky/resource-contended full parallel turbo run 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).
  • Not yet verified: wiring 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 existing create_worktree/remove_worktree tools. All new write/run tools are gated by this same (currently always-false) flag.

Deferred / out of scope

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)".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread packages/mcp-server/src/tools.ts Outdated
Comment thread app/src/main/ipc/hooks.ts
Comment thread app/src/main/ipc/hooks.ts
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
@liam-russell liam-russell force-pushed the claude/hooks-mcp-tools branch from 2f864f3 to 0f321a8 Compare July 7, 2026 08:01
@liam-russell

Copy link
Copy Markdown
Contributor Author

Thanks for the review — addressed all three:

  1. run_hook now always returns a normal (non-error) result; not_run is a structured outcome an agent branches on via status, not an RPC-level failure.
  2. createLocalHook now validates dependsOn against the existing local hook names (and rejects self-reference) before writing, so a bad reference can no longer corrupt local-hooks.json and silently disable every local hook.
  3. Same validation added to updateLocalHook, computed against the post-rename name set so a rename can't accidentally introduce a self-reference either.

Also rebased onto main to pick up #142 (which landed get_worktree_diff/report_session_done and the MCP docs page) — merged cleanly, both tool sets coexist, and I extended the existing website/src/content/docs/docs/guides/mcp-server.md doc with the new hook tools rather than only documenting in docs/agent-instructions.md. Added tests for the new validation. All green: pnpm lint && pnpm typecheck && pnpm test.

@liam-russell liam-russell merged commit ba7ed1b into main Jul 7, 2026
15 checks passed
@liam-russell liam-russell deleted the claude/hooks-mcp-tools branch July 7, 2026 09:55
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.

MCP tools for hooks: list, manage local hooks, run, read audit log (no trust granting)

2 participants