Configure your development environment for building MCP servers with TypeScript and the official SDK
Before we start building MCP servers, let's ensure you have everything you need. Don't worry - the setup is straightforward!
You'll need:
Why Node.js 18+? MCP SDK uses modern JavaScript features and the native fetch API, which requires Node.js 18 or higher.
This module assumes you:
If you're new to TypeScript, don't worry! We'll explain TypeScript-specific concepts as we go.
Let's set up your development environment step by step.
First, check if you have Node.js installed:
<CodeExample title="Checking Node.js Version" language="bash" code={`# Check Node.js version (should be 18.x or higher) node --version
npm --version
/>
If you need to install or update Node.js:
While not required, these tools will improve your development experience:
<CodeExample title="Optional Global Tools" language="bash" code={`# TypeScript compiler (optional - we'll use tsx for development) npm install -g typescript
npm install -g @modelcontextprotocol/inspector`} />
Pro Tip: Using tsx instead of tsc during development allows you to run TypeScript files directly without compilation!
Verify your Node.js installation
Now let's create your first MCP server project from scratch.
<CodeExample title="Initialize Project" language="bash" code={`# Create project directory mkdir my-first-mcp-server cd my-first-mcp-server
npm init -y
npm install --save-dev typescript @types/node tsx npm install @modelcontextprotocol/sdk`} />
Create a tsconfig.json file to configure TypeScript for MCP development:
<CodeExample
title="TypeScript Configuration"
language="json"
fileName="tsconfig.json"
code={{   "compilerOptions": {     "target": "ES2022",     "module": "Node16",     "moduleResolution": "Node16",     "lib": ["ES2022"],     "outDir": "./dist",     "rootDir": "./src",     "strict": true,     "esModuleInterop": true,     "skipLibCheck": true,     "forceConsistentCasingInFileNames": true,     "resolveJsonModule": true,     "declaration": true,     "declarationMap": true,     "sourceMap": true   },   "include": ["src/**/*"],   "exclude": ["node_modules", "dist"] }}
highlightLines={[3, 4, 5, 9]}
/>
Important: The module and moduleResolution settings must be "Node16" to work properly with the MCP SDK's ES modules.
Add important configuration to your package.json:
<CodeExample
title="Package Configuration"
language="json"
fileName="package.json"
code={{   "name": "my-first-mcp-server",   "version": "1.0.0",   "type": "module",   "main": "dist/index.js",   "scripts": {     "dev": "tsx watch src/index.ts",     "build": "tsc",     "start": "node dist/index.js"   },   // ... dependencies }}
highlightLines={[4, 6, 7, 8, 9]}
/>
Key Points:
"type": "module" enables ES modulestsx watch provides hot reloading during developmentnpm run dev for development, npm run build for productionSet up a clean project structure:
Your project should now look like this:
my-first-mcp-server/
├── node_modules/
├── src/
│   └── index.ts
├── package.json
├── package-lock.json
└── tsconfig.json
Create and configure a new MCP server project
Configure TypeScript for MCP development
Module content not available.
Once you've built your server, let's test it!
Add these helpful scripts to your package.json:
<CodeExample
title="Package.json Scripts"
language="json"
fileName="package.json"
code={{   "name": "my-first-mcp-server",   "version": "1.0.0",   "type": "module",   "scripts": {     "dev": "tsx watch src/index.ts",     "build": "tsc",     "start": "node dist/index.js",     "test": "npx @modelcontextprotocol/inspector"   },   // ... other fields }}
highlightLines={[5, 6, 7, 8, 9]}
/>
The MCP Inspector is a powerful tool for testing your server:
Start your server in one terminal:
Run the inspector in another terminal:
Connect to your server in the inspector:
npm run devSuccess! If everything is set up correctly, you should see your server's resources in the inspector.
Issue: "Cannot find module" errors
Solution: Ensure all imports end with .js extension (even for TypeScript files)
Issue: "Module not found" for MCP SDK
Solution: Check that you're using Node.js 18+ and have "type": "module" in package.json
Issue: Server doesn't respond in inspector Solution: Make sure you're using stdio transport and the server is running
Add convenient scripts for development
As your MCP server grows, a good structure becomes essential. Here's a recommended approach:
<CodeExample
title="Recommended Project Structure"
language="text"
code={my-mcp-server/ ├── src/ │   ├── index.ts          # Main server entry point │   ├── handlers/         # Request handlers │   │   ├── resources.ts  # Resource handlers │   │   └── tools.ts      # Tool handlers │   ├── providers/        # Business logic │   │   ├── database.ts   # Database connections │   │   └── files.ts      # File system operations │   └── types/            # TypeScript type definitions ├── dist/                 # Compiled output ├── tests/                # Test files ├── .gitignore ├── package.json ├── tsconfig.json └── README.md}
/>
<CodeExample title="Example Handler Organization" language="typescript" fileName="src/handlers/resources.ts" code={`import { Server } from '@modelcontextprotocol/sdk/server/index.js';
export function registerResourceHandlers(server: Server) { // Register all resource-related handlers server.setRequestHandler('resources/list', async () => { return { resources: [ ...await fileProvider.listResources(), ...await databaseProvider.listResources() ] }; });
server.setRequestHandler('resources/read', async (request) => { // Delegate to appropriate provider based on URI scheme const uri = request.params.uri;
if (uri.startsWith('file://')) {
  return fileProvider.readResource(uri);
} else if (uri.startsWith('db://')) {
  return databaseProvider.readResource(uri);
}
throw new Error('Unknown resource type');
}); }`} />
Organize your MCP server for maintainability