MCP Learning Project - Complete Guide
This is a comprehensive tutorial project that teaches Model Context Protocol (MCP) development from beginner to advanced levels. You'll learn both server-side (backend) and client-side (frontend) development.
๐ฏ What You'll Learn
Beginner Level:
- โ Basic MCP server structure and concepts
- โ Simple tool creation and registration
- โ Parameter handling and validation
- โ Basic client connection and tool calling
Intermediate Level:
- โ State management between tool calls
- โ Resource management (serving data to AI)
- โ Data processing and complex operations
- โ Client-server communication patterns
Advanced Level:
- โ CRUD operations with persistent state
- โ Comprehensive error handling
- โ Prompt templates for AI interactions
- โ Best practices and production considerations
๐ Project Structure
mcp-learning-project/
โโโ src/
โ โโโ server.ts # MCP Learning Server (backend)
โ โโโ client.ts # MCP Learning Client (frontend)
โโโ dist/ # Compiled JavaScript
โโโ package.json # Dependencies and scripts
โโโ tsconfig.json # TypeScript configuration
โโโ README.md # This file
๐ Quick Start
1. Setup Project
# Create project directory
mkdir mcp-learning-project
cd mcp-learning-project
# Initialize npm project
npm init -y
# Install dependencies
npm install @modelcontextprotocol/sdk
# Install dev dependencies
npm install --save-dev typescript @types/node tsx
2. Create Package.json
{
"name": "mcp-learning-project",
"version": "1.0.0",
"description": "Learn MCP development from beginner to advanced",
"main": "dist/server.js",
"type": "module",
"scripts": {
"build": "tsc",
"start:server": "node dist/server.js",
"start:client": "node dist/client.js dist/server.js",
"dev:server": "tsx src/server.ts",
"dev:client": "tsx src/client.ts dist/server.js",
"demo": "npm run build && npm run start:client"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^0.4.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"tsx": "^4.0.0",
"typescript": "^5.0.0"
}
}
3. Create TypeScript Config
Create tsconfig.json
:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
4. Save the Code Files
- Save the MCP Learning Server code as
src/server.ts
- Save the MCP Learning Client code as
src/client.ts
5. Build and Run
# Build the project
npm run build
# Run the interactive client (this will also start the server)
npm run demo
๐ Learning Path
Phase 1: Understanding the Basics
Start the interactive client:
npm run demo
Try basic commands:
mcp-learning> help mcp-learning> tools mcp-learning> call hello_world {"name": "Alice"}
Learn about resources:
mcp-learning> resources mcp-learning> read mcp-concepts
Phase 2: Hands-on Practice
Run the beginner demo:
mcp-learning> demo beginner
Practice tool calls:
mcp-learning> call calculator {"operation": "add", "a": 5, "b": 3} mcp-learning> call calculator {"operation": "divide", "a": 10, "b": 0}
Understand state management:
mcp-learning> call counter {"action": "get"} mcp-learning> call counter {"action": "increment", "amount": 5} mcp-learning> call counter {"action": "get"}
Phase 3: Advanced Concepts
Run intermediate demo:
mcp-learning> demo intermediate
Work with complex data:
mcp-learning> call data_processor {"data": [5, 2, 8, 1, 9], "operation": "sort"} mcp-learning> call data_processor {"data": [5, 2, 8, 1, 9], "operation": "average"}
CRUD operations:
mcp-learning> call task_manager {"action": "create", "task": {"title": "Learn MCP", "priority": "high"}} mcp-learning> call task_manager {"action": "list"}
Phase 4: Production Ready
Run advanced demo:
mcp-learning> demo advanced
Learn error handling:
mcp-learning> call error_demo {"error_type": "none"} mcp-learning> call error_demo {"error_type": "validation"}
Study best practices:
mcp-learning> read best-practices
๐ง Key Concepts Explained
1. MCP Server (Backend)
The server provides capabilities to AI models:
// Server setup
const server = new Server({
name: 'my-server',
version: '1.0.0'
}, {
capabilities: {
tools: {}, // Functions AI can call
resources: {}, // Data AI can read
prompts: {} // Templates AI can use
}
});
// Tool registration
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'my_tool',
description: 'What this tool does',
inputSchema: { /* JSON Schema */ }
}
]
}));
// Tool implementation
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
// Process the tool call and return results
return {
content: [{
type: 'text',
text: 'Tool response'
}]
};
});
2. MCP Client (Frontend)
The client connects to servers and uses their capabilities:
// Client setup
const client = new Client({
name: 'my-client',
version: '1.0.0'
}, {
capabilities: { /* client capabilities */ }
});
// Connect to server
const transport = new StdioClientTransport(/* server process */);
await client.connect(transport);
// Discover server capabilities
const tools = await client.listTools();
const resources = await client.listResources();
// Use server tools
const result = await client.callTool({
name: 'tool_name',
arguments: { /* tool parameters */ }
});
3. Communication Flow
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ AI Model โ โโโโถ โ MCP Client โ โโโโถ โ MCP Server โ
โ โ โ (Frontend) โ โ (Backend) โ
โ โ โโโโ โ โ โโโโ โ โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โฒ โ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโ
Uses server capabilities
๐งช Experimentation Ideas
Create Your Own Tools:
Weather Tool:
{ name: 'weather', description: 'Get weather information', inputSchema: { type: 'object', properties: { city: { type: 'string', description: 'City name' }, units: { type: 'string', enum: ['celsius', 'fahrenheit'], default: 'celsius' } }, required: ['city'] } }
File System Tool:
{ name: 'file_operations', description: 'Basic file system operations', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['list', 'read', 'write'] }, path: { type: 'string', description: 'File or directory path' }, content: { type: 'string', description: 'Content to write' } }, required: ['action', 'path'] } }
Database Tool:
{ name: 'database', description: 'Simple in-memory database operations', inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['create', 'read', 'update', 'delete'] }, table: { type: 'string', description: 'Table name' }, data: { type: 'object', description: 'Data to store/update' }, id: { type: 'string', description: 'Record ID' } }, required: ['action', 'table'] } }
Create Custom Resources:
Configuration Resource:
{ uri: 'config://app-settings', name: 'Application Settings', description: 'Current application configuration', mimeType: 'application/json' }
Documentation Resource:
{ uri: 'docs://api-reference', name: 'API Reference', description: 'Complete API documentation', mimeType: 'text/markdown' }
Create Interactive Prompts:
- Code Review Prompt:
{ name: 'code-review', description: 'Start a code review session', arguments: [ { name: 'language', description: 'Programming language', required: true }, { name: 'focus', description: 'Review focus (security, performance, style)', required: false } ] }
๐ Debugging and Troubleshooting
Common Issues:
Server Won't Start:
# Check if TypeScript compiled correctly npm run build # Look for compilation errors npx tsc --noEmit # Check for missing dependencies npm install
Client Can't Connect:
# Make sure server path is correct node dist/client.js dist/server.js # Check if server process starts node dist/server.js
Tool Calls Fail:
// Add debugging to your server console.error(`[DEBUG] Tool called: ${name}`, JSON.stringify(args)); // Validate input parameters carefully if (typeof args.requiredParam === 'undefined') { throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter'); }
Debug Mode:
Enable verbose logging in both server and client:
// In server
console.error('[SERVER]', 'Detailed log message');
// In client
console.log('[CLIENT]', 'Connection status:', connected);
๐ Next Steps: Building Production Servers
1. Add Real Functionality:
Replace demo tools with actual useful functionality:
// Example: Real file system access
private async handleFileOperations(args: any) {
const { action, path, content } = args;
switch (action) {
case 'read':
return {
content: [{
type: 'text',
text: await fs.readFile(path, 'utf-8')
}]
};
case 'write':
await fs.writeFile(path, content);
return {
content: [{
type: 'text',
text: `File written: ${path}`
}]
};
}
}
2. Add External Integrations:
// Example: HTTP API integration
private async handleApiCall(args: any) {
const { url, method, data } = args;
const response = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: data ? JSON.stringify(data) : undefined
});
return {
content: [{
type: 'text',
text: JSON.stringify({
status: response.status,
data: await response.json()
}, null, 2)
}]
};
}
3. Add Persistence:
import * as fs from 'fs/promises';
class PersistentMCPServer {
private dataFile = './mcp-data.json';
async loadState(): Promise<Map<string, any>> {
try {
const data = await fs.readFile(this.dataFile, 'utf-8');
return new Map(Object.entries(JSON.parse(data)));
} catch {
return new Map();
}
}
async saveState(state: Map<string, any>): Promise<void> {
const data = Object.fromEntries(state);
await fs.writeFile(this.dataFile, JSON.stringify(data, null, 2));
}
}
4. Add Authentication:
private validateAuth(headers: any): boolean {
const token = headers['authorization'];
return token === 'Bearer your-secret-token';
}
private async handleSecureTool(args: any, headers: any) {
if (!this.validateAuth(headers)) {
throw new McpError(ErrorCode.InvalidParams, 'Authentication required');
}
// Continue with tool logic...
}
๐ Additional Resources
Official Documentation:
Community Examples:
Advanced Topics:
- HTTP transport for web services
- WebSocket transport for real-time communication
- Custom transport implementations
- Performance optimization techniques
- Security best practices
๐ฏ Learning Exercises
Exercise 1: Extend the Calculator
Add more operations: power
, sqrt
, factorial
, sin
, cos
Exercise 2: Build a Note-Taking System
Create tools for creating, editing, searching, and organizing notes with tags.
Exercise 3: Add External API Integration
Integrate with a real API (weather, news, stock prices) and create corresponding tools.
Exercise 4: Build a Project Manager
Create a comprehensive project management system with tasks, deadlines, priorities, and progress tracking.
Exercise 5: Add Real-Time Features
Implement tools that can send notifications or updates back to the client.
๐ Mastery Checklist
Beginner Level โ
- Understand MCP architecture (client, server, transport)
- Create basic tools with input validation
- Handle simple tool calls and responses
- Read and understand error messages
Intermediate Level โ
- Implement stateful tools with persistence
- Create and serve resources to AI
- Handle complex data processing
- Implement proper error handling patterns
Advanced Level โ
- Build CRUD operations with complex state
- Create interactive prompt templates
- Implement production-ready error handling
- Understand security and authentication concepts
- Optimize performance for production use
Expert Level ๐
- Build custom transport layers
- Create MCP server frameworks
- Implement advanced security measures
- Build distributed MCP architectures
- Contribute to the MCP ecosystem
๐ Congratulations!
You now have a complete understanding of MCP development from both frontend and backend perspectives. You can:
- Build MCP servers that provide tools, resources, and prompts
- Create MCP clients that interact with servers effectively
- Handle errors gracefully and implement proper validation
- Manage state between tool calls and across sessions
- Follow best practices for production-ready implementations
The interactive learning environment in this project gives you hands-on experience with all MCP concepts. Use this as a foundation to build your own specialized MCP servers for any domain or use case!
Happy coding! ๐