I'm a software engineer with 2 years of experience. I kept hearing about MCP (Model Context Protocol) and how it's the "future of AI integrations." So I spent my holiday weekend actually building one from scratch.
Here's my honest experience — including the errors, the confusion, and the moment it finally clicked.
What is MCP, actually?
Everyone describes it as "a protocol that lets AI models use tools." That sounds fancy. Here's the simpler version:
You build a wrapper around any API. Claude calls it using plain English.
That's it. Your server has zero AI in it. Claude is the brain. Your server is just the hands.
Once I understood that, everything made sense.
What I built
A weather MCP server in TypeScript that exposes 3 tools to Claude:
-
get_current_weather— current conditions for any city -
get_forecast— 1 to 7 day forecast -
get_weather_by_coords— weather by latitude/longitude
Uses the Open-Meteo API — completely free, no API key needed, works globally.
GitHub: https://github.com/hemanthly/weather-mcp-server
The stack
- TypeScript + Node.js
-
@modelcontextprotocol/sdk(official Anthropic SDK) -
zodfor input validation - Open-Meteo API (free, no signup)
- Claude Desktop for testing
How it works — the core code
The entire server is one file. Here's the heart of it:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "weather-mcp-server",
version: "1.0.0",
});
server.tool(
"get_current_weather",
"Get the current weather conditions for any city in the world",
{
city: z.string().describe("City name, e.g. 'Mumbai', 'Hyderabad', 'London'"),
},
async ({ city }) => {
const location = await geocode(city);
const weather = await fetchCurrentWeather(location.latitude, location.longitude);
return { content: [{ type: "text", text: formatWeather(location, weather) }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
You register a tool with a name, description, input schema, and handler. Claude reads the description to know when to call it. That's the whole contract.
The setup (what actually took time)
1. Install dependencies
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
2. Build the server
npm run build
This compiles TypeScript to build/index.js.
3. Test with MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js
This opens a browser UI at localhost:6274 where you can call your tools directly — without Claude Desktop. This is where I first saw my tools working and it felt real.
4. Connect to Claude Desktop
This is where I got stuck. Here's the exact fix.
Open your Claude Desktop config file:
-
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json -
Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add this:
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["C:\\Users\\YourName\\projects\\weather-mcp\\build\\index.js"]
}
}
}
Critical gotcha on Windows: use double backslashes \\ in the path. Single backslashes will silently fail and you'll spend 30 minutes wondering why Claude Desktop isn't connecting. Trust me.
After saving, fully quit Claude Desktop from the system tray — not just close the window. Else you can consider opening taskmanager and kill the processes related to claude. Then reopen it.
The moment it clicked
I was expecting something magical when Claude called my tool. Instead it looked exactly like calling a REST API — geocode the city, fetch weather data, return formatted text.
And then I realized: that's the point.
MCP servers are structured API wrappers. The AI part isn't inside your server. It's in how Claude decides to use it.
When I typed:
"I'm flying from Hyderabad to Mumbai this weekend. What should I pack?"
Claude called get_forecast for both cities automatically, compared the results, and gave me packing advice. I never told it to do any of that. It reasoned over my dumb API wrapper and produced something useful.
That's where the intelligence lives — not in your server, in Claude.
The architecture in plain English
User types a question in plain English
↓
Claude figures out which tools to call and with what arguments
↓
Your MCP server receives the call and hits the actual API
↓
Returns raw data back to Claude
↓
Claude reasons over the data and responds naturally
You own the bottom half. Claude owns the top half. MCP is the contract between them.
What I learned
1. Start with MCP Inspector, not Claude Desktop.
The Inspector lets you test tools directly in a browser. Much faster feedback loop than reconfiguring Claude Desktop every time.
2. console.log() will break your server.
MCP uses stdio (standard input/output) to communicate. If you use console.log(), it writes to stdout and corrupts the JSON-RPC messages. Always use console.error() for any logging.
3. The description on each tool matters a lot.
Claude reads your tool description to decide when to use it. A vague description = Claude uses it at the wrong time or not at all. Be specific.
4. Error handling is your responsibility.
If your tool throws an uncaught error, the whole server crashes. Wrap every tool handler in try/catch and return { isError: true } on failure.
5. Windows path gotcha.
Double backslashes in the Claude config JSON. C:\\Users\\... not C:\Users\...
Total time
About 3 to 4 hours from zero to working chat in Claude Desktop. Mostly spent on:
- Understanding the MCP primitives (tools, resources, prompts) — 45 min
- Writing the actual server code — 1 hour
- Debugging the Claude Desktop config path — 30 min
- Git push issues (remote already existed, non-fast-forward) — 20 min
- Actually understanding what was happening — ongoing
What's next
This was Day 1 of a 3-day sprint. Day 2 is building a Razorpay MCP server — a real portfolio piece since Razorpay has no official MCP server yet and is used by thousands of Indian startups.
The goal: position as an MCP server developer for hire. If you're a SaaS company that wants Claude or Cursor to natively use your API, that's the service.
Follow along — I'll post the Razorpay server next.
Resources
- Official MCP docs: https://modelcontextprotocol.io
- My server repo: https://github.com/hemanthly/weather-mcp-server
- MCP registry (find gaps = find clients): https://pulsemcp.com
- Open-Meteo API: https://open-meteo.com
Built this during a 3-day holiday sprint. If you're a software engineer trying to get into the AI tooling space, MCP is one of the fastest ways to build something real and billable right now.
Top comments (1)
please have a read and learn about mcp