MCP & Skills
Claude Code uses two complementary extension mechanisms: the Model Context Protocol (MCP) for connecting external tool servers and data sources, and the Skills system for reusable, composable slash command scripts.
What is MCP?
The Model Context Protocol is an open standard for connecting AI models to external tools and data sources. It defines a client-server architecture where:
- MCP Servers expose tools, resources, and prompts over a standardized protocol (JSON-RPC over stdio, SSE, or WebSocket).
- MCP Clients (Claude Code) discover and invoke these capabilities on behalf of the model.
- Tools, resources, and prompts are all first-class protocol concepts, enabling rich integrations without custom code in the client.
From Claude Code's perspective, an MCP tool is treated identically to a built-in tool at runtime, it goes through the same permission system, progress reporting, and rendering pipeline. The difference is that its call() implementation delegates to the MCP server via JSON-RPC.
How MCP Integrates
The MCP integration lives in services/mcp/. The key files are:
| File | Purpose |
|---|---|
client.ts | MCP SDK client wrapper; manages connection lifecycle |
MCPConnectionManager.tsx | React component managing connection state across all configured servers |
types.ts | TypeScript types: MCPServerConnection, ServerResource, config types |
config.ts | Load and merge MCP server configs from settings files |
auth.ts | OAuth flow for MCP servers that require authentication |
channelAllowlist.ts | Security: origin allowlist for bridge connections |
channelPermissions.ts | Per-channel permission rules for bridge-connected servers |
normalization.ts | Normalize MCP tool names and schemas to internal format |
officialRegistry.ts | Prefetch official MCP server registry from Anthropic |
InProcessTransport.ts | For MCP servers that run in-process (no subprocess) |
Connection Lifecycle
MCP Server Configuration
MCP servers are configured in ~/.claude/settings.json (global) or .claude/settings.json (project-scoped):
// ~/.claude/settings.json - MCP server configuration
{
"mcpServers": {
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
"env": {}
},
"github": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
},
"my-custom-api": {
"type": "sse",
"url": "https://my-company.internal/mcp",
"headers": {
"Authorization": "Bearer ${MY_API_TOKEN}"
}
}
}
}
Environment variable interpolation (${VAR_NAME}) is supported in MCP server configs via envExpansion.ts. This allows storing credentials in environment variables rather than hardcoding them in settings files, which is important if your settings are committed to version control.
MCP Resources
MCP servers can expose resources in addition to tools. Resources are read-only data sources (files, database records, API responses) that Claude can access via the ListMcpResourcesTool and ReadMcpResourceTool built-in tools:
// How Claude accesses MCP resources:
// 1. Discover available resources
// (uses ListMcpResourcesTool)
// → { uri: "file:///home/user/data.csv", name: "Sales Data", mimeType: "text/csv" }
// 2. Read a specific resource by URI
// (uses ReadMcpResourceTool)
// → Contents of the resource as text or base64-encoded binary
// resources are different from tools - they are accessed directly
// by URI without calling any server-side logic beyond the fetch itself
MCP Authentication
MCP servers that require authentication (e.g., a company's internal API) can implement the OAuth 2.0 flow via the MCP protocol's elicitation mechanism. When Claude Code encounters a tool call that returns error code -32042 (authentication required), it launches the OAuth flow:
- The MCP server returns
-32042with an authorization URL. - Claude Code opens the URL in the user's browser.
- After OAuth completion, the token is stored in the keychain.
- Future calls include the token in the MCP connection headers.
The McpAuthTool and elicitationHandler.ts implement this flow. In print/SDK mode, elicitations are surfaced as structured events rather than UI dialogs.
The Skills System
Skills are the scripting layer of Claude Code. A skill is a markdown file (with optional YAML frontmatter) that defines a reusable slash command. Skills live in ~/.claude/skills/ (global), .claude/skills/ (project), or are bundled with the tool itself (src/skills/bundled/).
When a user types /commit, the skill system:
- Looks up the skill file matching "commit".
- Reads and parses the skill's markdown template.
- Expands any template variables (
$ARGUMENTS,$CWD, etc.). - Submits the expanded prompt as a user message to the query pipeline.
Skill File Format
---
# skills/commit.md - skill frontmatter
name: commit
description: Create a git commit with a smart message
aliases:
- c
- git-commit
# Arguments this skill accepts (for autocomplete and help)
arguments:
- name: message
description: Optional commit message override
required: false
---
Review the git diff and create a well-structured commit message.
Focus on the "why" not the "what". Format as:
<type>(<scope>): <short description>
<body if needed>
Then run: `git commit -m "..."` with the generated message.
$ARGUMENTS
Template Variables
| Variable | Value |
|---|---|
$ARGUMENTS | Any text the user typed after the slash command name |
$CWD | Current working directory path |
$SELECTION | Currently selected text (in IDE integrations) |
Bundled Skills
Claude Code ships with a set of bundled skills in src/skills/bundled/. These are compiled into the binary and available without any configuration:
| Skill | Description |
|---|---|
batch.ts | Run multiple tasks in parallel as separate subagent calls. |
claudeApi.ts | Integration helpers for building apps with the Claude API. |
commit.ts | Smart git commit with AI-generated commit message following conventional commits. |
index.ts | Skill registry/index; lists all available skills. |
keybindings.ts | Helper for customizing Claude Code keyboard bindings. |
loop.ts | Run a prompt or skill on a recurring interval (polling pattern). |
loremIpsum.ts | Generate placeholder text, useful for testing layouts. |
remember.ts | Save facts or instructions to persistent memory. |
scheduleRemoteAgents.ts | Create, list, and manage scheduled remote agent triggers. |
simplify.ts | Review changed code for quality and refactoring opportunities. |
skillify.ts | Convert a prompt or workflow into a reusable skill file. |
stuck.ts | Get unstuck: analyze what's blocking progress and suggest approaches. |
updateConfig.ts | Configure Claude Code settings via natural language description. |
verify.ts | Verify a claim or implementation against tests and specifications. |
verifyContent.ts | Verify that content (docs, comments) matches the actual code behavior. |
claudeApiContent.ts | Generate content using the Claude API with streaming. |
claudeInChrome.ts | Integration with Claude's Chrome extension. |
debug.ts | Step through a debugging workflow systematically. |
Writing Your Own Skill
Creating a custom skill is straightforward. Here is a complete example of a skill that performs a security review of changed files:
---
name: security-check
description: Review changed files for security vulnerabilities
aliases:
- sec
- security
arguments:
- name: files
description: Specific files to check (defaults to git diff)
required: false
---
Perform a security review of the following changes.
Check for:
1. **Injection vulnerabilities**, SQL injection, shell injection, XSS
2. **Authentication issues**, missing auth checks, JWT misuse
3. **Secrets in code**, API keys, passwords, tokens hardcoded
4. **Dependency vulnerabilities**, outdated packages with CVEs
5. **Input validation**, missing sanitization of user inputs
6. **Path traversal**, unvalidated file paths
7. **Cryptographic issues**, weak algorithms, improper key handling
For each finding, rate severity (LOW/MEDIUM/HIGH/CRITICAL) and suggest a fix.
$ARGUMENTS
Save this as ~/.claude/skills/security-check.md (global) or .claude/skills/security-check.md (project-only). It will be available as /security-check (or /sec via the alias) in any Claude Code session.
Skill Discovery and Loading
Skills are loaded by skills/loadSkillsDir.ts, which scans skill directories and builds a registry. The bundledSkills.ts file exports the pre-compiled bundled skills. At runtime, the skill registry is merged from all sources: user global, project-local, and bundled.
When the EXPERIMENTAL_SKILL_SEARCH feature flag is enabled, services/skillSearch/prefetch.js runs at turn start to pre-index the skills directory for semantic search. This allows the model to discover and invoke skills based on intent rather than exact command names.
MCP-Based Skills
The skills/mcpSkillBuilders.ts file enables skills to be exposed as MCP tools. This means a skill defined in your ~/.claude/skills/ directory can be made available to any MCP client, not just Claude Code's own REPL. This is the bridge between the simple markdown-skill format and the full MCP ecosystem.
// skills/mcpSkillBuilders.ts - exposes skills as MCP tools
export function buildMCPSkillTool(skill: SkillDefinition): MCPToolDefinition {
return {
name: skill.name,
description: skill.description,
inputSchema: {
type: 'object',
properties: {
arguments: {
type: 'string',
description: 'Arguments to pass to the skill',
},
},
},
// When called, expands the skill template and submits it
handler: async ({ arguments: args }) => {
const expanded = expandSkillTemplate(skill.content, args)
return { content: expanded }
},
}
}
Skills are a lightweight alternative to full MCP server development for many use cases. If you need to give Claude Code a repeatable workflow (code review, deployment checklist, commit message format), a skill file is often the right tool. Only build a full MCP server when you need real-time data access, persistent state, or tools that non-Claude clients also need.
MCP vs. Skills: When to Use Each
| Consideration | Use MCP Server | Use a Skill |
|---|---|---|
| Real-time data access | ✓ Database, APIs, live data | - Static templates only |
| Complex server logic | ✓ Computation, transformations | - Delegates to Claude |
| Other AI clients | ✓ Works with any MCP client | - Claude Code only |
| Setup complexity | High (Node.js server, deployment) | Low (single markdown file) |
| Reusable prompts | - Overkill | ✓ Perfect fit |
| Team sharing | ✓ Via server URL | ✓ Via project .claude/skills/ |
| Version control | ✓ Server source code | ✓ Markdown files in repo |