Skip to main content
Glama

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.


Related MCP server: Simple MCP Server Tutorial

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).

Available Tools

5 tools
calculatorA

Performs basic arithmetic (add, subtract, multiply, divide) on two numbers.

ParametersJSON Schema
NameRequiredDescriptionDefault
aYesThe first number.
bYesThe second number.
operationYesThe math operation to perform: add, subtract, multiply, or divide.

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Does not disclose behavior on division by zero or error handling, nor precision details. Only states it 'performs' operations without constraints or side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, 12 words, front-loaded with action verb. Every word earns its place. No redundancies.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with full schema coverage, description is adequate but missing key behavioral details (e.g., division by zero behavior, return type). No output schema, so return value info would be helpful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptions for all three parameters. The description adds minimal value beyond the schema (e.g., listing operations), but does not introduce new detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'performs basic arithmetic' on two numbers, specifying four operations. It distinguishes itself from sibling tools (get_weather, password_generator, etc.) which are not arithmetic.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use or not use this tool vs alternatives. Implicitly it's the only arithmetic tool, but lacking context like 'for simple math only' or when to prefer another tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_weatherA

Fetches the current temperature, humidity, and condition for a given city.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityYesThe name of the city to get weather for, e.g. 'Lucknow'.

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It only states what the tool does without disclosing behavioral traits like error handling, rate limits, or query semantics beyond the obvious read-only fetch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence with no redundancy. Every word earns its place, making it efficient and easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (1 param, no output schema, no annotations), the description is adequate but lacks details on output format or error behavior, which could improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single parameter 'city' with a clear description. The tool description adds value by specifying the returned data (temperature, humidity, condition), which goes beyond the parameter schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'fetches' and the resource 'current temperature, humidity, and condition for a given city', which is specific and distinguishes it from unrelated siblings like calculator and password_generator.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for getting weather data but provides no explicit guidance on when to use it versus alternatives, nor does it mention prerequisites or when not to use it. The sibling tools are unrelated, so the context is clear, but guidance is minimal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

password_generatorB

Generates a random password of a given length, optionally including symbols.

ParametersJSON Schema
NameRequiredDescriptionDefault
lengthYesLength of the password. Must be between 6 and 32.
symbolsNoWhether to include symbol characters like @ # $ in the password.

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It does not disclose return type, randomness quality, or side effects. The tool is likely safe, but the description is too minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence that efficiently conveys the core function. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with full schema coverage, the description is adequate but lacks return value details. Given no output schema, mentioning the return type would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameters are already well-documented. The description adds no extra meaning beyond the schema, so baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool 'Generates a random password' with specific attributes: length and optional symbols. It is distinct from siblings like uuid_generator which generates UUIDs, not passwords.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., uuid_generator). The description only states what it does, not when it is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_notesA

Reads and returns the contents of the local notes.txt file.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses core behavior (returns file contents) but doesn't cover edge cases like file existence or encoding, which are relevant for a read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single concise sentence with zero wasted words, front-loading the purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema; description says 'returns contents' but doesn't specify format or error handling, leaving some ambiguity for a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so description doesn't need to add semantic value; baseline score of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states verb 'Reads and returns' and resource 'local notes.txt file', distinguishing it from unrelated sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for reading a local file, but no explicit guidance on when to use vs alternatives, though siblings are unrelated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

uuid_generatorA

Generates a list of random UUIDs (v4). Accepts a count between 1 and 20.

ParametersJSON Schema
NameRequiredDescriptionDefault
countYesHow many UUIDs to generate. Must be between 1 and 20.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully disclose behavior. It states generation of UUIDs and count limit, which implies a safe, non-destructive operation. However, it does not explicitly confirm that the tool is read-only or has no side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, front-loaded with the main action, no unnecessary words. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description is sufficiently complete for an AI agent to understand input constraints and output behavior. Could mention that output is a list of UUIDs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (count parameter fully described in both schema and description). The description adds context on the count range, but the schema already includes min/max constraints. No additional semantic value beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Generates' and resource 'random UUIDs (v4)', clearly stating the tool's function. It distinguishes from siblings like 'password_generator' by specifying UUIDs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly suggests usage for generating UUIDs with a count constraint, but does not explicitly state when to use this tool versus alternatives like 'password_generator' or other generation tools. The guidelines are adequate but not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv1.0.0
    • First observedcalculator
    • First observedget_weather
    • First observedpassword_generator
    • First observedread_notes
    • First observeduuid_generator

TDQS

A3.7/5.0
Disambiguation5/5

All five tools perform entirely distinct and unrelated functions: arithmetic, weather lookup, password generation, note reading, and UUID generation. There is no overlap or confusion between them.

Naming Consistency4/5

Most tool names follow a clear 'verb_noun' pattern (get_weather, read_notes, uuid_generator, password_generator). 'calculator' is a noun rather than verb_noun, but it is still unambiguous and fits the style.

Tool Count5/5

With 5 tools, the server is well-scoped and not overloaded. Each tool serves a clear, standalone purpose without redundancy.

Completeness3/5

Each tool is individually complete for its specific function; for example, calculator covers basic arithmetic. However, the tools are disconnected and do not form a coherent domain, so there is no sense of a full surface.

Maintenance

ActivityStale
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    A demonstration TypeScript MCP server that showcases basic MCP concepts with simple tools (greeting, calculator), text resources, and prompt templates for learning the Model Context Protocol.
    2
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol (MCP) server designed for learning and experimentation. It provides a foundational setup for developers to build, run, and debug MCP server implementations using Node.js.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    An educational repository designed to practice and understand the Model Context Protocol through simple server implementations. It demonstrates core MCP concepts such as tools, resources, and communication via stdio and SSE transport methods.
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abhishekmishra06/mcp-learning-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server