feat(#418): enforce MCP search-first pattern#422
Conversation
- Add suggest-mcp-search.sh (PreToolUse on Bash) — emits advisory banner when grep/find targets framework or project paths, reminding the agent to try search_docs/search_code first (~3-5x token savings) - Add remind-mcp-tools.sh (SessionStart) — emits banner with the ToolSearch load command so the agent sees MCP tools from session start, removing deferred-tool friction - Wire both hooks in settings.json - Add 13 test cases for the advisory hook (8 should-fire, 5 should-not) Root causes: RC1 deferred-tool friction (ToolSearch required before use), RC2 no mechanical enforcement of feedback memory. These hooks address both — the session-start hook reduces friction, the PreToolUse hook catches the moment of drift. Refs #418 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #422
Commit: e71cb0d530ebc382d426df1a4251a6dc5d436e22
Summary
Adds two advisory hooks to nudge agents toward MCP search tools (search_docs/search_code) instead of defaulting to grep+Read. remind-mcp-tools.sh fires at session start (only when .mcp.json exists), and suggest-mcp-search.sh fires on PreToolUse for Bash when grep/find targets framework paths. Both are non-blocking (exit 0 always). 13 test cases cover the detection logic.
Checklist Results
- ✅ Architecture & Design: Pass — follows existing advisory-hook pattern (
detect-role-trigger.shshape), no new layers or dependencies introduced - ✅ Code Quality: Pass — scripts are focused, well-commented,
set -uthroughout, cleancase/pattern matching - ✅ Testing: Pass — 13 cases (8 should-fire, 5 should-not) cover the key branches; edge cases like non-Bash tool, non-framework path, piped grep all tested
- ✅ Security: Pass — no secrets, no user input passed to eval, no injection surface (jq extracts, grep matches, no dynamic execution)
- ✅ Performance: Pass — early exits on tool_name/command checks keep the hot path fast
- ✅ PR Description & Glossary: Pass — glossary present with MCP, Deferred tool, Advisory hook defined
- ⚠ Summary Bullet Narrative: Pass — all three bullets are narrative with rationale
- ✅ Technical Decisions (AgDR): N/A — no new libraries, frameworks, or architecture patterns; follows the established advisory-hook convention
- ✅ Adopter Handbooks: Pass — no violations detected (migration-safety N/A, clean-architecture N/A for shell scripts, commit-message-quality advisory — no findings)
Issues Found
None.
Suggestions
-
suggest-mcp-search.sh:30-34—grep -Ewithout-ron framework dirs would not trigger: The case arms matchgrep -r*,grep --include*,grep -l*, and piped grep. Butgrep -E "pattern" roles/(without-r) targeting a framework dir would slip through. Low priority since single-file grep is less of a token concern than recursive grep. -
remind-mcp-tools.sh:25-31— walk-up loop for.mcp.json: Correctly walks fromREPO_ROOTupward, finding the ops-root.mcp.jsoneven from a workspace clone. Good design. -
nit:Thefindpattern on line 37 ofsuggest-mcp-search.shrequires the extension list (md|yaml|yml|ts|tsx|js|py) — a barefind roles/ -type fwithout-namewouldn't trigger. Acceptable since barefindwithout-nameis rare in practice.
Verdict
APPROVED
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: e71cb0d530ebc382d426df1a4251a6dc5d436e22
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #422
Commit: e71cb0d530ebc382d426df1a4251a6dc5d436e22
Summary
Adds two advisory hooks to enforce MCP search-first behaviour: suggest-mcp-search.sh (PreToolUse on Bash — fires when grep/find targets framework paths, reminding the agent to use MCP search_docs/search_code first) and remind-mcp-tools.sh (SessionStart — emits a ToolSearch load command so MCP tools are in context from the beginning). Both are non-blocking (exit 0 always), matching the established advisory-hook pattern. Wired into .claude/settings.json at the correct hook points. 13 test cases cover the should-fire/should-not-fire matrix.
Checklist Results
- ✅ Architecture & Design: Pass — advisory-only hooks, no domain dependencies, follows established patterns (
detect-role-trigger.sh,check-upstream-drift.sh) - ✅ Code Quality: Pass —
set -u, clear comments, clean separation of detection/emission - ✅ Testing: Pass — 13 cases (8 positive, 5 negative), all passing
- ✅ Security: Pass — no secrets, no eval, no user input passed to commands
- ✅ Performance: Pass — sub-millisecond case/grep-q checks, bounded walk-up loop
- ✅ PR Description & Glossary: Pass — narrative bullets, glossary with 3 terms, testing instructions, issue linked
- ✅ Summary Bullet Narrative: Pass — all bullets are narrative with what+why
- ✅ Technical Decisions (AgDR): N/A — no new dependencies, frameworks, or architectural patterns introduced
- ✅ Adopter Handbooks: Pass — no violations (Clean Architecture Layers, Migration Safety, Commit Message Quality all N/A for this shell-only diff)
Issues Found
None.
Handbook Findings
No violations detected. All three loaded handbooks (clean-architecture-layers, migration-safety, commit-message-quality) are not applicable to this diff — no domain/application/infrastructure layering, no database migrations, and the single commit subject is descriptive.
Suggestions
-
nit:suggest-mcp-search.sh:54— the"hooks/"pattern inframework_patternsis a bare substring that could false-positive on managed-project paths likewebhooks/orgithooks/. Consider tightening to".claude/hooks/"(the framework's hook location) or keeping it as-is since the advisory cost of a false-positive banner is near zero. Not blocking. -
nit:Perhandbooks/general/commit-message-quality.md— the commit (e71cb0d5) is 225 lines of diff with a subject-only message. An optional body explaining WHY the MCP search-first pattern matters (the deferred-tool friction root cause) would help futuregit blamereaders. The PR description covers this well, so this is purely a commit-hygiene observation. Not blocking.
Verdict
APPROVED (posted as comment — cannot approve own PR)
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: e71cb0d530ebc382d426df1a4251a6dc5d436e22
Put grep\ -rn* before grep\ -r* so the more specific pattern isn't shadowed by the shorter one. Refs #418 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #422
Commit: 59f9de7037ef0de063fe46a1196355d67d359a65
Summary
Adds two advisory hooks to enforce the MCP search-first pattern: suggest-mcp-search.sh fires on PreToolUse for Bash when grep/find targets framework paths, and remind-mcp-tools.sh emits a ToolSearch load command at session start. Both are wired in settings.json.
Checklist Results
- ✅ Architecture & Design: Pass — advisory hooks follow the established pattern (exit 0 always, stderr banners, no blocking)
- ✅ Code Quality: Pass — clean shell scripts with proper
set -u, clear comments, deterministic control flow - ✅ Testing: Pass — 13 test cases covering both should-fire and should-not-fire scenarios
- ✅ Security: Pass — no secrets, no user input processed unsafely,
jq -rfor JSON parsing - ✅ Performance: Pass — early exits on non-matching tools/commands, no expensive operations
- ✅ PR Description & Glossary: Pass — glossary present with MCP, deferred tool, advisory hook definitions
- ⚠ Summary Bullet Narrative: Pass
- ✅ Technical Decisions (AgDR): N/A — no new libraries or architecture patterns; hooks follow the existing advisory shape
Issues Found
None.
Suggestions
-
suggest-mcp-search.sh:29-33— thecasestatement catchesgrep -rn*andgrep -r*butgrep -r*already subsumesgrep -rn*since-rnstarts with-r. Thegrep -rn*branch is unreachable. Harmless but could be simplified. -
remind-mcp-tools.sh:24-31— the walk-up loop looking for.mcp.jsonis a nice touch (handles portfolio layouts), but it will also match an.mcp.jsonat/if one existed. The[ "$r" != "/" ]guard prevents that, so this is fine — just noting the defensive shape works correctly.
Verdict
APPROVED (posted as comment — cannot approve own PR)
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: 59f9de7037ef0de063fe46a1196355d67d359a65
feat(#418): enforce MCP search-first pattern
Summary
suggest-mcp-search.sh— fires onPreToolUseforBashwhengrep -r/findtargets framework or project paths (roles/, workflows/, handbooks/, .claude/, workspace/, etc.). Emits a non-blocking banner reminding the agent to try MCPsearch_docs/search_codefirst, saving ~3-5x tokens per lookup.remind-mcp-tools.sh— emits theToolSearchload command at session start so MCP tools are in context from the beginning, removing deferred-tool friction that was the primary root cause of underuse..claude/settings.json— SessionStart for the reminder, PreToolUse Bash for the advisory.Testing
bash .claude/hooks/tests/test_suggest_mcp_search.sh— 13 cases (8 should-fire, 5 should-not), all passgrep -r "activation" roles/→ advisory banner firesnpm test→ no banner (non-framework path)Glossary
ToolSearchcall to activate, creating friction vs always-available tools likegrepdetect-role-trigger.shRefs #418
🤖 Generated with Claude Code