Build a Custom MCP Server Using Node.js (Simple Guide)
The Model Context Protocol (MCP) lets you expose functions (called tools) that AI clients can reliably call. Think of it like building a clean, typed API for AI.
This guide shows how to build a basic stdio-based MCP server using Node.js, step by step. This is a simple "hello world" kind of implementation—perfect for getting started with MCP.
What We're Building
A small MCP server that:
- Runs on Node.js
- Exposes a few tools
- Validates inputs
- Returns predictable JSON output
No magic. No over-engineering.
Requirements
- Node.js 18+
- npm
- Basic JavaScript knowledge
Step 1: Create a New Project
mkdir my-mcp-server
cd my-mcp-server
npm init -y
Install dependencies:
npm install @modelcontextprotocol/sdk zod
Step 2: Create the MCP Server
Create a file:
touch index.js
Add this code:
import { McpServer } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "My MCP Server",
version: "1.0.0",
});
const transport = new StdioServerTransport();
server.connect(transport);
That's your MCP server. It runs over stdio, which is perfect for local testing and IDE clients.
Note: Once your server starts, MCP clients automatically discover your tools. Learn more about how MCP Discovery & Initialization works.
Step 3: Add Your First Tool
Tools are just functions with validated inputs.
import { z } from "zod";
server.tool(
"sayHello",
{
name: z.string(),
},
async ({ name }) => {
return {
message: `Hello ${name}!`,
};
}
);
That's it.
Important rules
- Always validate inputs
- Always return JSON
- Keep tools predictable
Step 4: Add Another Tool (Example)
server.tool(
"addNumbers",
{
a: z.number(),
b: z.number(),
},
async ({ a, b }) => {
return {
result: a + b,
};
}
);
MCP tools should behave like pure functions.
Step 5: Handle Errors Cleanly
server.tool(
"divide",
{
a: z.number(),
b: z.number(),
},
async ({ a, b }) => {
if (b === 0) {
throw new Error("Cannot divide by zero");
}
return {
result: a / b,
};
}
);
If something is invalid → fail fast and clearly.
Step 6: Run the Server
node index.js
Your MCP server is now running.
Step 7: Test It with an MCP Client
Before deploying or publishing, check that:
- Tools are listed correctly
- Inputs are validated
- Output shape is consistent
- Errors are clear
If it works locally, it will work in real AI clients.
Pro tip: Test your server using MCP Playground to ensure it works correctly before publishing.
Recommended Project Structure
my-mcp-server/
├── index.js
├── tools/
│ ├── math.js
│ └── greeting.js
├── package.json
(You can split tools later—start simple.)
Good Practices (Keep This Short)
✅ Do
- Small, focused tools
- Clear input schemas
- Stable output format
❌ Avoid
- Free-text responses
- Hidden side effects
- Changing tool behavior
What's Next?
Once your server works:
- Add real business logic
- Wrap APIs or databases
- Test with multiple MCP clients
- Learn about MCP Discovery & Initialization to understand how clients find your tools
- Browse MCP Servers List
Final Thought
MCP servers are easiest when you think of them as:
Typed functions for AI, not chat responses
Keep them boring, strict, and predictable—and they'll scale beautifully.
Ready to test your MCP server? Test it now on MCP Playground →
Nikhil Tiwari
15+ years of experience in product development, AI enthusiast, and passionate about building innovative solutions that bridge the gap between technology and real-world applications. Specializes in creating developer tools and platforms that make complex technologies accessible to everyone.