A reference manual for people who design and build MCP (Model Context Protocol) ecosystems
A reference manual for people who design and build MCP (Model Context Protocol) ecosystems
A reference manual for people who design and build MCP (Model Context Protocol) ecosystems
The Three Sacred Objects
The Three Sacred Objects
The Three Sacred Objects
Tools, Resources, and Prompts walk into a bar • Understanding the trinity of MCP capabilities • How each piece plays its part in the grand orchestra
Tools, Resources, and Prompts walk into a bar • Understanding the trinity of MCP capabilities • How each piece plays its part in the grand orchestra
Tools, Resources, and Prompts walk into a bar • Understanding the trinity of MCP capabilities • How each piece plays its part in the grand orchestra
The Periodic Table of AI Interaction
The Periodic Table of AI Interaction
Every breakthrough in science starts with classification. Mendeleev didn't discover elements he discovered that elements had patterns. Darwin didn't discover species he discovered that species had relationships.
Every breakthrough in science starts with classification. Mendeleev didn't discover elements he discovered that elements had patterns. Darwin didn't discover species he discovered that species had relationships.
Anthropic didn't invent AI interactions they discovered that every interaction falls into exactly three categories:
Anthropic didn't invent AI interactions they discovered that every interaction falls into exactly three categories:



Resources

Things AI can observe
(READ)



Tools

Things AI can manipulate (WRITE/EXECUTE



Prompt

Things humans can invoke (TEMPLATES)
API Call
API Call
That's it. Every API call, every integration, every "Can AI do X?" question they all reduce to these three primitives. It's chemistry-level fundamental.
That's it. Every API call, every integration, every "Can AI do X?" question they all reduce to these three primitives. It's chemistry-level fundamental.
// The entire universe of AI interaction in 3line type Resource = { read: () => Data } type Tool = { execute: (params) => Result } type Prompt = { template: string, args: Schema }
Resources: The Observable Universe
Resources: The Observable Universe
Resources are MCP's way of saying
Resources are MCP's way of saying
"look, but don't touch."
"look, but don't touch."
They're the read-only windows into your world files, databases, APIs, anything that has state you want to observe
The genius? Resources use URIs the same concept that makes the web work. Your AI doesn't need to know how to read Postgres vs. Notion vs. files. It just needs to know how to ask for a URI.
Here's what declaring a resource actually looks like
They're the read-only windows into your world files, databases, APIs, anything that has state you want to observe
The genius? Resources use URIs the same concept that makes the web work. Your AI doesn't need to know how to read Postgres vs. Notion vs. files. It just needs to know how to ask for a URI.
Here's what declaring a resource actually looks like
Initialize Resources
Initialize Resources
{ "jsonrpc": "2.0", "method": "resources/list", "result": { "resources": [ { "uri": "file:///workspace/src", "name": "Source Code", "mimeType": "text/x-directory", "description": "Project source files" }, { "uri": "postgres://analytics/customers", "name": "Customer Data", "mimeType": "application/x-postgres-table", "description": "Read-only customer analytics" }, { "uri": "notion://pages/roadmap", "name": "Product Roadmap", "mimeType": "text/markdown", "description": "Current quarter planning" } ] } }
Real Implementation: File System Resource
Real Implementation: File System Resource
File System
File System
class FileSystemResource implements MCPResource { async read(uri: string): Promise<ResourceContent> { const path = uri.replace('file://', ''); // Security: Validate path is within allowed directory if (!path.startsWith(this.basePath)) { throw new Error('Access denied: Path outside workspace'); } const stats = await fs.stat(path); if (stats.isDirectory()) { const entries = await fs.readdir(path); return { mimeType: 'text/x-directory', data: entries.map(entry => ({ name: entry, uri: `file://${path}/${entry}` })) }; } else { const content = await fs.readFile(path, 'utf-8'); return { mimeType: mime.lookup(path) || 'text/plain', data: content }; } } }



project-modiqo
├── index.ts
├── utils.ts
└── config.ts
3.1 Tree Foldering
3.1 Tree Foldering
Tools: The Instruments of Change
Tools: The Instruments of Change
If Resources are the eyes of MCP, Tools are the hands. They're how AI takes action in the world—but with great power comes great protocol design. Every tool must declare:
If Resources are the eyes of MCP, Tools are the hands. They're how AI takes action in the world—but with great power comes great protocol design. Every tool must declare:
1. What it does
2. What parameters it needs
3. What it returns
4. What could go wrong
1. What it does
2. What parameters it needs
3. What it returns
4. What could go wrong
Instrument Json
{ "name": "send_slack_message", "description": "Post a message to a Slack channel", "inputSchema": { "type": "object", "properties": { "channel": { "type": "string", "description": "Channel name (without #)", "pattern": "^[a-z0-9-_]+$" }, "message": { "type": "string", "description": "Message text (supports basic markdown)", "maxLength": 4000 }, "thread_ts": { "type": "string", "description": "Optional: Thread timestamp to reply to" } }, "required": ["channel", "message"] }, "returnSchema": { "type": "object", "properties": { "ts": { "type": "string" }, "channel": { "type": "string" }, "permalink": { "type": "string" } } } }
The Tool Lifecycle
The Tool Lifecycle
// 1. AI decides to use a tool const decision = await ai.analyze("User wants to notify team about deployment"); // → "I should send a Slack message" // 2. AI prepares tool call const toolCall = { jsonrpc: "2.0", method: "tools/call", params: { name: "send_slack_message", arguments: { channel: "deployments", message: "🚀 Deployment to production completed successfully!" } }, id: "call_001" }; // 3. MCP validates against schema validator.validate(toolCall.params.arguments, tool.inputSchema); // ✓ Valid // 4. Server executes tool const result = await slackAPI.postMessage({ channel: "#deployments", text: toolCall.params.arguments.message }); // 5. Return standardized response { jsonrpc: "2.0", result: { ts: "1234567890.123456", channel: "C1234567890", permalink: "https://slack.com/archives/C1234567890/p1234567890123456" }, id: "call_001" }





3.2 Live Cycle
3.2 Live Cycle
Real-World Tool: Database Query Tool
Real-World Tool: Database Query Tool
class DatabaseQueryTool(MCPTool): def __init__(self, connection_string: str): self.db = psycopg2.connect(connection_string) @property def schema(self): return { "name": "query_database", "description": "Execute read-only SQL queries", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "SQL query (SELECT only)" }, "params": { "type": "array", "description": "Query parameters for safety" } }, "required": ["query"] } } async def execute(self, arguments: dict) -> dict: query = arguments["query"] params = arguments.get("params", []) # Security: Only allow SELECT statements if not query.strip().upper().startswith("SELECT"): raise PermissionError("Only SELECT queries allowed") # Security: Use parameterized queries cursor = self.db.cursor() cursor.execute(query, params) columns = [desc[0] for desc in cursor.description] rows = cursor.fetchall() return { "columns": columns, "rows": rows, "rowCount": len(rows) }





3.3 Query Tool
3.3 Query Tool
Prompts: The Human Touch
Prompts: The Human Touch
Prompts are MCP's most misunderstood primitive. They're not AI prompts—they're human prompts. They're templates for common workflows that users can invoke.Think of Prompts as "recipes" that combine Resources and Tools into meaningful actions:
Prompts are MCP's most misunderstood primitive. They're not AI prompts—they're human prompts. They're templates for common workflows that users can invoke.Think of Prompts as "recipes" that combine Resources and Tools into meaningful actions:
1. Check my GitHub commits
2. Review completed Jira tickets
3. ...
1. Check my GitHub commits
2. Review completed Jira tickets
3. ...
{ "name": "daily_standup", "description": "Generate daily standup report", "arguments": [ { "name": "date", "description": "Date for standup (defaults to today)", "required": false } ], "template": ` Please generate my daily standup report for {date}: 1. Check my GitHub commits: @{tool:list_commits date={date}} 2. Review completed Jira tickets: @{tool:query_jira status=done date={date}} 3. Read my calendar: @{resource:calendar://today} 4. Check Slack mentions: @{tool:search_slack mentions=true date={date}} Format as: - What I did yesterday - What I'm doing today - Any blockers ` }
Prompt Expansion
Prompt Expansion
// User says: "Run my daily standup" const prompt = await mcp.getPrompt("daily_standup"); const expanded = await prompt.expand({ date: "2025-03-15" }); // MCP expands the template: /* Please generate my daily standup report for 2025-03-15: 1. Check my GitHub commits: [ { sha: "abc123", message: "Fixed auth bug" }, { sha: "def456", message: "Updated dependencies" } ] 2. Review completed Jira tickets: [ { key: "PROJ-123", summary: "Implement MCP integration" } ] 3. Read my calendar: [ { time: "10am", title: "Architecture Review" }, { time: "2pm", title: "1:1 with Sarah" } ] 4. Check Slack mentions: [ { channel: "engineering", message: "Great work on the MCP docs!" } ] Format as: - What I did yesterday - What I'm doing today - Any blockers */





3.4 Prompt Expansion
3.4 Prompt Expansion
The Symphony of Integration
The Symphony of Integration
The real magic happens when all three work together. Here's a complete MCP workflow in action:
The real magic happens when all three work together. Here's a complete MCP workflow in action:
// A code review workflow combining all three primitives // 1. RESOURCE: Read the pull request const pr = await mcp.getResource("github://pulls/123"); /* { title: "Add MCP integration", files: ["src/mcp/client.ts", "src/mcp/server.ts"], diff: "...", author: "sarah" } */ // 2. RESOURCE: Read related files const context = await mcp.getResource("file:///workspace/src/mcp"); /* { structure: ["client.ts", "server.ts", "types.ts"], content: { ... } } */ // 3. TOOL: Run tests const testResults = await mcp.callTool("run_tests", { files: pr.files }); /* { passed: 47, failed: 0, coverage: 94.2 } */ // 4. TOOL: Static analysis const lintResults = await mcp.callTool("eslint", { files: pr.files }); /* { errors: 0, warnings: 2, details: [...] } */ // 5. PROMPT: Generate review const review = await mcp.expandPrompt("code_review", { pr: pr, context: context, tests: testResults, lint: lintResults }); // 6. TOOL: Post review await mcp.callTool("post_github_review", { pr_id: 123, review: review.content });



Resources
Resources
Tools
Tools
Prompt
Prompt
3.5 Workflow
3.5 Workflow
Security: The Fourth Dimension
Security: The Fourth Dimension
Resource Security
{ "uri": "postgres://analytics/customers", "permissions": { "read": true, "write": false, "allowed_queries": ["SELECT"], "denied_fields": ["ssn", "credit_card"], "rate_limit": "100/hour" } }
Tool Security
{ "name": "send_email", "permissions": { "require_confirmation": true, "allowed_domains": ["@company.com"], "max_recipients": 10, "rate_limit": "20/day", "audit_log": true } }
Prompt Security
{ "name": "send_email", "permissions": { "require_confirmation": true, "allowed_domains": ["@company.com"], "max_recipients": 10, "rate_limit": "20/day", "audit_log": true } }
Real Production Example: Customer Support Bot
Real Production Example: Customer Support Bot
Here's how a real company uses all three primitives:
Here's how a real company uses all three primitives:
# Resources: Read-only access to support data resources = [ MCPResource( uri="zendesk://tickets/open", name="Open Support Tickets" ), MCPResource( uri="postgres://knowledge_base", name="Help Articles" ), MCPResource( uri="slack://channels/customer-support", name="Support Channel History" ) ] # Tools: Actions the bot can take tools = [ MCPTool( name="update_ticket", schema={ "status": ["open", "pending", "resolved"], "priority": ["low", "normal", "high", "urgent"] } ), MCPTool( name="send_response", schema={ "ticket_id": "string", "message": "string", "attachments": "array" } ) ] # Prompts: Common support workflows prompts = [ MCPPrompt( name="escalate_to_human", template=""" Escalate ticket {ticket_id} to human support: 1. Read ticket: @{resource:zendesk://tickets/{ticket_id}} 2. Find similar resolved tickets: @{tool:search_similar} 3. Update priority: @{tool:update_ticket priority=high} 4. Notify team: @{tool:send_slack_message channel=urgent-support} Include context about why escalation is needed. """ ) ] # In action: async def handle_support_ticket(ticket_id: str): # Resource: Read the ticket ticket = await mcp.get_resource(f"zendesk://tickets/{ticket_id}") # Resource: Search knowledge base articles = await mcp.get_resource( f"postgres://knowledge_base?q={ticket.subject}" ) if articles: # Tool: Send automated response await mcp.call_tool("send_response", { "ticket_id": ticket_id, "message": f"Found {len(articles)} relevant help articles", "attachments": [a.url for a in articles] }) else: # Prompt: Escalate to human await mcp.expand_prompt("escalate_to_human", { "ticket_id": ticket_id })
3.6 Working customer support
3.6 Working customer support
The State of the Art
The State of the Art
As of March 2025, here's what the three primitives have enabled:
As of March 2025, here's what the three primitives have enabled:
Resource Implementations
File Systems
Local, S3, Google Drive, Dropbox
Local, S3, Google Drive, Dropbox
Local, S3, Google Drive, Dropbox
Databases
Postgres, MySQL, MongoDB, Redis
Postgres, MySQL, MongoDB, Redis
Postgres, MySQL, MongoDB, Redis
APIs
Stripe, Twilio, OpenWeatherMap
Stripe, Twilio, OpenWeatherMap
Stripe, Twilio, OpenWeatherMap
Dev Tools
Git, Docker, Kubernetes
Git, Docker, Kubernetes
Git, Docker, Kubernetes
Tool
Implementations
Communication
Email, Slack, Discord, Teams
Email, Slack, Discord, Teams
Email, Slack, Discord, Teams
Development
Compile, Test, Deploy, Rollback
Compile, Test, Deploy, Rollback
Compile, Test, Deploy, Rollback
Business
Create Invoice, Update CRM, Generate Report
Create Invoice, Update CRM, Generate Report
Create Invoice, Update CRM, Generate Report
Creative
Generate Image, Edit Video, Compose Music
Generate Image, Edit Video, Compose Music
Generate Image, Edit Video, Compose Music
Prompt
Libraries
Engineering
Code Review, Debug Session, Architecture Design
Code Review, Debug Session, Architecture Design
Code Review, Debug Session, Architecture Design
Business
Sales Followup, Quarterly Review, Risk Assessment
Sales Followup, Quarterly Review, Risk Assessment
Sales Followup, Quarterly Review, Risk Assessment
Personal
Daily Planning, Learning Path, Health Check
Daily Planning, Learning Path, Health Check
Daily Planning, Learning Path, Health Check
3.7 Table State
3.7 Table State
