Chapter 2: Development Environment Setup
Haiyue
19min
Chapter 2: Development Environment Setup
Learning Objectives
- Install and configure Node.js development environment
- Understand MCP SDK and related tools
- Set up your first MCP Server project
- Configure development debugging tools and test environment
- Understand the basic project structure of MCP Server
Knowledge Summary
Environment Requirements
- Node.js >= 18.0.0 (LTS version recommended)
- npm or yarn package manager
- TypeScript support (recommended)
- Git version control tool
- VS Code or other IDE with TypeScript support
MCP SDK Core Packages
| Package Name | Purpose | Description |
|---|---|---|
@modelcontextprotocol/sdk | MCP Core SDK | Provides basic protocol implementation and type definitions |
@modelcontextprotocol/server | MCP Server Framework | High-level framework to simplify Server development |
@modelcontextprotocol/client | MCP Client Tool | For testing and debugging MCP Server |
@types/node | Node.js Type Definitions | Required for TypeScript development |
Project Structure Standards
mcp-server-example/
├── src/
│ ├── index.ts # Server entry file
│ ├── tools/ # Tool implementations
│ ├── resources/ # Resource providers
│ ├── prompts/ # Prompt templates
│ └── types/ # Type definitions
├── dist/ # Compilation output directory
├── package.json # Project configuration
├── tsconfig.json # TypeScript configuration
├── .gitignore # Git ignore configuration
└── README.md # Project documentation
Environment Setup Steps
1. Install Node.js Environment
# Python script demonstrating environment check
import subprocess
import sys
import json
def check_node_version():
"""Check Node.js version"""
try:
result = subprocess.run(['node', '--version'],
capture_output=True, text=True)
if result.returncode == 0:
version = result.stdout.strip()
print(f"✅ Node.js installed: {version}")
# Check if version meets requirements
major_version = int(version[1:].split('.')[0])
if major_version >= 18:
print("✅ Node.js version meets requirements (>=18.0.0)")
return True
else:
print("❌ Node.js version too old, requires >=18.0.0")
return False
else:
print("❌ Node.js not installed")
return False
except FileNotFoundError:
print("❌ Node.js not installed")
return False
def check_npm_version():
"""Check npm version"""
try:
result = subprocess.run(['npm', '--version'],
capture_output=True, text=True)
if result.returncode == 0:
version = result.stdout.strip()
print(f"✅ npm installed: {version}")
return True
else:
print("❌ npm not installed")
return False
except FileNotFoundError:
print("❌ npm not installed")
return False
# Environment check
print("🔍 Checking development environment...")
node_ok = check_node_version()
npm_ok = check_npm_version()
if node_ok and npm_ok:
print("\n✅ Environment check passed, ready to start MCP development!")
else:
print("\n❌ Environment check failed, please install required tools")
2. Create MCP Server Project
# Simulate project initialization process
import os
import json
from pathlib import Path
def create_mcp_project(project_name):
"""Create MCP Server project structure"""
# Create project directory structure
dirs = [
f"{project_name}",
f"{project_name}/src",
f"{project_name}/src/tools",
f"{project_name}/src/resources",
f"{project_name}/src/prompts",
f"{project_name}/src/types",
f"{project_name}/dist"
]
for dir_path in dirs:
Path(dir_path).mkdir(parents=True, exist_ok=True)
print(f"📁 Created directory: {dir_path}")
# Generate package.json
package_json = {
"name": project_name,
"version": "1.0.0",
"description": "MCP Server example",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "tsx src/index.ts",
"watch": "tsx watch src/index.ts"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"@modelcontextprotocol/server": "^1.0.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.0.0",
"tsx": "^4.0.0"
}
}
# Generate tsconfig.json
tsconfig = {
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": True,
"esModuleInterop": True,
"skipLibCheck": True,
"forceConsistentCasingInFileNames": True,
"declaration": True,
"declarationMap": True,
"sourceMap": True
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
# Write configuration files
with open(f"{project_name}/package.json", "w", encoding="utf-8") as f:
json.dump(package_json, f, indent=2, ensure_ascii=False)
with open(f"{project_name}/tsconfig.json", "w", encoding="utf-8") as f:
json.dump(tsconfig, f, indent=2, ensure_ascii=False)
print(f"📝 Created configuration files: package.json, tsconfig.json")
return f"{project_name}"
# Create sample project
project_path = create_mcp_project("my-mcp-server")
print(f"\n✅ Project '{project_path}' created successfully!")
3. Hello World MCP Server
# Generate basic MCP Server code structure
hello_world_server = '''
import { Server } from '@modelcontextprotocol/server';
import { StdioTransport } from '@modelcontextprotocol/server/stdio';
class HelloWorldMCPServer {
private server: Server;
constructor() {
// Create MCP Server instance
this.server = new Server(
{
name: "hello-world-server",
version: "1.0.0"
},
{
capabilities: {
tools: {},
resources: {},
prompts: {}
}
}
);
this.setupTools();
this.setupResources();
this.setupPrompts();
}
private setupTools() {
// Register Hello World tool
this.server.setRequestHandler('tools/list', async () => {
return {
tools: [
{
name: "say_hello",
description: "A tool that says Hello",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Name to greet"
}
},
required: ["name"]
}
}
]
};
});
// Handle tool calls
this.server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === "say_hello") {
const userName = args.name || "World";
return {
content: [
{
type: "text",
text: `Hello, ${userName}! Welcome to MCP Server!`
}
]
};
}
throw new Error(`Unknown tool: ${name}`);
});
}
private setupResources() {
// Register resource list
this.server.setRequestHandler('resources/list', async () => {
return {
resources: [
{
uri: "hello://info",
name: "Server Information",
description: "Get basic information about the Hello World server",
mimeType: "text/plain"
}
]
};
});
// Handle resource reading
this.server.setRequestHandler('resources/read', async (request) => {
const uri = request.params.uri;
if (uri === "hello://info") {
return {
contents: [
{
uri: uri,
mimeType: "text/plain",
text: "This is a Hello World MCP Server example\\nVersion: 1.0.0\\nFeatures: Demonstrates basic MCP protocol usage"
}
]
};
}
throw new Error(`Unknown resource: ${uri}`);
});
}
private setupPrompts() {
// Register prompt templates
this.server.setRequestHandler('prompts/list', async () => {
return {
prompts: [
{
name: "greeting_template",
description: "Friendly greeting template",
arguments: [
{
name: "user_name",
description: "User name",
required: true
}
]
}
]
};
});
// Handle prompt template retrieval
this.server.setRequestHandler('prompts/get', async (request) => {
const { name, arguments: args } = request.params;
if (name === "greeting_template") {
const userName = args?.user_name || "friend";
return {
description: "Generate a friendly greeting message",
messages: [
{
role: "user",
content: {
type: "text",
text: `Please greet ${userName} in a friendly manner and introduce the advantages of the MCP protocol.`
}
}
]
};
}
throw new Error(`Unknown prompt template: ${name}`);
});
}
public async start() {
// Use standard input/output transport
const transport = new StdioTransport();
await this.server.connect(transport);
console.error("Hello World MCP Server started!");
}
}
// Start server
const server = new HelloWorldMCPServer();
server.start().catch((error) => {
console.error("Server startup failed:", error);
process.exit(1);
});
'''
print("📄 Basic MCP Server code template:")
print("=" * 50)
print(hello_world_server)
print("=" * 50)
Development Tools Configuration
VS Code Configuration
# VS Code configuration example
import json
def create_vscode_config():
"""Generate VS Code development configuration"""
# launch.json - Debug configuration
launch_config = {
"version": "0.2.0",
"configurations": [
{
"name": "Start MCP Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/index.ts",
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"console": "integratedTerminal",
"envFile": "${workspaceFolder}/.env"
},
{
"name": "Debug MCP Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/tsx/cli.js",
"args": ["${workspaceFolder}/src/index.ts"],
"console": "integratedTerminal",
"envFile": "${workspaceFolder}/.env"
}
]
}
# settings.json - Workspace settings
settings_config = {
"typescript.preferences.importModuleSpecifier": "relative",
"editor.codeActionsOnSave": {
"source.organizeImports": True
},
"files.exclude": {
"**/node_modules": True,
"**/dist": True,
"**/.git": True
}
}
# extensions.json - Recommended extensions
extensions_config = {
"recommendations": [
"ms-vscode.vscode-typescript-next",
"esbenp.prettier-vscode",
"ms-vscode.vscode-json",
"bradlc.vscode-tailwindcss"
]
}
print("VS Code configuration files:")
print("\n.vscode/launch.json:")
print(json.dumps(launch_config, indent=2, ensure_ascii=False))
print("\n.vscode/settings.json:")
print(json.dumps(settings_config, indent=2, ensure_ascii=False))
print("\n.vscode/extensions.json:")
print(json.dumps(extensions_config, indent=2, ensure_ascii=False))
create_vscode_config()
Testing and Debugging Tools
Testing Tools
MCP Inspector - MCP protocol debugging tool
- Provides visual interface to test MCP Server
- Real-time view of message passing process
- Supports tool invocation and resource access testing
MCP Client CLI - Command-line testing tool
- Quick testing of MCP Server functionality
- Automated testing script support
- Performance and load testing
# Test script example
def create_test_script():
"""Generate MCP Server test script"""
test_script = '''
import asyncio
import json
from typing import Any, Dict
class MCPServerTester:
def __init__(self, server_command: str):
self.server_command = server_command
self.process = None
async def start_server(self):
"""Start MCP Server process"""
import subprocess
self.process = await asyncio.create_subprocess_exec(
*self.server_command.split(),
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
print("📡 MCP Server started")
async def send_request(self, method: str, params: Dict[str, Any] = None):
"""Send MCP request"""
if not self.process:
raise RuntimeError("Server not started")
request = {
"jsonrpc": "2.0",
"id": 1,
"method": method,
"params": params or {}
}
# Send request
request_data = json.dumps(request) + "\\n"
self.process.stdin.write(request_data.encode())
await self.process.stdin.drain()
# Read response
response_line = await self.process.stdout.readline()
response = json.loads(response_line.decode())
return response
async def test_tools(self):
"""Test tools functionality"""
print("🔧 Testing Tools functionality...")
# Get tools list
tools_response = await self.send_request("tools/list")
print(f"Available tools: {tools_response}")
# Call say_hello tool
call_response = await self.send_request("tools/call", {
"name": "say_hello",
"arguments": {"name": "Test User"}
})
print(f"Tool call result: {call_response}")
async def test_resources(self):
"""Test resources functionality"""
print("📚 Testing Resources functionality...")
# Get resources list
resources_response = await self.send_request("resources/list")
print(f"Available resources: {resources_response}")
# Read resource content
read_response = await self.send_request("resources/read", {
"uri": "hello://info"
})
print(f"Resource content: {read_response}")
async def test_prompts(self):
"""Test prompts functionality"""
print("💬 Testing Prompts functionality...")
# Get prompt templates list
prompts_response = await self.send_request("prompts/list")
print(f"Available templates: {prompts_response}")
# Get prompt template
get_response = await self.send_request("prompts/get", {
"name": "greeting_template",
"arguments": {"user_name": "Developer"}
})
print(f"Template content: {get_response}")
async def run_all_tests(self):
"""Run all tests"""
await self.start_server()
try:
await self.test_tools()
await self.test_resources()
await self.test_prompts()
print("\\n✅ All tests passed!")
finally:
if self.process:
self.process.terminate()
await self.process.wait()
# Usage example
async def main():
tester = MCPServerTester("node dist/index.js")
await tester.run_all_tests()
# Run tests
# asyncio.run(main())
print("Test script ready")
'''
print("🧪 MCP Server test script:")
print(test_script)
create_test_script()
Project Management Best Practices
Git Configuration
# .gitignore file content
gitignore_content = '''
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# TypeScript
dist/
*.tsbuildinfo
# Environment variables
.env
.env.local
.env.production
# IDE
.vscode/settings.json
.idea/
# Operating system
.DS_Store
Thumbs.db
# Log files
logs/
*.log
# Temporary files
tmp/
temp/
'''
print("📄 .gitignore configuration:")
print(gitignore_content)
Development Workflow
Development Workflow
- Project Initialization - Use scaffolding tools to quickly create project structure
- Dependency Installation - Install MCP SDK and development dependencies
- Code Development - Develop MCP Server using TypeScript
- Local Testing - Test functionality using MCP Client tools
- Build and Package - Compile TypeScript to JavaScript
- Integration Testing - Test in real AI clients
- Deployment and Release - Publish to npm or private repository
Through this chapter, we have successfully set up a complete MCP Server development environment, created our first Hello World project, and configured necessary development and testing tools. This lays a solid foundation for in-depth learning of MCP protocol implementation.