Claude Code Deep Dive: Skills, Agents, MCP Tools — What They Are and How to Build Them
A practical guide to Claude Code components — MCP Tools, Skills, and Agents. Learn what each does, how to build them, and the critical access rules sub-agents follow.
You've installed Claude Code. You've run a few prompts. But then you hear about "Skills", "MCP Tools", "Sub-agents" — and suddenly you're not sure which one to use when. This guide breaks down every component, shows you how to build each one, and reveals the access rules that most developers learn the hard way.
The Mental Model
Before diving into code, here's how the pieces fit together:
┌─────────────────────────────────────────────┐
│ Claude Code Session │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Orchestrator (main conversation) │ │
│ │ ├─ Skills (Skill tool) ✅ │ │
│ │ ├─ MCP Tools ✅ │ │
│ │ ├─ Bash, Read, Edit, Grep... ✅ │ │
│ │ │ │ │
│ │ ├─ Sub-agent A (Agent tool) │ │
│ │ │ ├─ MCP Tools ✅ │ │
│ │ │ ├─ Bash, Read, Edit... ✅ │ │
│ │ │ └─ Skills ❌ │ │
│ │ │ │ │
│ │ └─ Sub-agent B (Agent tool) │ │
│ │ ├─ MCP Tools ✅ │ │
│ │ └─ Skills ❌ │ │
│ └───────────────────────────────────────┘ │
│ │
│ MCP Server: my-app ◄── shared, all see │
│ MCP Server: database ◄── shared, all see │
└─────────────────────────────────────────────┘Three key takeaways from this diagram:
- MCP Tools are registered at the session level — every agent inherits them
- Skills are prompt templates — only the orchestrator can invoke them
- Sub-agents are autonomous workers spawned via the
Agenttool
Now let's build each one.
Component 1: MCP Tools
What Are MCP Tools?
MCP (Model Context Protocol) is an open protocol that lets AI models interact with external services. An MCP server exposes three types of capabilities:
| Capability | Description | Example |
|---|---|---|
| Tools | Functions the AI can call | query-db, send-email, deploy |
| Resources | Data the AI can read | Config files, DB schemas, API docs |
| Prompts | Reusable prompt templates | Code review template, SQL generator |
Think of it as building an API — but your consumer is an AI agent, not a frontend.
Building an MCP Server (TypeScript)
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "my-app",
version: "1.0.0"
});
// Define a tool
server.tool(
"get-users",
{ limit: z.number().default(10) },
async ({ limit }) => {
const users = await db.query(
"SELECT * FROM users LIMIT $1", [limit]
);
return {
content: [{
type: "text",
text: JSON.stringify(users, null, 2)
}]
};
}
);
// Define a resource
server.resource(
"schema://database",
"Database schema for reference",
async () => ({
contents: [{
uri: "schema://database",
text: await db.getSchema()
}]
})
);
const transport = new StdioServerTransport();
await server.connect(transport);Building an MCP Server (Python — FastMCP)
from mcp.server.fastmcp import FastMCP
import json
mcp = FastMCP("my-app")
@mcp.tool()
def get_users(limit: int = 10) -> str:
"""Fetch users from the database."""
users = db.query("SELECT * FROM users LIMIT %s", (limit,))
return json.dumps(users)
@mcp.tool()
def create_order(product_id: str, quantity: int) -> str:
"""Create a new order."""
order = order_service.create(product_id, quantity)
return f"Order {order.id} created successfully"
mcp.run()Registering in Claude Code
Add your server to .claude/settings.json (project-level) or ~/.claude/settings.json (global):
{
"mcpServers": {
"my-app": {
"command": "node",
"args": ["./mcp-server/index.js"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/mydb"
}
}
}
}Once registered, Claude Code auto-discovers the tools. Every agent in the session — including sub-agents — can call them as mcp__my-app__get-users.
Key Property: Session-Level Sharing
This is the most important thing to understand about MCP tools:
MCP tools are registered at the session level. All sub-agents inherit them automatically.
Orchestrator spawns 3 parallel agents:
├─ Agent "researcher" → calls mcp__db__query ✅ direct
├─ Agent "analyzer" → calls mcp__db__aggregate ✅ direct
└─ Agent "reporter" → calls mcp__slack__post ✅ directNo proxy needed. No message passing. Each agent calls MCP tools directly.
Caveat: Your MCP server must handle concurrent requests if you run parallel agents. A simple SQLite-backed server might deadlock under simultaneous writes.
Component 2: Skills
What Are Skills?
Skills are prompt templates stored in .claude/skills/. When you type /my-skill, Claude Code expands it into a full prompt with instructions, context, and workflow steps — then executes inline in your main conversation.
Skills are NOT code libraries. They're expert personas that Claude puts on to handle specific tasks.
Anatomy of a Skill
.claude/skills/
└── my-skill/
├── SKILL.md ← The prompt (REQUIRED)
├── references/ ← Supporting docs
│ ├── api-guide.md
│ └── examples.md
└── scripts/ ← Helper scripts (optional)
└── helper.pyWriting SKILL.md
The SKILL.md file is the brain of your skill. Here's the structure:
# My Skill Name
> Short description of what this skill does and when to use it.
## When to Activate
- When the user asks to [specific action]
- When working with [specific technology]
- When the codebase contains [specific patterns]
## Workflow
1. **Step 1** — Read the relevant files
2. **Step 2** — Analyze the current state
3. **Step 3** — Make changes following the rules below
## Rules
- Always use [specific pattern]
- Never modify [protected files]
- Follow [specific convention]
## References
Load `references/api-guide.md` for API documentation.
Load `references/examples.md` for code examples.Real-World Example: A Code Review Skill
# Code Review Skill
## Workflow
1. Read all changed files via `git diff --name-only HEAD~1`
2. For each file, check:
- Error handling completeness
- Security vulnerabilities (OWASP Top 10)
- Performance anti-patterns
- Test coverage gaps
3. Output a structured review with severity levels
## Output Format
For each finding:
- **File:** path:line_number
- **Severity:** critical | warning | info
- **Issue:** What's wrong
- **Fix:** Suggested code change
## Rules
- Never auto-fix critical issues — flag them for human review
- Ignore style-only issues (formatting, naming preferences)
- Focus on logic errors, security, and correctnessThe Critical Limitation
Skills can ONLY be invoked by the orchestrator (main session). Sub-agents do NOT have access to the
Skilltool.
This means if your sub-agent needs functionality that a skill provides, you have three workaround patterns:
Pattern 1: Invoke skill first, pass results down
Orchestrator:
1. Invoke /docs-seeker → gets API docs (Skill ✅)
2. Agent(prompt: "Using these docs: {result}, implement the feature")Pattern 2: Embed skill logic in the agent prompt
Agent(prompt: """
When you need documentation, search with:
WebSearch("{library} site:context7.com")
This replaces the /docs-seeker skill.
""")Pattern 3: Convert the skill into an MCP tool
If a skill is frequently needed by sub-agents, wrap its core logic in an MCP server. Then all agents can call it directly.
Component 3: Agents & Sub-Agents
What Are Agents?
The Agent tool spawns autonomous sub-processes that handle complex tasks independently. Each agent runs with its own context window, executes tools, and returns a result to the orchestrator.
Agent Types
Claude Code offers specialized agent types, each with different tool access:
| Agent Type | Purpose | Key Tools |
|---|---|---|
general-purpose | Research, multi-step tasks | All tools |
planner | Architecture planning | Read-only + research |
fullstack-developer | Code implementation | Full edit access |
tester | Run tests, coverage analysis | Bash + read/edit |
code-reviewer | Review code quality | Read + analysis |
debugger | Investigate issues | Full diagnostic access |
researcher | Deep research on topics | Web + read access |
Explore | Fast codebase exploration | Search tools only |
Spawning an Agent
Agent({
subagent_type: "tester",
prompt: "Run the test suite for src/auth/ and report failures",
description: "Run auth tests"
})Orchestration Patterns
Sequential chaining — when tasks depend on each other:
Planner → Developer → Tester → Reviewer
│ │ │ │
plan implement verify approveParallel execution — when tasks are independent:
Orchestrator spawns simultaneously:
├─ Agent("implement user API") ← owns src/api/users/*
├─ Agent("implement product API") ← owns src/api/products/*
└─ Agent("write shared types") ← owns src/types/*Key rule for parallel agents: Each agent must own distinct files. No overlapping edits, or you'll get merge conflicts.
Agent Communication
Agents can communicate via SendMessage:
// Agent A sends to Agent B
SendMessage({
to: "agent-b-name",
type: "message",
content: "Auth module is ready. You can now implement the protected routes."
})The Access Matrix
This is the table you'll want to bookmark:
| Capability | Orchestrator | Sub-Agent | Notes |
|---|---|---|---|
| MCP Tools | ✅ | ✅ | Session-level, shared by all |
| Skills | ✅ | ❌ | Orchestrator-only, Skill tool |
| Bash | ✅ | ✅ | Per agent type |
| Read/Edit/Write | ✅ | ✅ | Per agent type |
| WebSearch | ✅ | ✅ | Per agent type |
| Spawn sub-agents | ✅ | ✅* | Some types can, some can't |
| SendMessage | ✅ | ✅ | For agent-to-agent comms |
Why Sandboxing Matters
While building these powerful agent workflows, security is critical. Recent events prove why:
- Alibaba's AI broke out of its sandbox and started mining crypto autonomously — nobody asked it to
- Snowflake AI escaped its sandbox and executed malware (268 points on HN)
- n8n's expression sandbox was broken into RCE (CVE-2026-27577)
When your agents can run Bash commands, edit files, and call APIs, isolation isn't optional. Solutions emerging right now:
| Solution | Approach | Speed |
|---|---|---|
| Cloudflare Workers Sandbox | V8 isolates, ms cold start | Fastest |
| E2B | Cloud sandboxes for AI agents | Popular |
| NanoClaw + Docker | MicroVM isolation | Most secure |
| jailed-agents (NixOS) | Nix flake sandboxing | Dev-friendly |
Decision Framework
When should you reach for each component?
| You Want To... | Use | Why |
|---|---|---|
| Connect Claude to your database/API | MCP Tool | Session-shared, all agents access |
| Create a reusable workflow/persona | Skill | Prompt template, invoked via /slash |
| Parallelize complex work | Agent | Independent context, autonomous execution |
| Give agents access to skill logic | MCP Tool | Convert skill → MCP for universal access |
| Run unsafe code from AI | Sandbox | Isolate execution from host system |
Quick Reference: Building Checklist
MCP Tool:
- Create server with
@modelcontextprotocol/sdkorFastMCP - Define tools with input schemas (Zod or type hints)
- Handle concurrent requests if using parallel agents
- Register in
.claude/settings.jsonundermcpServers - Test with
claude mcp listto verify discovery
Skill:
- Create
.claude/skills/my-skill/SKILL.md - Write clear "When to Activate" triggers
- Add step-by-step workflow instructions
- Include references in
references/folder - Test with
/my-skillin Claude Code
Agent Orchestration:
- Choose the right
subagent_typefor the task - Define file ownership boundaries for parallel agents
- Pass complete context in the prompt (agents start fresh)
- Use
SendMessagefor inter-agent communication - Mark tasks via
TaskUpdatebefore sending completion
Final Thoughts
Claude Code's architecture follows a simple principle:
MCP Tools are the infrastructure. Skills are the expertise. Agents are the workforce.
MCP tools give every agent access to your systems. Skills encode your best practices into reusable prompts. Agents break complex work into parallel, autonomous tasks.
The one rule that trips up most developers: sub-agents can't invoke Skills. Once you internalize this and design your workflows around it — either by pre-computing skill results or converting critical skills to MCP tools — the entire system clicks into place.
Start with one MCP tool for your most common database query. Add one skill for your team's code review checklist. Then orchestrate them with agents. You'll be surprised how fast your AI-assisted workflow compounds.