MCP Learning Server
A beginner-friendly MCP server built in plain Node.js/JavaScript that exposes five tools (calculator, UUID generator, read notes, get weather, password generator) to teach how the Model Context Protocol works under the hood.
README
MCP Learning Server
A beginner-friendly Model Context Protocol (MCP) server, built in plain Node.js/JavaScript. This project exists purely to teach you, step by step, how an MCP server actually works under the hood.
1. What is MCP?
MCP (Model Context Protocol) is an open standard that lets an AI model (like Claude) talk to external programs called MCP servers. An MCP server exposes a set of tools — real pieces of functionality such as "do math", "read a file", or "call a weather API" — that the AI model can discover and call on demand.
Without MCP, an AI model can only generate text based on what it already knows. With MCP, the AI can:
- Discover what tools are available and what input each one needs.
- Call a tool with real arguments.
- Receive a real, structured result back and use it in its response.
Think of the AI as a "brain" and this server as a "toolbox" the brain can reach into whenever it needs to do something it can't do on its own.
2. What is this project?
This project is a single MCP server exposing five independent tools:
| Tool name | What it does |
|---|---|
calculator |
Add, subtract, multiply, or divide two numbers |
uuid_generator |
Generate 1–20 random UUIDs |
read_notes |
Read the contents of data/notes.txt |
get_weather |
Fetch live weather for a city via the OpenWeatherMap API |
password_generator |
Generate a random password (6–32 characters) |
Every tool follows the exact same pattern: name → description → input schema → validation → try/catch → standardized response. Once you understand one tool deeply, you understand all five.
The code is intentionally simple: small functions, descriptive names, no clever one-liners, and heavy comments explaining why, not just what.
3. Installation
You need Node.js version 18 or later installed.
# 1. Move into the project folder
cd mcp-learning-server
# 2. Install dependencies
npm install
4. Environment Variables
Only the weather tool needs a secret: a free API key from OpenWeatherMap.
# Copy the example file
cp .env.example .env
Then open .env and paste your key:
WEATHER_API_KEY=your_real_key_here
.env is listed in .gitignore, so your real key is never committed to
version control. If you skip this step, every tool except get_weather
will still work perfectly fine — get_weather will just return a friendly
error explaining the key is missing.
5. How to Run
npm start
You should see this line printed to your terminal:
mcp-learning-server is running and ready for requests.
The process will keep running — it is now waiting for an MCP client to connect to it over stdin/stdout. This is normal; it is not supposed to exit on its own.
Testing it interactively
The easiest way to try the tools by hand, without setting up a full AI client, is the official MCP Inspector:
npx @modelcontextprotocol/inspector node src/server.js
This opens a browser UI listing all five registered tools, where you can fill in inputs and see exactly what each tool returns.
Connecting it to Claude Desktop
Add an entry to Claude Desktop's MCP configuration file pointing at
node and the absolute path to src/server.js. Restart Claude Desktop,
and the five tools will appear as available capabilities in a
conversation.
6. Folder Structure
mcp-learning-server/
├── data/
│ └── notes.txt # Sample file used by the read_notes tool
├── src/
│ ├── server.js # Entry point: creates & starts the MCP server
│ ├── tools/
│ │ ├── calculator.js
│ │ ├── uuidGenerator.js
│ │ ├── fileReader.js
│ │ ├── weather.js
│ │ └── passwordGenerator.js
│ └── utils/
│ └── response.js # Shared success/error response helpers
├── .env.example # Template for required environment variables
├── .gitignore
├── package.json
└── README.md
Why each folder exists:
data/— holds real, static local data that a tool can access. It exists to prove that MCP tools can touch the filesystem, not just compute in memory.src/tools/— one file per tool. Keeping every tool in its own file means each one can be read, understood, and tested in isolation, without needing to understand the other four.src/utils/— shared code used by every tool (like our response formatting helpers). Anything more than one tool needs belongs here, instead of being copy-pasted into each tool file.src/server.js— the single place where the server is created and every tool is registered. This file's only job is "wiring", not logic.
7. Tool Reference
calculator
Input:
{ "operation": "add", "a": 20, "b": 10 }
Success output:
{ "success": true, "result": 30 }
Error example (divide by zero):
{ "success": false, "message": "Division by zero is not allowed." }
uuid_generator
Input:
{ "count": 5 }
Success output:
{ "success": true, "uuids": ["...", "...", "...", "...", "..."] }
Valid range: count must be between 1 and 20.
read_notes
Input: none ({})
Success output:
{ "success": true, "content": "Learning MCP Server\nNode.js is awesome.\n..." }
Error example:
{ "success": false, "message": "notes.txt was not found. Make sure data/notes.txt exists." }
get_weather
Input:
{ "city": "Lucknow" }
Success output:
{ "success": true, "city": "Lucknow", "temperature": 32, "humidity": 65, "condition": "haze" }
Error example:
{ "success": false, "message": "City \"Notacity123\" was not found." }
password_generator
Input:
{ "length": 12, "symbols": true }
Success output:
{ "success": true, "password": "Ab@12Lk#98Pq" }
Valid range: length must be between 6 and 32.
8. Common Errors
| Error message | Cause |
|---|---|
"Division by zero is not allowed." |
calculator was called with operation: "divide" and b: 0 |
"notes.txt was not found. Make sure data/notes.txt exists." |
data/notes.txt was deleted or moved |
"WEATHER_API_KEY is missing. Add it to your .env file." |
You never created a .env file or left the key blank |
"City \"X\" was not found." |
The city name sent to get_weather doesn't exist per the API |
| A zod validation error before your handler even runs | Input didn't match the tool's schema (e.g. count: 50 when max is 20) |
Every tool in this project returns errors as plain JSON objects
({ "success": false, "message": "..." }) instead of throwing raw
JavaScript exceptions. This is deliberate — see the "Error Handling"
section in src/utils/response.js for the full reasoning.
9. Learning Summary
By working through this project you should now understand:
- MCP architecture — an AI model (client) talks to a local process (server) over a shared protocol, most simply via stdin/stdout.
- Tool registration — calling
server.tool(name, description, schema, handler)once per capability, during server startup. - Tool discovery — the AI reads each tool's name, description, and schema to decide when and how to call it; it never sees your source code.
- The request lifecycle — client sends a "call tool" message → SDK validates arguments against the schema → your handler runs → your return value is wrapped and sent back.
- JSON schema & input validation — using
zodto describe exactly what shape of input a tool accepts, so bad input never reaches your logic. - File handling — reading local files safely with
fs/promisesandasync/await. - External API calls — using
axiosplus environment variables to call a real third-party API without hard-coding secrets. - Standardized error handling — never throwing raw errors back to a
client; always responding with a predictable
{ success, message }or{ success, ...data }shape. - Best practices — small single-responsibility functions, descriptive names, and heavy comments, all of which make a codebase easier to trust and extend as it grows.
From here, a natural next step is adding a sixth tool of your own — try building one that combines two ideas from this project (for example, a tool that reads a file and calls an API).
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。