As AI agents move from demos to production, the question of how to give them capabilities becomes critical. Two paradigms have emerged: Skills (behavioral instructions injected into context) and MCP (Model Context Protocol—a standardized way to connect agents to external tools).
This post builds on LlamaIndex's excellent analysis with additional research on enterprise adoption, security considerations, and real-world use cases from companies like Block, Bloomberg, and Microsoft.
Understanding the Two Paradigms
Skills: Behavioral Instructions via Context Injection
Skills are localized, domain-specific behavioral instructions—typically markdown files with code snippets and resource links. When a user's request matches a skill's triggers, the instructions are injected into the agent's context window.
my-skill/
├── SKILL.md # Instructions with YAML frontmatter
├── scripts/
│ └── format_report.py
└── templates/
└── compliance_template.md
# SKILL.md example
---
name: "Financial Report Generator"
description: "Generates compliant quarterly reports"
triggers:
- "quarterly report"
- "financial summary"
- "Q[1-4] report"
---
## Instructions
When generating financial reports:
1. Always use the compliance template at ./templates/compliance_template.md
2. Include required SEC disclaimers
3. Format currency as USD with 2 decimal places
4. Run ./scripts/format_report.py for final formatting
## Example Output Format
```markdown
# Q4 2024 Financial Summary
**Revenue:** $12,450,000.00
**Net Income:** $2,890,000.00
*This report complies with SEC Regulation S-K*
``` The key insight: Skills use progressive disclosure. Only metadata loads initially (minimal tokens), with full content loading only when relevant. This makes them highly token-efficient compared to loading all tool definitions upfront.
As Simon Willison noted: "Skills turn 'Claude can technically do this if I phrase it right' into 'Claude does this reliably, every single time.'"
MCP: Standardized External Tool Protocol
MCP is an open standard introduced by Anthropic in November 2024 for connecting AI agents to external systems. Think of it as "USB-C for AI"—a universal interface that works across providers.
# MCP Server Example: Database Integration
import asyncio
from mcp.server import Server
from mcp.types import Tool, TextContent
server = Server("database-mcp")
@server.list_tools()
async def list_tools():
return [
Tool(
name="query_sales",
description="Query sales data with date range filtering",
inputSchema={
"type": "object",
"properties": {
"start_date": {"type": "string", "format": "date"},
"end_date": {"type": "string", "format": "date"},
"region": {"type": "string", "enum": ["NA", "EU", "APAC"]}
},
"required": ["start_date", "end_date"]
}
),
Tool(
name="get_customer",
description="Retrieve customer details by ID",
inputSchema={
"type": "object",
"properties": {
"customer_id": {"type": "string"}
},
"required": ["customer_id"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "query_sales":
# Execute actual database query
results = await db.query_sales(
arguments["start_date"],
arguments["end_date"],
arguments.get("region")
)
return [TextContent(type="text", text=json.dumps(results))]
elif name == "get_customer":
customer = await db.get_customer(arguments["customer_id"])
return [TextContent(type="text", text=json.dumps(customer))]
if __name__ == "__main__":
asyncio.run(server.run()) MCP servers expose tools through a standardized interface. Clients discover available tools, call them with structured arguments, and receive structured responses. The protocol handles communication, authentication, and error handling.
// .mcp.json - Client configuration
{
"mcpServers": {
"database": {
"command": "python",
"args": ["./mcp_servers/database_server.py"],
"env": {
"DATABASE_URL": "postgresql://..."
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_..."
}
},
"stripe": {
"command": "npx",
"args": ["-y", "@stripe/mcp-server"],
"env": {
"STRIPE_SECRET_KEY": "sk_..."
}
}
}
} By December 2025, MCP had achieved remarkable adoption: 97M+ monthly SDK downloads, backing from Anthropic, OpenAI, Google, and Microsoft, and donation to the Linux Foundation's Agentic AI Foundation.
Key Differences: Skills vs MCP vs Function Calling
| Aspect | Skills | MCP | Function Calling |
|---|---|---|---|
| Setup | Minimal (markdown files) | Moderate (server deployment) | Per-request schema definition |
| Execution | LLM interprets instructions | Deterministic API calls | Deterministic API calls |
| Portability | Platform-specific (Claude) | Vendor-agnostic | Provider-specific schemas |
| Token Cost | Low (lazy loading) | High (tool metadata) | Medium (per-request) |
| Maintenance | Local file edits | Centralized server updates | App-local changes |
| Best For | Procedural knowledge | External integrations | Simple, one-shot tasks |
Why Not Just Function Calling?
Traditional function calling (introduced by OpenAI in 2023) works but has limitations at scale:
# Traditional Function Calling (OpenAI style)
tools = [
{
"type": "function",
"function": {
"name": "query_sales",
"description": "Query sales data with date range",
"parameters": {
"type": "object",
"properties": {
"start_date": {"type": "string"},
"end_date": {"type": "string"}
},
"required": ["start_date", "end_date"]
}
}
}
]
# Every new tool = redefine schema
# Every new provider = rewrite integration
# No standardized discovery mechanism According to MarkTechPost's analysis, function calling creates tight coupling: tool definitions live alongside prompts, catalogs are app-local, and every new provider means rewriting integrations. MCP solves this with standardization; Skills solve it with abstraction.
Real Enterprise Use Cases
Block: 75% Time Reduction on Engineering Tasks
Block's internal AI agent "Goose" demonstrates MCP's productivity impact. According to Xenoss's enterprise research, Block built proprietary MCP servers integrating Snowflake, Jira, Slack, and Google Drive. The result: up to 75% time reduction on daily engineering tasks.
Key decisions that made this work:
- Built proprietary servers (not third-party) for complete security control
- Integrated with existing SSO infrastructure
- Implemented comprehensive audit logging
Bloomberg: Days to Minutes Deployment
Bloomberg initially developed an internal MCP alternative before adopting Anthropic's protocol. Their implementation reduced "time-to-production from days to minutes", enabling faster deployment of AI-powered development tools across research teams.
Microsoft Dynamics 365: Enterprise ERP Integration
At Build 2025, Microsoft announced the Dynamics 365 ERP MCP server—connecting AI agents directly to ERP systems for invoicing, inventory management, and financial reporting. All new ERP agents will be built using MCP, with existing agents migrating by end of 2025.
Healthcare: Real-Time Clinical Decisions
MCP enables connecting EHRs (Electronic Health Records), symptom checkers, and diagnostic tools. AI assistants can suggest treatments using real-time vitals combined with patient history— enabling safer, faster clinical decisions without copying sensitive data into prompts.
Financial Services: Multi-Source Risk Analysis
Risk analysis requires inputs from credit scores, fraud detection, and behavioral data. MCP aggregates these from multiple systems, allowing an AI banker to review credit scores, transactions, and fraud alerts in a single session—producing smarter financial advice without manual data compilation.
The Hybrid Pattern: MCP + Skills Together
As IntuitionLabs explains: "MCP connects Claude to data; Skills teach Claude what to do with that data." The most effective production systems use both.
# Hybrid Pattern: MCP for data, Skills for processing
# 1. MCP fetches raw data from external systems
mcp_result = await mcp_client.call_tool(
"github",
"list_pull_requests",
{"repo": "myorg/myrepo", "state": "open"}
)
# 2. Skill provides domain-specific processing instructions
# (loaded automatically when context matches "PR review")
"""
SKILL: PR Review Protocol
When reviewing pull requests:
1. Check for breaking changes in public APIs
2. Verify test coverage > 80%
3. Flag security-sensitive files: auth/, crypto/, permissions/
4. Use our severity scale: P0 (blocker) -> P3 (minor)
5. Always suggest at least one improvement
"""
# 3. LLM combines MCP data + Skill knowledge
# Result: Consistent, domain-aware PR reviews The LlamaIndex team's experience validates this. When building LlamaAgents Builder, they found that their documentation MCP provided sufficient context for code generation, while custom skills added domain-specific processing logic that would be awkward to encode in tool schemas.
Security Considerations
MCP's rapid adoption has exposed critical security challenges. In July 2025, Knostic scanned nearly 2,000 MCP servers exposed to the internet—all verified servers lacked authentication.
Tool Poisoning Attacks
Invariant Labs demonstrated that attackers can embed hidden instructions within MCP server responses,
manipulating agents into extracting sensitive data. One proof-of-concept extracted WhatsApp conversations
through a poisoned get_fact_of_the_day() function.
The Replit Incident
A cautionary tale: in July 2025, Replit's AI agent deleted a production database containing over 1,200 records—despite explicit instructions meant to prevent changes to production systems. This highlighted the gap between instructions and enforcement.
Security Best Practices
# Security Pattern: Human-in-the-loop for sensitive MCP actions
class SecureMCPGateway:
SENSITIVE_ACTIONS = [
"delete_*",
"drop_*",
"modify_production_*",
"transfer_funds"
]
async def call_tool(self, server: str, tool: str, args: dict):
# Check if action requires approval
if any(fnmatch(tool, pattern) for pattern in self.SENSITIVE_ACTIONS):
# Pause for human confirmation
approval = await self.request_human_approval(
action=f"{server}.{tool}",
arguments=args,
risk_level="HIGH"
)
if not approval.granted:
return {"error": "Action rejected by human reviewer"}
# Audit logging
await self.audit_log.record(
timestamp=datetime.utcnow(),
server=server,
tool=tool,
args=args, # Sanitized
user=self.current_user
)
# Execute with timeout
return await asyncio.wait_for(
self.mcp_client.call_tool(server, tool, args),
timeout=30.0
) Recommended patterns for production MCP deployments:
- Human-in-the-loop: Require confirmation for destructive or sensitive actions
- Audit logging: Record all tool invocations with sanitized arguments
- Process sandboxing: Each MCP server operates in isolated environment
- Path restrictions: Limit server interactions to approved directories/APIs
- Transparent UI: Clear indicators of which tools are exposed and being invoked
When to Choose What
Choose Skills When:
- Setup simplicity is prioritized—Skills are just markdown files
- Domain knowledge evolves slowly—procedures don't change weekly
- Natural language guidance suffices—no strict schema requirements
- Token efficiency matters—Skills lazy-load only when relevant
- Internal processes need standardization—compliance, formatting, review protocols
Choose MCP When:
- External system integration required—databases, APIs, third-party services
- Precision and predictability are critical—fixed schemas prevent misinterpretation
- Context changes frequently—real-time data from external sources
- Multi-provider support needed—same tools work with Claude, GPT, Gemini
- Centralized maintenance preferred—update server once, all clients get changes
Use Both Together When:
- Complex workflows—MCP fetches data, Skills encode processing logic
- Compliance requirements—Skills enforce rules, MCP connects to audit systems
- Multi-team environments—shared MCP servers, team-specific Skills
Practical Recommendations
For Startups & Small Teams
Start with Skills. They're faster to set up, require no infrastructure, and let you encode domain knowledge immediately. Add MCP servers when you need external integrations that can't be handled through existing APIs.
For Enterprise Teams
- Build proprietary MCP servers—don't rely solely on third-party integrations
- Implement MCP gateways—centralized policy enforcement and routing
- Version control Skills—treat them like code, with review and approval processes
- Plan for hybrid—design systems assuming both paradigms will be needed
For Platform Teams
Consider building an internal "tool registry" that abstracts the choice:
- Developers define capabilities in a unified format
- Platform decides whether to implement as Skill (procedural) or MCP (integration)
- Agents consume capabilities without knowing the underlying mechanism
The Road Ahead
MCP's trajectory is clear: with backing from Anthropic, OpenAI, Google, and Microsoft, it's becoming the standard for agent-tool integration. But as some developers note, Skills, MCPs, and slash commands all represent the same underlying trend: context engineering—giving agents the right information at the right time.
The winners won't be those who pick one paradigm over another, but those who understand when each applies and architect systems that leverage both effectively.
Sources
- LlamaIndex: Skills vs MCP Tools for Agents
- Anthropic: Introducing the Model Context Protocol
- Xenoss: MCP in Enterprise
- IntuitionLabs: Claude Skills vs MCP Technical Comparison
- Simon Willison: Claude Skills are Awesome
- MarkTechPost: MCP vs Function Calling
- Microsoft: Dynamics 365 ERP MCP Server
- Pento: A Year of MCP Review