mcpatom
mcpatom
A minimal Python MCP Server SDK.
From Greek atomos: indivisible. The whole library is a single file,
mcpatom.py, consumable two ways:
Copy the file into your project. No dependency, no lockfile entry.
Install the package:
pip install mcpatom- the file itself is the installed module.
Scope
Tools, resources, and prompts, over stdio or streamable HTTP.
Protocol versions
2026-07-28(stateless, per-request_meta) and theinitialize-handshake versions2025-11-25and2025-06-18, served side by side.stdlib-only Python >= 3.10, no dependencies, ever.
Everything else (sampling, elicitation, subscriptions, auth, etc.) is deliberately omitted.
Usage
from mcpatom import Server
srv = Server("my-server")
@srv.tool
def greet(name: str, excited: bool = False) -> str:
"""Return a greeting for the given name."""
return f"Hello, {name}{'!' if excited else '.'}"
@srv.resource("data://motd")
def motd() -> str:
"""Message of the day."""
return "Be indivisible."
@srv.prompt
def haiku(topic: str) -> str:
"""Ask for a haiku."""
return f"Write a haiku about {topic}."
srv.serve_stdio()For streamable HTTP instead of stdio, end with:
srv.serve_http(8388) # http://127.0.0.1:8388/mcpserve_http accepts only localhost (and the bind host) as Origin/Host;
allowed_origins=["*.example.com"] replaces that list, ["*"] allows
any origin, and host="0.0.0.0" requires it.
More runnable servers in examples/.
Schemas and return types
Each function's name, docstring, and annotations become the tool's name,
description, and schema; @srv.tool(name=, description=, input_schema=, output_schema=) override generation, and extra= merges raw fields into
the listing. Server() also takes version= and instructions=.
Parameters may be annotated with any of these:
strintfloatboollist[X](or barelist)Literal[...]TypedDictX | Noneof any of the above
Annotated[X, "text"] adds a description the model sees. A parameter's
default is published in the schema when it is JSON-representable; a None
default is omitted unless null is a selectable Literal value.
A tool may return:
str- one text blockdict- JSON text plusstructuredContent; aTypedDictreturn annotation publishes the matchingoutputSchemaImage(data, mime_type)/Audio(data, mime_type)- one binary block (raw bytes in, base64 on the wire)a tuple - one block per item:
strtext,Image/Audiomedia, a dict whose"type"names a spec block type verbatim (e.g.resource_link)None- empty content; any other JSON value - text
Raising is the error API: any exception becomes isError content the
model can read and correct.
Resources return str (text) or bytes (base64 blob).
Prompts take only str arguments and return a str user message, or a
list of message dicts passed through verbatim.
Wiring it up
claude mcp add my-server -- /abs/path/.venv/bin/python /abs/path/server.pyor in any mcpServers config:
{"mcpServers": {"my-server": {"command": "/abs/path/.venv/bin/python", "args": ["/abs/path/server.py"]}}}Smoke test without a client:
echo '{"jsonrpc":"2.0","id":1,"method":"server/discover"}' | python server.py
# {"jsonrpc":"2.0","id":1,"result":{"resultType":"complete","_meta":{...},"supportedVersions":[...],"capabilities":{"tools":{}},"ttlMs":0,"cacheScope":"private"}}Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/physcat/mcpatom'
If you have feedback or need assistance with the MCP directory API, please join our Discord server