Academy hook bundle, auto-recipe lookup, session-start dashboard
Two mcp_tool hooks for the Academy MCP itself. UserPromptSubmit pre-fetches recipes when you ask 'how do I X'. SessionStart shows you XP, rank, next lesson without typing a command.
Academy hook bundle, auto-recipe lookup, session-start dashboard
The Academy MCP (mcp-academy on npm, hosts at studiomeyer.academy) ships 23 tools spanning lessons, recipes, concepts, quiz, certificates, tutor. Two hooks cover 80% of the friction.
Step 1: UserPromptSubmit hook → auto-recipe lookup
When you ask "how do I publish to npm" or "recipe for OAuth setup" or "wie mache ich X", the Academy probably has a recipe for it. Fire academy_get_recipe automatically:
{
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/home/simple/.claude/hooks/academy-recipe-trigger.sh",
"timeout": 3
}
]
}
]
}
Where academy-recipe-trigger.sh:
#!/usr/bin/env bash
input=$(cat)
prompt=$(echo "$input" | jq -r '.prompt // .user_prompt // ""')
# Trigger phrases (DE + EN) that indicate the user wants step-by-step guidance
if echo "$prompt" | grep -qiE 'how (do|to)|recipe for|wie mache ich|wie geht|step.by.step|schritt für schritt'; then
echo '{"hookSpecificOutput":{"additionalContext":"User asked for how-to guidance. Suggest calling academy_concept_search({query: \"<topic>\"}) to find related concepts, then academy_list_recipes({phase: <relevant>}) to find a step-by-step recipe. If the user already has a recipe slug, call academy_start_recipe({slug}) directly."}}'
fi
Why bash + context-injection instead of mcp_tool calling academy_concept_search? Because we need to extract the topic from the prompt and bash regex is too fragile for that. The injected context tells the assistant exactly which two tools to call with the right parameters.
Step 2: SessionStart hook → dashboard injection
Every session should start knowing where you stand: XP, rank, current league, next lesson. Wire it:
{
"SessionStart": [
{
"hooks": [
{
"type": "mcp_tool",
"server": "academy",
"tool": "academy_stats",
"input": {},
"timeout": 10,
"statusMessage": "Academy: loading stats..."
},
{
"type": "mcp_tool",
"server": "academy",
"tool": "academy_next_lesson",
"input": {},
"timeout": 10,
"statusMessage": "Academy: finding next lesson..."
}
]
}
]
}
Two parallel hooks. Both read-only. Both under 500ms. Result: every Claude Code session you start, the assistant already knows your XP, rank, streak, and what to recommend studying next. Without typing a command.
Step 3: GDPR + idempotency notes
- Idempotent.
academy_statsandacademy_next_lessonare pure reads.academy_concept_searchis read-only. - Fast. All three under 500ms.
- Deterministic. Same time, same stats. Same query, same concept ranking.
- Side-effect-free without user trigger. All read-only.
- GDPR. Academy data flows from your Claude Code session to your own Academy tenant on
studiomeyer.academy. No third-party sharing. Your XP and lesson progress are not exposed in any leaderboard unless you opt-in.
Step 4: Optional, quiz auto-trigger on lesson completion
Advanced pattern: when you call academy_progress_complete for a lesson, automatically offer the quiz:
{
"PostToolUse": [
{
"matcher": "mcp__academy__academy_progress_complete",
"hooks": [
{
"type": "mcp_tool",
"server": "academy",
"tool": "academy_quiz",
"input": { "lesson_slug": "${tool_input.lesson_slug}" },
"timeout": 10,
"statusMessage": "Academy: loading quiz..."
}
]
}
]
}
This pattern cascades: lesson-complete → quiz-fetch. Claude Code presents the quiz inline, user answers, you call academy_quiz_submit. Closes the loop without any "and now check the quiz" prompt.
Step 5: Verify the bundle works
# Edit settings.json with the SessionStart hooks above
claude
You should see both status messages flash on session start: "Academy: loading stats..." then "Academy: finding next lesson...". The assistant's first response should reference your current XP and the recommended next lesson without you asking.
# In the running session:
# "wie mache ich npm publish"
Status: nothing (UserPromptSubmit triggers context-injection only, not a tool call). But the assistant's response should now suggest specific Academy recipes, usually 9.1-npm-publish.
Step 6: Why these hooks instead of others
Academy has 23 tools. We only wired three. The rest (review, certificates, tutor, leaderboard) are user-driven explicit calls, not lifecycle-triggered. Hooks are for things the assistant SHOULD do automatically. Tools that need user-input (e.g. submitting a quiz answer) stay user-explicit.
If you do a lot of Academy work, you might also wire:
Stop→academy_reviewto log session retrospectiveSubagentStop→academy_tutorto ask the tutor for follow-up suggestions
But those are personal preferences. Start with the 2-3 from this recipe.
Done
Five SaaS-MCPs (Memory, CRM, GEO, Crew, Academy) all have working hook bundles. Your Claude Code workflow is now fully agentic, the assistant uses MCP tools without you having to remember to call them.
Next: distribute these as plugins
The five bundles are ready to be packaged as Claude Code plugins on the studiomeyer-io/studiomeyer-marketplace. One claude plugin install studiomeyer-memory-hooks and the user gets all four Memory hooks at once. That packaging is recipe 9.6 (coming soon as part of Phase 9 Distribution).