Build a Custom MCP Server Using Node.js (Simple Guide)
Nikhil Tiwari
MCP Playground
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 →
Written by Nikhil Tiwari
15+ years in product development. AI enthusiast building developer tools that make complex technologies accessible to everyone.
Related Resources