MCP Learning Server

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.

Category
Visit Server

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 zod to describe exactly what shape of input a tool accepts, so bad input never reaches your logic.
  • File handling — reading local files safely with fs/promises and async/await.
  • External API calls — using axios plus 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).

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured