Recommended resources
The freely available resources this lesson will direct you to.
Hello! Welcome back to our exploration of advanced Claude Code workflows.
In the previous lesson, we created a conceptual map, identifying which advanced features to use at each stage of the development lifecycle. We saw how slash commands, hooks, and MCP servers could orchestrate a full-stack feature implementation from planning to deployment.
Today, we transition from mapping to architectural design. Your goal is to design a complex workflow where a custom slash command triggers a process involving a hook and a custom MCP server. We will blueprint a practical, integrated system that leverages your expertise in FastAPI and PostgreSQL, laying the groundwork for hands-on implementation in our next session.
The Anatomy of an Integrated Workflow
Before we design our own, let's solidify our understanding of the three core components and their distinct roles. Each serves a unique purpose, and their power comes from how they interoperate.
- Slash Command (
/): The explicit trigger. This is the user-facing entry point. You decide when to run it, providing clear intent and initiating a defined process. - MCP Server (
mcp__): The external capability provider. It gives Claude access to tools and data outside its core functions, like your database, a third-party API, or a custom microservice. - Hook (
settings.json): The automated guardian. It runs implicitly in response to lifecycle events (like a tool being used). Hooks enforce rules, run quality checks, and automate repetitive tasks without you or Claude having to remember.
From CLI to Platform: Claude Code's Extension System
To see how these components are officially positioned within the Claude Code ecosystem, let's watch a few key segments from the 'From CLI to Platform' video by The Gray Cat. This will reinforce the specific role each one plays.
Please watch the following three short clips: Custom Commands (03:21 - 05:18): Focus on how commands are explicit shortcuts for reusable prompts. Hooks (05:18 - 06:49): Note the event-driven nature of hooks and how they provide automated control. MCP Servers (13:15 - 14:18): Understand that MCPs are protocol-based tool providers that give Claude new capabilities.
These components form a powerful triad: the command expresses intent, the MCP provides capability, and the hook ensures compliance.

Designing a Real-World Workflow
Let's design a workflow tailored to your background. Imagine you're working on one of your GenAI projects that uses FastAPI and PostgreSQL, possibly for a RAG pipeline. A common task is to add new data structures.
Our Goal: Create a robust workflow to scaffold a new database-backed data model.
The workflow will perform three actions:
- Trigger: A user invokes a
/new-modelslash command. - Action: Claude scaffolds a new Pydantic model and a corresponding SQLAlchemy table model.
- Integration & Guardrails:
- The creation event is logged to an external audit service (a custom FastAPI MCP server).
- A hook prevents any accidental edits to a protected, core database schema file.
Let's design each component.
1. The Auditing MCP Server
First, we need the external capability: a service to log schema changes. This is a perfect use case for a simple, custom MCP server built with FastAPI.
- Functionality: A single API endpoint, say
POST /log, that accepts a JSON body like{"event_type": "schema_change", "details": "..."}. In a real system, this might write to a database or a log aggregator. For our design, we can assume it just prints the received data to the console. - MCP Registration: This FastAPI application would be registered in the project's
.claude/mcp.jsonfile. Claude Code would start this server in the background. - Tool Exposure: Once registered, the server would expose a tool to Claude. Following the standard naming convention, it might be called
mcp__audit__log. When Claude uses this tool, it's making an HTTP request to our FastAPI server.
This design gives Claude a new, well-defined capability: mcp__audit__log.
2. The /new-model Slash Command
This is the user's entry point. It's a Markdown file, likely located at .claude/commands/new-model.md.
- Arguments: It needs to accept the name of the new model, which we can capture using the
$ARGUMENTSplaceholder. For example:/new-model UserFeedback. - Prompt Design: The core of the command is its prompt, which instructs Claude on the sequence of actions to perform. It would look something like this:
---
description: "Scaffolds a new Pydantic/SQLAlchemy model and logs the event."
argument-hint: "[ModelName]"
---
You are an expert FastAPI developer. Based on the provided model name, `$ARGUMENTS`, perform the following steps:
1. **Create Pydantic Model:** Generate a Pydantic model for `$ARGUMENTS`. Place it in a new file at `app/schemas/$ARGUMENTS_lower.py`.
2. **Create SQLAlchemy Model:** Generate a corresponding SQLAlchemy model that inherits from our declarative base. Place it in a new file at `app/models/$ARGUMENTS_lower.py`.
3. **Log the Event:** Use the `mcp__audit__log` tool to record this action. The tool input should be a JSON object with the format: `{"event_type": "MODEL_CREATE", "model_name": "$ARGUMENTS"}`.
4. **Confirm:** Report back to me when all steps are complete.
This command design is explicit, multi-step, and integrates the use of our custom MCP tool.
3. The PreToolUse Security Hook
Finally, we need our automated guardian. We want to protect a critical file, for example, app/db/base.py, which might contain the core declarative_base or database session setup. No automated process should ever touch this file.
- Configuration: This hook will be defined in
.claude/settings.json. - Event: It will trigger on the
PreToolUseevent, which fires before a tool likeEditorWriteis executed. - Matcher: The
matcherwill target theEditandWritetools:"matcher": "Edit|Write". - Logic (The Hook Script): The hook will be a simple shell script.
- It reads the JSON input provided by Claude Code via
stdin. - It extracts the
file_pathfrom the tool's input. - It checks if
file_pathmatches our protected file (app/db/base.py). - If it matches, the script prints an error message to
stderrand exits with code2. This special exit code signals to Claude Code to block the tool's execution. - If it doesn't match, the script exits with code
0, allowing the action to proceed.
- It reads the JSON input provided by Claude Code via
To understand the mechanics of hooks and their integration with MCPs, the "Claude Code Hooks" guide is invaluable.
Claude Code Hooks: Complete Guide to Workflow Automation | Morph
The article 'Claude Code Hooks: Complete Guide to Workflow Automation' provides an in-depth look at how hooks function, including their security applications and integration with MCP servers.
Please read the sections 'The Security Angle: Programmable Guardrails' and 'Hook + MCP Integration.' Focus on how a PreToolUse hook can inspect tool arguments to block actions on protected files, and how hooks can be configured to target specific MCP tool patterns.
The Complete Workflow in Action
Let's trace the execution flow of our designed system.
Successful Scenario: /new-model UserProfile
- User: Types
/new-model UserProfile. - Claude Code: Executes the slash command's prompt.
- Claude (AI): Generates code for
UserProfileand proposes toWritethe fileapp/schemas/user_profile.py. - Hook (
PreToolUse): The hook script runs. It checks the pathapp/schemas/user_profile.py, finds no match with the protected file, and exits0(allow). - Claude Code: The
Writeoperation succeeds. - Claude (AI): Proposes to
Writethe fileapp/models/user_profile.py. - Hook (
PreToolUse): The hook runs again, allows the action. TheWriteoperation succeeds. - Claude (AI): Proposes to call the
mcp__audit__logtool with the payload{"event_type": "MODEL_CREATE", "model_name": "UserProfile"}. - Hook (
PreToolUse): The hook runs. The tool name (mcp__audit__log) does not match theEdit|Writematcher, so the hook takes no action and implicitly allows it. - Claude Code (MCP): Forwards the request to the running FastAPI audit server.
- FastAPI Server: Receives the request, logs the event, and returns a success response.
- Claude (AI): Confirms to the user that both models were created and the action was logged.
Failure Scenario: "Add a comment to app/db/base.py"
- User: Prompts Claude to edit the protected file.
- Claude (AI): Proposes to
Editthe fileapp/db/base.py. - Hook (
PreToolUse): The hook script runs. It finds thatapp/db/base.pymatches the protected path. - Hook Script: Prints "ERROR:
app/db/base.pyis a protected file and cannot be modified." tostderrand exits2(block). - Claude Code: The
Editoperation is blocked. - Claude (AI): Receives the error message from the hook and informs the user: "I cannot perform this action because
app/db/base.pyis a protected file."
This design creates a powerful, semi-autonomous workflow that is both efficient and safe.
Conclusion
Today, we've moved from theory to practice by architecting a concrete, integrated workflow. We designed a system where a user's explicit intent (a slash command) triggers a series of actions that leverage an external capability (an MCP server), all while being governed by automated safety rules (a hook).
Key Takeaways:
- Design is about Interconnection: The power lies not in the individual components, but in how they are designed to communicate and trigger one another.
- Command as the Entry Point: Slash commands are the ideal way to start a complex, predefined workflow, passing initial parameters.
- MCP for Extensibility: Custom MCP servers are the bridge to your existing infrastructure, allowing Claude to interact with your databases, APIs, and services in a structured way.
- Hooks for Safety and Automation:
PreToolUsehooks are essential for creating programmable guardrails that enforce project rules deterministically, making autonomous workflows safer.
Next Up:
With our architectural blueprint complete, the next logical step is to build it. In our next lesson, you will implement and debug this integrated workflow, writing the Python code for the FastAPI MCP server, the shell script for the hook, and the Markdown/YAML for the slash command. You'll see firsthand how these designed components come together in a functioning system.