Tools, Skills, and MCPs: The Three Building Blocks of Claude Agents

Tools, Skills, and MCPs
author picture

Oscar Gallo

Published on March 19, 2026

Understanding what connects Claude to the world, what makes Claude smarter, and what bridges the gap between them.


If you're building agents with Claude — whether through the Agent SDK, Claude Code, or the API — you've probably run into three terms that get thrown around constantly: Tools, Skills, and MCPs. They sound similar. They overlap in places. And the docs, while thorough, don't always make it obvious when to reach for which.

This post breaks down exactly what each one is, how they differ, and — most importantly — how to think about combining them in real agent architectures.


The One-Liner Version

  • Tools execute actions. They connect Claude to the outside world.
  • Skills inject expertise. They teach Claude how to approach problems.
  • MCPs expose capabilities. They're a protocol that turns any service into a set of tools Claude can discover and call.

If tools are Claude's hands, skills are Claude's training manuals, and MCPs are the standardized plugs that connect Claude to everything else.


Tools: What Claude Does

Tools are the most concrete of the three. A tool is a function Claude can call — it has a name, a JSON schema for its inputs, and it returns a result. When Claude decides it needs to read a file, run a shell command, or call an API, it's using a tool.

The Agent SDK ships with a set of built-in tools that cover the fundamentals:

  • Read — Read file contents
  • Write — Create or overwrite files
  • Edit / MultiEdit — Surgical text replacements in existing files
  • Bash — Execute shell commands
  • Glob — Find files by pattern
  • Grep — Search file contents
  • Agent (formerly Task) — Spawn a subagent with its own context window
  • WebSearch / WebFetch — Search the web and retrieve page content

These are action-oriented. Each one executes something and returns a result. Claude sees the tool definitions in its context window, decides when to invoke them, receives the output, and continues reasoning.

Custom Tools

Beyond the built-ins, you can define your own tools using in-process MCP servers (more on MCP below). The Agent SDK provides a tool() helper and createSdkMcpServer() to make this straightforward:

from claude_agent_sdk import tool, create_sdk_mcp_server

@tool("lookup_ticket", "Fetch a GitHub issue by number", {"issue_number": int})
async def lookup_ticket(args):
    # Your logic here — call GitHub API, query a database, whatever
    return {"content": [{"type": "text", "text": f"Issue #{args['issue_number']}: ..."}]}

server = create_sdk_mcp_server(
    name="project-tools",
    version="1.0.0",
    tools=[lookup_ticket]
)

The key insight: tools are about doing. They take an input, perform a side effect or computation, and return a result. They don't teach Claude anything — they give Claude the ability to act.

The Performance Reality

Every tool definition consumes context window tokens. A typical five-MCP-server setup with ~58 tools can burn ~55,000 tokens before Claude processes a single user message. Anthropic has internally observed setups consuming 134,000 tokens in tool definitions alone.

More concerning than cost: accuracy degrades. Anthropic's internal benchmarks showed that with large tool libraries, Opus 4 dropped to 49% accuracy on tool selection — essentially a coin flip. The most common failure mode is picking the wrong tool when names are similar (e.g., notification-send-user vs. notification-send-channel).

Practical guidance: Keep your always-loaded tools scoped to what the agent actually needs for the current task. If an agent is doing git operations and file edits, don't load Slack, Jira, and analytics tools into that same context. For larger tool libraries, use the Tool Search Tool (covered below) to load tools on-demand.


Skills: What Claude Knows

Skills are fundamentally different from tools. They don't execute anything. They don't return results. Instead, skills prepare Claude to solve a problem by injecting domain-specific instructions, workflows, and best practices into the context.

A skill is a filesystem artifact — a directory containing a SKILL.md file and optional supporting resources (scripts, templates, reference data). The SKILL.md has two parts:

  1. YAML Frontmatter — Metadata that controls how and when the skill loads (name, description, allowed tools, model overrides)
  2. Markdown Content — The actual instructions that tell Claude what to do and how to do it

Here's what a simple skill structure looks like:

.claude/skills/
└── branch-naming/
    └── SKILL.md

And the SKILL.md itself:

---
name: branch-naming
description: >
  Enforces team branch naming conventions and PR description
  standards. Use when creating branches, opening PRs, or
  writing commit messages.
---

# Branch Naming Convention

When creating a new branch, always follow this pattern:
`{type}/{ticket-id}-{short-description}`

Types: feat, fix, chore, refactor, docs, test

## PR Descriptions

Always include:
1. Link to the ticket
2. Summary of changes (2-3 sentences)
3. Testing notes
4. Screenshots if UI changed

## Commit Messages

Use conventional commits: `type(scope): description`

When Claude encounters a task where this skill is relevant, it loads the SKILL.md into context and follows the instructions. The skill didn't do anything — it changed how Claude approaches the work.

Skills vs. Prompts

You might be thinking: "Isn't this just a system prompt?" Sort of, but with key differences:

  • Prompts are conversation-level. You write them for one-off tasks.
  • Skills are reusable and on-demand. They load dynamically when relevant, across any conversation or agent.
  • Skills can include supporting resources — scripts, templates, example files — that go beyond plain text instructions.

The mental model from Anthropic's own docs: Projects say "here's what you need to know." Skills say "here's how to do things."

Using Skills in the Agent SDK

Enable skills by adding "Skill" to your allowed tools and configuring setting sources:

options = ClaudeAgentOptions(
    setting_sources=["user", "project"],  # Discover skills from filesystem
    allowed_tools=["Skill", "Read", "Write", "Bash"],
)

Once configured, Claude automatically discovers skills from .claude/skills/ directories and invokes them when the task matches the skill's description.

The Power Combo: Skills + Tools

Skills and tools aren't competing — they're complementary. A skill might instruct Claude to use certain tools in specific ways. For example:

  • A code-review skill might tell Claude to always run grep for TODO and FIXME before reviewing, use bash to run the test suite, and structure its feedback in a specific format.
  • A database-migration skill might tell Claude to always back up before running migrations, use a specific naming pattern for migration files, and verify the rollback path.

The skill provides the expertise. The tools provide the capability. Together, they create a specialized agent.


MCP: The Universal Connector

MCP — the Model Context Protocol — is the standardized protocol that lets Claude (and other AI models) connect to external services and data sources. It's the bridge between Claude and everything else: databases, SaaS platforms, APIs, local tools, and file systems.

If tools are individual functions, MCP is the framework for exposing and discovering those functions.

How MCP Works

An MCP server exposes a set of tools (and optionally resources and prompts) over a standardized transport — typically stdio for local servers or SSE/HTTP for remote ones. Claude communicates with these servers using the MCP protocol, which handles:

  • Tool discovery — Claude can ask an MCP server what tools it offers
  • Tool invocation — Claude calls a tool with structured input and gets structured output
  • Resource access — MCP servers can expose data sources (files, database tables, API endpoints) that Claude can read

The Agent SDK supports MCP servers natively:

options = ClaudeAgentOptions(
    mcp_servers={
        "github": {
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-github"],
            "env": {"GITHUB_TOKEN": "..."}
        },
        "postgres": {
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://..."]
        }
    },
    allowed_tools=[
        "mcp__github__create_pull_request",
        "mcp__postgres__query"
    ]
)

MCP vs. Custom Tools

You can define tools directly in your application code or through MCP servers. Here's when to use which:

Use direct/custom tools when:

  • The tool is tightly coupled to your application logic
  • You want in-process execution (no IPC overhead)
  • The tool needs access to your application's state or memory

Use MCP servers when:

  • You're integrating with an external service (GitHub, Slack, databases)
  • You want reusable, portable tool packages
  • You want to share tool implementations across different agents or projects
  • A community MCP server already exists for your use case

The Token Cost of MCP

Every MCP server adds its tool definitions to Claude's context window, even when those tools are idle. This is where the token overhead problem gets real:

  • A typical MCP server adds 5-15 tools
  • Each tool definition costs ~500-2,000 tokens (name, description, JSON schema)
  • Five servers can easily consume 55,000+ tokens
  • Jira's MCP server alone uses ~17,000 tokens in definitions

This isn't just a cost problem — it's a quality problem. More tools in context means more opportunities for Claude to pick the wrong one.

Tool Search Tool: The Scaling Solution

Anthropic's answer to MCP sprawl is the Tool Search Tool. Instead of loading all tool definitions upfront, you mark tools with defer_loading: true. Claude only sees the Tool Search Tool itself plus your most critical always-loaded tools. When it needs a specific capability, it searches for relevant tools, and matching definitions get expanded into context on-demand.

The results are significant: 85% reduction in token usage and accuracy jumps from 49% to 74% (Opus 4) and 79.5% to 88.1% (Opus 4.5).

For CLI-based workflows, prefer native CLI tools over MCP when possible. Running gh pr create through Bash consumes zero persistent context — the tool definition for Bash is already loaded. An MCP GitHub server, by contrast, adds dozens of tool definitions to every turn.


The Comparison Table

DimensionToolsSkillsMCP
What it isA function Claude can callA knowledge pack Claude can loadA protocol for exposing tools
What it doesExecutes an action, returns a resultInjects instructions into contextConnects Claude to external services
AnalogyClaude's handsClaude's training manualThe electrical standard that lets any appliance plug in
Defined asJSON schema (name, description, input schema)SKILL.md file + optional resourcesServer exposing tools over a transport
Context cost~500-2,000 tokens per tool definitionLoaded on-demand when relevantProportional to number of exposed tools
PersistenceAlways present (unless deferred)Loaded dynamicallyServer runs continuously, definitions always present
ReusabilityTied to the application/SDK configPortable across conversations and agentsPortable across any MCP-compatible client
In the Agent SDKallowed_tools=["Read", "Bash", ...]setting_sources=["project"] + allowed_tools=["Skill"]mcp_servers={...}

Architecture Patterns

Pattern 1: Scoped Agent Runs (Minimal Context)

Best for: CI/CD agents, ticket-scoped automation, batch processing.

Load only the tools the agent needs for one specific task. No MCP servers, no skill discovery. Fast, cheap, predictable.

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Write", "Bash"],
    max_turns=10,
    max_budget_usd=0.50,
)

Pattern 2: Skilled Specialist

Best for: Code review, documentation generation, data analysis.

Combine a focused toolset with domain-specific skills. The skills teach Claude your team's standards, and the tools let Claude apply them.

options = ClaudeAgentOptions(
    setting_sources=["project"],
    allowed_tools=["Skill", "Read", "Grep", "Glob", "Bash"],
)

Pattern 3: Connected Agent (MCP-Heavy)

Best for: Workflow automation across multiple platforms.

Multiple MCP servers give Claude access to external services. Use Tool Search Tool to manage context overhead.

options = ClaudeAgentOptions(
    mcp_servers={
        "github": github_server,
        "slack": slack_server,
        "linear": linear_server,
    },
    allowed_tools=["Read", "Bash", "ToolSearch", "mcp__github__*"],
)

Pattern 4: Subagent Delegation

Best for: Complex multi-step workflows where different phases need different capabilities.

The parent agent has a broad view. It spawns subagents with scoped tools and skills for specific phases. Each subagent gets its own context window, preventing cross-contamination.

options = ClaudeAgentOptions(
    allowed_tools=["Agent", "Read", "Bash"],
    agents={
        "security-reviewer": {
            "description": "Reviews code for security issues",
            "allowed_tools": ["Read", "Grep", "Glob"],
            "model": "sonnet",
        },
        "test-writer": {
            "description": "Writes unit tests for changed code",
            "allowed_tools": ["Read", "Write", "Bash"],
        }
    }
)

Key Takeaways

  1. Tools are for doing, skills are for knowing, MCPs are for connecting. Don't conflate them. Each solves a different problem.

  2. Context window is your scarcest resource. Every tool definition, every skill loaded, every MCP server connected consumes tokens. More tokens consumed by overhead means less room for actual work — and measurably worse tool selection accuracy.

  3. Scope aggressively. The best agent architectures load only what's needed for the current task. If you're doing git operations, don't load your analytics MCP. If you're writing docs, you probably don't need the database tools.

  4. Prefer CLI tools over MCP for simple integrations. Running gh, aws, or sentry-cli through Bash adds zero persistent token overhead. Reserve MCP for services that need structured, multi-tool interactions.

  5. Skills compound over time. Every workflow you encode as a skill is a workflow you never have to explain again — across any conversation, any agent, any teammate using your project.

  6. Use Tool Search Tool beyond ~15-20 tools. Once you're connecting multiple MCP servers, the token overhead and accuracy degradation make on-demand discovery essential.

  7. Skills and tools are better together. A skill that teaches Claude your code review standards, combined with tools that let Claude actually read code and run tests, creates a specialist that's more than the sum of its parts.


Building agents is fundamentally about giving Claude the right capabilities (tools), the right knowledge (skills), and the right connections (MCPs) — then scoping each run to only what it needs. Get that balance right, and you get agents that are fast, accurate, and cost-effective. Get it wrong, and you're burning tokens on context overhead while Claude picks the wrong tool half the time.