Model Context Protocol: Technical Guide for Developers
Complete technical guide to Model Context Protocol (MCP). Learn how to install, configure, and create your own MCP servers with TypeScript and Python code examples. Includes integrations with GitHub, PostgreSQL, Filesystem, and more.

What is Model Context Protocol (MCP)?
Model Context Protocol (MCP) is an open standard created by Anthropic that enables LLMs to connect with external tools in a standardized way. It works as a client-server protocol where AI models can execute actions on external systems.
MCP Architecture
MCP follows a client-server architecture:
| Component | Description | Example |
|---|---|---|
| Host | Application that initiates connections | Claude Desktop, IDEs |
| Client | Maintains 1:1 connection with server | Built into host |
| Server | Exposes resources and tools | GitHub MCP, Filesystem MCP |
The Three Primitives
- Tools: Functions the model can execute
- Resources: Data the model can read
- Prompts: Reusable context templates
SDK Installation
TypeScript/Node.js
npm install @modelcontextprotocol/sdk
Python
pip install mcp
Create Your First MCP Server
Basic TypeScript Server
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{ name: "my-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// Define a tool
server.setRequestHandler("tools/list", async () => ({
tools: [{
name: "greet",
description: "Greets a person",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "Person's name" }
},
required: ["name"]
}
}]
}));
// Implement the tool
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "greet") {
const name = request.params.arguments.name;
return { content: [{ type: "text", text: `Hello, ${name}!` }] };
}
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Basic Python Server
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
server = Server("my-server")
@server.list_tools()
async def list_tools():
return [
Tool(
name="greet",
description="Greets a person",
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Name"}
},
"required": ["name"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "greet":
return [TextContent(type="text", text=f"Hello, {arguments['name']}!")]
async def main():
async with stdio_server() as (read, write):
await server.run(read, write)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Configure Claude Desktop
Edit the Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/my-server/build/index.js"]
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/user/projects"
]
}
}
}
Popular MCP Servers with Examples
1. Filesystem Server
Allows Claude to read and write files on your system.
Installation:
npx -y @modelcontextprotocol/server-filesystem /allowed/path
Configuration:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/user/Documents",
"/Users/user/projects"
]
}
}
}
Usage in Claude: "Read the package.json file from my project"
2. GitHub Server
Manage repositories, issues, and pull requests.
Installation:
npm install -g @modelcontextprotocol/server-github
Configuration:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
}
}
}
}
Available Tools:
| Tool | Description |
|---|---|
| create_repository | Create new repository |
| search_repositories | Search repositories |
| create_issue | Create issue |
| create_pull_request | Create PR |
| push_files | Upload files |
| list_commits | List commits |
Usage in Claude: "Create an issue in my repo describing this bug"
3. PostgreSQL Server
Execute SQL queries on your database.
Installation:
npm install -g @modelcontextprotocol/server-postgres
Configuration:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://user:password@localhost:5432/my_database"
]
}
}
}
Usage in Claude: "Show me the last 10 registered users"
4. Playwright Server
Web browser automation.
Installation:
npm install -g @playwright/mcp
Configuration:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp"]
}
}
}
Available Tools:
| Tool | Description |
|---|---|
| browser_navigate | Navigate to URL |
| browser_click | Click element |
| browser_type | Type text |
| browser_snapshot | Capture page state |
| browser_screenshot | Take screenshot |
Usage in Claude: "Go to github.com and search for MCP repositories"
5. Supabase Server
Interact with your Supabase backend.
Installation:
npx supabase mcp
Configuration:
{
"mcpServers": {
"supabase": {
"command": "npx",
"args": ["-y", "supabase", "mcp"],
"env": {
"SUPABASE_URL": "https://your-project.supabase.co",
"SUPABASE_SERVICE_ROLE_KEY": "your_service_role_key"
}
}
}
}
Create an Advanced MCP Server
Example server exposing resources and tools:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListResourcesRequestSchema,
ListToolsRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{ name: "api-server", version: "1.0.0" },
{ capabilities: { tools: {}, resources: {} } }
);
// Simulated database
const users = [
{ id: 1, name: "Ana", email: "ana@example.com" },
{ id: 2, name: "Carlos", email: "carlos@example.com" },
];
// List available resources
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
resources: [{
uri: "api://users",
name: "User list",
mimeType: "application/json"
}]
}));
// Read a resource
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
if (request.params.uri === "api://users") {
return {
contents: [{
uri: "api://users",
mimeType: "application/json",
text: JSON.stringify(users, null, 2)
}]
};
}
});
// List tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "create_user",
description: "Creates a new user",
inputSchema: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string", format: "email" }
},
required: ["name", "email"]
}
},
{
name: "search_user",
description: "Search user by name",
inputSchema: {
type: "object",
properties: {
query: { type: "string" }
},
required: ["query"]
}
}
]
}));
// Execute tools
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "create_user":
const newId = users.length + 1;
const newUser = { id: newId, ...args };
users.push(newUser);
return {
content: [{
type: "text",
text: `User created with ID: ${newId}`
}]
};
case "search_user":
const results = users.filter(u =>
u.name.toLowerCase().includes(args.query.toLowerCase())
);
return {
content: [{
type: "text",
text: JSON.stringify(results, null, 2)
}]
};
default:
throw new Error(`Unknown tool: ${name}`);
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
Debugging MCP Servers
Using MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js
This opens a web interface where you can:
- View available tools and resources
- Test tool calls
- Inspect responses
Claude Desktop Logs
macOS:
tail -f ~/Library/Logs/Claude/mcp*.log
Windows (PowerShell):
Get-Content -Path "$env:APPDATA\Claude\Logs\mcp*.log" -Wait
Best Practices
- Input validation: Use JSON Schema to validate arguments
- Error handling: Return clear error messages
- Minimal permissions: Only expose what's necessary
- Documentation: Clear descriptions for tools and resources
- Testing: Use the Inspector before deploying
Additional Resources
- Official specification: https://spec.modelcontextprotocol.io
- TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
- Python SDK: https://github.com/modelcontextprotocol/python-sdk
- Official servers: https://github.com/modelcontextprotocol/servers
- MCP Inspector: https://github.com/modelcontextprotocol/inspector
MCP is transforming how developers build AI applications. With these examples, you can start creating your own integrations.




