simple-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@simple-mcp-serverWhat's the weather in Tokyo?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Simple MCP Server Demo š
A full-featured demonstration project for the Model Context Protocol (MCP) built with TypeScript and @modelcontextprotocol/sdk.
This project showcases all three primary primitives of the MCP standard:
š ļø Tools ā Functions and actions executed by the AI model.
š Resources ā Data sources and context attachments read by the AI model via URIs.
š¬ Prompts ā Reusable, parameterized prompt templates and workflows.
It is structured to run both locally via Stdio (for Claude Desktop, IDEs, Inspector) and in the cloud on Vercel as a Serverless API (using Web Standards Streamable HTTP transport).
š Features Included
1. Tools
get_greeting: Greets a user by name with a friendly message.calculate: Performs arithmetic operations (add,subtract,multiply,divide,power) with safety checks (e.g. division by zero).fetch_weather: Fetches live, real-time weather forecasts for any city worldwide using the free Open-Meteo REST API (no API key required).add_note: Creates and stores a note in server memory with a custom ID.list_notes: Lists all notes currently stored in server memory.
2. Resources
Static Resource (
system://info): Returns host OS, Node.js version, memory usage, uptime, and timestamp in JSON format.Dynamic Resource Template (
notes://{id}): Reads specific note details and markdown content dynamically by ID.
3. Prompts
code_review: A structured code review prompt template that instructs the LLM to inspect code for security, performance, readability, and recommendations.summarize_notes: A prompt template that pulls all stored server notes and asks the model for an executive summary.
Related MCP server: creating-your-first-mcp-server
š Getting Started
Prerequisites
Node.js (v18 or higher)
npm
Installation
npm installDevelopment
Run the server locally over Stdio:
npm run devRun Local Automated Test Suite
npm testType Checking
npm run typecheckš Testing Interactively with MCP Inspector
The official MCP Inspector provides an interactive web UI to test and debug your MCP server:
npx @modelcontextprotocol/inspector tsx src/stdio.tsOnce running, open the URL provided in your terminal (usually http://localhost:5173) to test:
Tools tab: Execute
calculate,fetch_weather(e.g. city:"Tokyo"),add_note, andlist_notes.Resources tab: Read
system://infoornotes://welcome.Prompts tab: Test the
code_reviewandsummarize_notestemplates.
š Connecting to Local MCP Clients (Claude Desktop)
Add the following to your claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"simple-mcp-server": {
"command": "npx",
"args": [
"-y",
"tsx",
"/Users/saheel-ahmed/Projects/demos/saheel-git-repo/simple-mcp-project/src/stdio.ts"
]
}
}
}āļø Deploying to Vercel
This repository includes a serverless endpoint ready for Vercel in api/index.ts using WebStandardStreamableHTTPServerTransport.
Deploy using Vercel CLI
npx vercelFollow the interactive prompts to link and deploy your project.
Or Deploy via GitHub
Push this repository to GitHub.
Go to vercel.com/new and import the repository.
Click Deploy.
Once deployed, your remote MCP server endpoint will be live at:
https://<your-project-name>.vercel.app/apiRemote MCP clients can connect to this URL using the SSE/Streamable HTTP transport!
š Project Structure
simple-mcp-project/
āāā api/
ā āāā index.ts # Vercel Serverless Function entrypoint (HTTP / Web Standards)
āāā src/
ā āāā index.ts # Local entrypoint (Stdio transport)
ā āāā server.ts # MCP Server definition (Tools, Resources, Prompts)
ā āāā test-client.ts # Automated integration test suite
āāā tsconfig.json # TypeScript configuration
āāā vercel.json # Vercel routing configuration
āāā package.json # Dependencies, scripts, and build setup
āāā README.md # Project documentationAvailable Tools
5 toolsadd_noteA
Stores a new note in server memory.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Unique identifier/slug for the note (e.g. 'project-ideas') | |
| title | Yes | Title of the note | |
| content | Yes | Body content of the note |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It does reveal that this is a mutating operation and names the storage location as "server memory," but it does not state whether an existing note with the same ID is overwritten, whether storage is persistent, what errors may occur, or what the tool returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or redundant information. It states the essential action and object efficiently while leaving detailed parameter semantics to the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter create action with fully documented parameters, the description is minimally viable. However, there is no output schema, no mention of return values or confirmation, and no disclosure about duplicate-ID behavior, so an agent cannot fully anticipate the tool's side effects and response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds no extra parameter meaning beyond "new note," but the schema already documents id, title, and content adequately. The description does not clarify the uniqueness constraint on id or how the fields relate to the stored note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a clear action and resource: "Stores a new note in server memory." The word "Stores" plus "new note" distinguishes it from the read-only sibling list_notes, so an agent can identify it as the create operation without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, and no alternatives are mentioned. However, the phrase "stores a new note" implies the intended use case, and the only directly related sibling is list_notes, so the usage is reasonably inferable. It lacks clear exclusions such as behavior for duplicate IDs or how it differs from updating a note.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculateA
Performs arithmetic operations (add, subtract, multiply, divide, power).
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | First number operand | |
| b | Yes | Second number operand | |
| operation | Yes | The arithmetic operation to perform |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosing behavior, but it only lists the operations without mentioning edge cases such as division by zero, overflow, or error handling. The pure, deterministic nature of arithmetic is implied rather than explicitly stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence that front-loads the tool's purpose and enumerates the operations with no filler. It is appropriately sized and every word contributes to understanding the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple calculator with three required, fully documented parameters and an obvious numeric return value, the description is mostly complete. It omits edge-case behavior like division by zero, but the schema's thorough parameter documentation compensates for this minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides full descriptions for all three parameters, including an enum for the operation, so the schema description coverage is 100%. The description simply restates the same operations in prose without adding any semantic detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Performs') and resource ('arithmetic operations'), and enumerates the exact operations it supports. It is obviously distinct from the sibling tools (greeting, weather, notes), leaving no ambiguity about its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives, and no exclusions are mentioned. While the sibling tools are unrelated and the use case is self-evident, the description still does not provide any selection context or conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_weatherA
Fetches live weather forecast for any city using Open-Meteo.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | City name to fetch weather for (e.g. 'London', 'Tokyo', 'San Francisco') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It conveys read-only external fetching via 'live' and 'using Open-Meteo', which is helpful, but it does not disclose error behavior for unknown cities, units, network/API dependencies, or the shape of the returned forecast. These gaps are notable because no annotations or output schema fill them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler and no repetition of schema details. Every word adds meaning: operation, scope, live-like behavior, and data source are all present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool, the description is adequate for selection and initial invocation, but without an output schema it should say more about what the forecast contains, such as temperature or conditions, and how failures are handled. The absence of annotations increases the burden, leaving meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides full coverage for the only parameter, city, including examples. The description adds only 'any city', which reinforces the schema's unconstrained string type. No additional parameter semantics are supplied, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetches') and object ('live weather forecast') and scopes it to 'any city', naming the data source. This makes the tool's function unambiguous and distinguishes it from the sibling tools, none of which involve weather or external data retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly implies the intended use: whenever a live weather forecast for a city is needed. It does not explicitly mention exclusions or alternatives, but the sibling tools are unrelated, so no alternative-routing is necessary. It only lacks an explicit 'use this instead of X' style statement to earn a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_greetingB
Returns a personalized welcome message.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name of the person to greet |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It clearly indicates a read-only, side-effect-free operation by saying 'Returns,' but it does not describe output format, error behavior, or any edge cases. For a trivial getter, this is minimally adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. The core behavior is front-loaded, and the sentence is easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one required, fully documented parameter and a trivial string-like output, the description is sufficient. It does not specify the exact message format, but that is unlikely to prevent correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents the only parameter, 'name.' The description adds no new parameter-level detail beyond implying personalization, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Returns') and a clear resource ('a personalized welcome message'), so an agent can understand what the tool does. It does not explicitly distinguish itself from siblings, but the sibling names are unrelated and the behavior is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, and no mention of prerequisites or context. The intended use is only implied by the tool name and the simple phrase 'personalized welcome message.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_notesA
Lists all available notes stored in server memory.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. 'Lists' implies a safe read operation and 'stored in server memory' provides context, but the description does not disclose return format, ordering, emptiness behavior, or potential errors. It is minimally transparent but lacks richer behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one short, front-loaded sentence with no filler. It states the action, scope, and storage location efficiently, earning every word.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool, the description is sufficient to invoke correctly: the agent knows what will be listed and where the data lives. However, the absence of an output schema and any mention of return shape or edge cases leaves minor ambiguity about what a caller should expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters rooftrivial coverage is 100%, so there are no parameter semantics to explain. The baseline of 4 applies because there is nothing for the description to add beyond the already-complete schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Lists'), a clear resource ('all available notes'), and a location ('server memory'). It is immediately distinct from siblings like add_note and unrelated tools like calculate or fetch_weather.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this is the tool to call when the agent needs to see all stored notes. It does not explicitly state when not to use it or compare with alternatives, but the zero-parameter scope and contrast with add_note make the usage context clear.
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.
5 tool updates
v1.0.0- First observed
add_note - First observed
calculate - First observed
fetch_weather - First observed
get_greeting - First observed
list_notes
TDQS
Scored across 5 tools
Each tool addresses a distinct function: greeting, arithmetic, weather, and note management. There is no overlap or ambiguity between them.
Tool names follow a consistent snake_case verb pattern, mostly verb_noun (get_greeting, fetch_weather, add_note, list_notes). 'calculate' is a lone verb but still fits the predictable style.
Five tools is a reasonable size for a simple utility server. Each tool has a clear purpose and none feel redundant or excessive.
Core functionality for each utility is present, but note management lacks delete or update operations. This is a minor gap for a simple note-taking feature, not a critical omission.
Maintenance
Related MCP Connectors
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Nifty's MCP server ā exposes tasks, projects, messages, and files as tools for AI agents.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
MCP server for AI agent profiles and smart notes. 60+ coding prompt packs with expert personas.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA demonstration MCP server showcasing tools (calculator, file operations, weather, timestamp), resources (server config, system info, documentation), and reusable prompt templates for code review, documentation, and debugging.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables to perform mathematical calculations, retrieve weather information, and manage files through a standardized MCP interface, showcasing best practices for building MCP servers.1MIT
- AlicenseNot gradedqualityDmaintenanceThis MCP server provides tools like weather lookup and follows the Model Context Protocol for tool calling, resource sharing, and prompt templates.261 npmMIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI assistants to call weather tools, read resources, and use prompt templates for live weather data integration.1,020 npmMIT