MCP Hub
Back to servers

MCP Server Example

A reference implementation of a Model Context Protocol server that demonstrates core primitives including tools, resources, and prompts. It enables users to perform basic arithmetic operations and manage notes through a simple storage system.

glama
Updated
Mar 13, 2026

MCP Server Example

A simple MCP (Model Context Protocol) server for learning the core primitives: Tools, Resources, and Prompts.

Setup

Prerequisites

  • Python 3.10+
  • uv

Install

uv sync

Test

Option 1 — MCP Inspector (recommended)

uv run mcp dev server.py

Opens a browser UI at http://localhost:6274. From there you can:

  • Tools tab: call add, multiply, save_note, delete_note with custom inputs
  • Resources tab: read notes://list or notes://{name}
  • Prompts tab: run summarize_notes or brainstorm with arguments

Option 2 — CLI with mcp client

List all available tools:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | uv run python server.py

Call a tool (e.g. add 3 + 4):

echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"add","arguments":{"a":3,"b":4}}}' | uv run python server.py

Connect to Claude Code (CLI)

Add the server to your Claude Code session:

claude mcp add learning-mcp -- uv run --directory /Users/binod/projects/mcp-example python server.py

Verify it's connected:

claude mcp list

Once added, Claude Code can call your tools directly in the chat — just ask it to, e.g. "save a note called 'ideas'" or "what is 3 + 5?".

Connect to Claude Desktop

Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "learning-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/Users/binod/projects/mcp-example",
        "python", "server.py"
      ]
    }
  }
}

Then restart Claude Desktop.

Use programmatically (Python)

Use the mcp library to call tools, read resources, and fetch prompts from your own code:

from mcp import ClientSession
from mcp.client.stdio import stdio_client, StdioServerParameters
import asyncio

async def main():
    server = StdioServerParameters(
        command="uv", args=["run", "python", "server.py"]
    )
    async with stdio_client(server) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # Call a tool
            result = await session.call_tool("add", {"a": 3, "b": 4})
            print(result)  # 7.0

            # Read a resource
            notes = await session.read_resource("notes://list")
            print(notes)

            # Get a prompt
            prompt = await session.get_prompt("brainstorm", {"topic": "side projects"})
            print(prompt)

asyncio.run(main())

To let Claude (via Anthropic API) call your tools, add anthropic[mcp] to your dependencies and convert the tools:

from anthropic.lib.tools.mcp import async_mcp_tool
import anthropic

client = anthropic.AsyncAnthropic()
tools = [async_mcp_tool(t, session) for t in (await session.list_tools()).tools]

runner = client.beta.messages.tool_runner(
    model="claude-opus-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Save a note called ideas"}],
    tools=tools,
)
async for message in runner:
    for block in message.content:
        if hasattr(block, "text"):
            print(block.text)

What's inside

FileDescription
server.pyMCP server with tools, resources, and prompts
pyproject.tomlProject dependencies

Tools (Claude can call these)

ToolDescription
add(a, b)Add two numbers
multiply(a, b)Multiply two numbers
save_note(name, content)Save a note
delete_note(name)Delete a note

Resources (Claude can read these)

URIDescription
notes://listList all saved notes
notes://{name}Read a specific note

Prompts (reusable templates)

PromptDescription
summarize_notesSummarize all saved notes
brainstorm(topic)Brainstorm ideas on a topic

Reviews

No reviews yet

Sign in to write a review