mcp-protocol-builder
MCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
What this skill does
# MCP (Model Context Protocol) - AI-Native Server Development
## Overview
Model Context Protocol (MCP) is an open standard for connecting AI assistants to external data sources and tools. Build servers that expose **tools** (functions LLMs can call), **resources** (data LLMs can read), and **prompts** (templates LLMs can use).
**Key Concepts**:
- **Tools**: Functions LLMs can execute (read files, query APIs, run commands)
- **Resources**: Data sources LLMs can access (files, databases, APIs)
- **Prompts**: Reusable templates with arguments for common tasks
- **Client-Server**: MCP servers expose capabilities, clients (like Claude Desktop) consume them
- **Transport**: STDIO (local), SSE (Server-Sent Events), HTTP (network)
**Official SDKs**:
- TypeScript: `@modelcontextprotocol/sdk`
- Python: `mcp`
**Installation**:
```bash
# TypeScript server
npx @modelcontextprotocol/create-server@latest my-server
cd my-server && npm install
# Python server
pip install mcp
# Or use uv (recommended)
uv pip install mcp
```
## Quick Start - TypeScript Server
### 1. Create Server with CLI
```bash
# Interactive setup
npx @modelcontextprotocol/create-server@latest my-filesystem-server
# Options prompt:
# - Server name: my-filesystem-server
# - Language: TypeScript
# - Include example tools: Yes
```
### 2. Define Tools
```typescript
// src/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as fs from "fs/promises";
import * as path from "path";
const server = new Server(
{
name: "filesystem-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read_file",
description: "Read contents of a file",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "Path to the file to read",
},
},
required: ["path"],
},
},
{
name: "list_directory",
description: "List contents of a directory",
inputSchema: {
type: "object",
properties: {
path: {
type: "string",
description: "Directory path to list",
},
},
required: ["path"],
},
},
],
};
});
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "read_file": {
const filePath = args.path as string;
const content = await fs.readFile(filePath, "utf-8");
return {
content: [{ type: "text", text: content }],
};
}
case "list_directory": {
const dirPath = args.path as string;
const entries = await fs.readdir(dirPath, { withFileTypes: true });
const listing = entries
.map((entry) => `${entry.isDirectory() ? "๐" : "๐"} ${entry.name}`)
.join("\n");
return {
content: [{ type: "text", text: listing }],
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
});
// Start server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Filesystem MCP server running on stdio");
}
main();
```
### 3. Configure Claude Desktop
```json
// ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
// %APPDATA%/Claude/claude_desktop_config.json (Windows)
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["/absolute/path/to/my-filesystem-server/build/index.js"]
}
}
}
```
### 4. Build and Test
```bash
# Build TypeScript
npm run build
# Restart Claude Desktop (Cmd+Q and reopen)
# Server appears in ๐ menu
```
## Quick Start - Python Server
### 1. Create Server
```python
# server.py
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import json
import os
# Create server instance
app = Server("filesystem-server")
# Define tools
@app.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="read_file",
description="Read contents of a file",
inputSchema={
"type": "object",
"properties": {
"path": {"type": "string", "description": "File path to read"}
},
"required": ["path"],
},
),
Tool(
name="list_directory",
description="List directory contents",
inputSchema={
"type": "object",
"properties": {
"path": {"type": "string", "description": "Directory path"}
},
"required": ["path"],
},
),
]
# Handle tool calls
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name == "read_file":
file_path = arguments["path"]
with open(file_path, "r") as f:
content = f.read()
return [TextContent(type="text", text=content)]
elif name == "list_directory":
dir_path = arguments["path"]
entries = os.listdir(dir_path)
listing = "\n".join(
f"{'๐' if os.path.isdir(os.path.join(dir_path, e)) else '๐'} {e}"
for e in entries
)
return [TextContent(type="text", text=listing)]
else:
raise ValueError(f"Unknown tool: {name}")
# Start server
async def main():
async with stdio_server() as (read_stream, write_stream):
await app.run(read_stream, write_stream, app.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())
```
### 2. Configure Claude Desktop
```json
{
"mcpServers": {
"filesystem": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}
```
### 3. Test
```bash
# Test server standalone
python server.py
# Restart Claude Desktop
# Tools appear in ๐ menu
```
## Resources - Exposing Data to LLMs
Resources provide read-only access to data sources.
### TypeScript Resource Example
```typescript
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "file:///docs/readme.md",
name: "README",
description: "Project README documentation",
mimeType: "text/markdown",
},
{
uri: "file:///config/settings.json",
name: "Settings",
description: "Application settings",
mimeType: "application/json",
},
],
};
});
// Handle resource reads
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const uri = request.params.uri;
if (uri.startsWith("file://")) {
const filePath = uri.replace("file://", "");
const content = await fs.readFile(filePath, "utf-8");
return {
contents: [
{
uri,
mimeType: "text/plain",
text: content,
},
],
};
}
throw new Error(`Unknown resource: ${uri}`);
});
```
### Python Resource Example
```python
from mcp.types import Resource, ResourceContent
@app.list_resources()
async def list_resources() -> list[Resource]:
return [
Resource(
uri="file:///docs/readme.md",
name="README",
description="Project README",
mimeType="text/markdown",
),
Resource(
uri="file:///Related in toolchain
nextjs-core
IncludedCore Next.js patterns for App Router development including Server Components, Server Actions, route handlers, data fetching, and caching strategies
nextjs-v16
IncludedNext.js 16 migration guide (async request APIs, "use cache", Turbopack)
vitest
IncludedVitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design
golang-database-patterns
IncludedGo database integration patterns using sqlx, pgx, and migration tools like golang-migrate
sveltekit
IncludedSvelteKit - Full-stack Svelte framework with file-based routing, SSR/SSG, form actions, and adapters for deployment
vue
IncludedVue 3 - Progressive JavaScript framework with Composition API, reactivity system, single-file components, Vite integration, TypeScript support