Recap: What We Covered Last Time
In Episode 1, we learned what MCP is, why it matters, and how it solves the M×N integration problem. We explored the Client-Server architecture and discovered that every MCP Server can offer three capabilities: Tools, Resources, and Prompts. Now it’s time to get our hands dirty and set up our first MCP Server.
Why This Episode Matters
Reading about MCP is great, but until you actually run a server and watch Claude use it in real time, you won’t fully grasp how powerful this is. This episode takes you from theory to practice. We’ll install a simple MCP Server, connect it to Claude Desktop, and verify that it actually works.
What You’ll Need
Before we start, let’s make sure all the tools are ready. Here’s your checklist:
Node.js and npm: The official MCP SDK is written in TypeScript/JavaScript. Node.js is the runtime that executes JavaScript outside the browser, and npm is its package manager. When you install Node.js, npm comes bundled with it.
To verify your versions:
node --version # Should be v18+
npm --version # Should be v8+
Claude Desktop: The desktop application for Claude that supports MCP. You can download it from Anthropic’s website. This app acts as the MCP Host — the interface you chat with, through which Claude connects to MCP Servers.
A Code Editor: Whatever you’re comfortable with. VS Code is recommended since it also has built-in MCP support.
Installing the MCP SDK
Let’s get to the installation. The MCP SDK is an official library built by Anthropic that makes creating MCP Servers straightforward. Instead of implementing the JSON-RPC protocol yourself, the SDK handles all of that so you can focus on your actual logic.
Create a new folder and initialize the project:
mkdir my-first-mcp-server
cd my-first-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
That’s it! The SDK is installed. Let’s see what we got.
The @modelcontextprotocol/sdk package includes everything you need to build an MCP Server: connection management, JSON-RPC message parsing, tool definitions, and response handling. You just need to declare what tools your server has and what each tool does.
Building Your First MCP Server
Let’s build a simple MCP Server with just one tool: a clock tool that returns the current time. It’s simple, but it covers all the core concepts.
Create a file called index.js:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
name: "my-clock-server",
version: "1.0.0"
});
server.tool("get_current_time", "Returns the current date and time", {}, async () => {
return {
content: [{
type: "text",
text: new Date().toISOString()
}]
};
});
const transport = new StdioServerTransport();
await server.connect(transport);
Let’s walk through this line by line:
Lines 1-2: We import two things from the SDK — McpServer, which is the core of our server, and StdioServerTransport, which defines how communication happens. Stdio means we use standard input/output (stdin/stdout) — the simplest transport method.
Lines 4-7: We create a new MCP Server instance with a name and version. This information is shared with the Client so it knows which server it’s talking to.
Lines 9-16: This is where we define our tool. The server.tool() function takes four arguments: the tool name, its description (which the AI reads to understand when to use it), the input schema (empty here since we don’t need input), and the function that executes the tool.
Lines 18-19: We create the transport and connect it to the server. From this moment, the server is ready and waiting for requests.
package.json and add "type": "module" to it. Without this, import/export statements won’t work. Also make sure you have Node.js version 18 or higher.Connecting to Claude Desktop
The server is ready. Now we need to tell Claude Desktop to use it. This is done through a configuration file.
Find the Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
If the file doesn’t exist, create it. Set its contents to:
{
"mcpServers": {
"my-clock-server": {
"command": "node",
"args": ["/full/path/to/my-first-mcp-server/index.js"]
}
}
}
Replace /full/path/to/ with the actual path to your project folder.
Now close Claude Desktop completely and reopen it. If everything is set up correctly, you should see an MCP icon (a hammer shape) indicating that the server is connected.
claude_desktop_config.json file is like a phone directory. You’re telling Claude, “When you need to know the time, call this number (file path).” Claude runs that program whenever needed and asks its question.Testing It Out
Let’s see if it actually works. In Claude Desktop, type:
“What time is it right now?”
If everything is configured correctly, instead of saying “I don’t have access to the current time,” Claude will call the get_current_time tool and tell you the exact time on your system.
If it doesn’t work, run through this checklist:
- File path: The path in the config must be absolute (e.g.,
/Users/you/projects/my-first-mcp-server/index.js) - Node.js: Make sure
nodeis in your system’s PATH - package.json: Verify you added
"type": "module" - Restart: Fully close and reopen Claude Desktop
- Logs: In Claude Desktop, go to Developer > Open MCP Log to see errors
Going Further — A Tool with Input
The clock tool was simple. Let’s build something more interesting that also takes input: a BMI (Body Mass Index) calculator tool.
server.tool(
"calculate_bmi",
"Calculate BMI from weight (kg) and height (cm)",
{
weight: { type: "number", description: "Weight in kilograms" },
height: { type: "number", description: "Height in centimeters" }
},
async ({ weight, height }) => {
const heightInMeters = height / 100;
const bmi = weight / (heightInMeters * heightInMeters);
const category = bmi < 18.5 ? "Underweight"
: bmi < 25 ? "Normal"
: bmi < 30 ? "Overweight"
: "Obese";
return {
content: [{
type: "text",
text: `BMI: ${bmi.toFixed(1)} (${category})`
}]
};
}
);
The key difference from the previous tool is the third argument — the input schema. Here we're telling the AI: "This tool needs two numbers: weight in kilograms and height in centimeters." Claude reads each field's description to understand what to ask for and how to fill in the values.
Now if you type "I weigh 75 kg and I'm 180 cm tall, calculate my BMI" in Claude, it will automatically use the calculate_bmi tool and give you the result.
What We Learned
Let's summarize what we covered in this episode:
- Easy setup: With npm and one package, everything is ready to go
- Simple structure: Create a server, define tools, connect a transport
- Claude config: A simple JSON file introduces the server to Claude
- Tool without input: Like the clock — just returns a result
- Tool with input: Like BMI — accepts parameters and processes them