{
"mcpServers": {
"my-server": {
"url": "http://127.0.0.1:8000/mcp",
"type": "http"
}
}
}Are you the author?
Add this badge to your README to show your security score and help users find safe servers.
Zero-dependency MCP server implementation.
Is it safe?
No known CVEs for zeromcp.
No authentication — any process on your machine can connect.
MIT. View license →
Is it maintained?
Last commit 12 days ago. 74 stars.
Will it work with my client?
Transport: stdio, sse, http. Works with Claude Desktop, Cursor, Claude Code, and most MCP clients.
Context cost
3 tools. ~200 tokens (0.1% of 200K).
This server supports HTTP transport. Be the first to test it — help the community know if it works.
No known vulnerabilities.
greetGenerate a greeting message
struct_getRetrieve structure information by names
divideDivide two numbers
read_fileGet information about data.txt
file://data.txt
read_any_fileGet information about any file
file://{filename}
code_reviewReview code for bugs and improvements
This server is missing a description.If you've used it, help the community.
Add informationHave you used this server?
Share your experience — it helps other developers decide.
Sign in to write a review.
Persistent memory using a knowledge graph
Pre-build reality check. Scans GitHub, HN, npm, PyPI, Product Hunt — returns 0-100 signal.
Privacy-first. MCP is the protocol for tool access. We're the virtualization layer for context.
Monitor browser logs directly from Cursor and other MCP compatible IDEs.
MCP Security Weekly
Get CVE alerts and security updates for Zeromcp and similar servers.
Start a conversation
Ask a question, share a tip, or report an issue.
Sign in to join the discussion.
Minimal MCP server implementation in pure Python.
A lightweight, handcrafted implementation of the Model Context Protocol focused on what most users actually need: exposing tools with clean Python type annotations.
pip install zeromcp
Or with uv:
uv add zeromcp
from typing import Annotated
from zeromcp import McpServer
mcp = McpServer("my-server")
@mcp.tool
def greet(
name: Annotated[str, "Name to greet"],
age: Annotated[int | None, "Age of person"] = None
) -> str:
"""Generate a greeting message"""
if age:
return f"Hello, {name}! You are {age} years old."
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.serve("127.0.0.1", 8000)
Then manually test your MCP server with the inspector:
npx -y @modelcontextprotocol/inspector
Once things are working you can configure the mcp.json:
{
"mcpServers": {
"my-server": {
"type": "http",
"url": "http://127.0.0.1:8000/mcp"
}
}
}
For MCP clients that only support stdio transport:
from zeromcp import McpServer
mcp = McpServer("my-server")
@mcp.tool
def greet(name: str) -> str:
"""Generate a greeting"""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.stdio()
Then configure in mcp.json (different for every client):
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["path/to/server.py"]
}
}
}
zeromcp uses native Python Annotated types for schema generation:
from typing import Annotated, Optional, TypedDict, NotRequired
class GreetingResponse(TypedDict):
message: Annotated[str, "Greeting message"]
name: Annotated[str, "Name that was greeted"]
age: Annotated[NotRequired[int], "Age if provided"]
@mcp.tool
def greet(
name: Annotated[str, "Name to greet"],
age: Annotated[Optional[int], "Age of person"] = None
) -> GreetingResponse:
"""Generate a greeting message"""
if age is not None:
return {
"message": f"Hello, {name}! You are {age} years old.",
"name": name,
"age": age
}
return {
"message": f"Hello, {name}!",
"name": name
}
Tools can accept multiple input types:
from typing import Annotated, TypedDict
class StructInfo(TypedDict):
name: Annotated[str, "Structure name"]
size: Annotated[int, "Structure size in bytes"]
fields: Annotated[list[str], "List of field names"]
@mcp.tool
def struct_get(
names: Annotated[list[str], "Array of structure names"]
| Annotated[str, "Single structure name"]
) -> list[StructInfo]:
"""Retrieve structure information by names"""
return [
{
"name": name,
"size": 128,
"fields": ["field1", "field2", "field3"]
}
for name in (names if isinstance(names, list) else [names])
]
from zeromcp import McpToolError
@mcp.tool
def divide(
numerator: Annotated[float, "Numerator"],
denominator: Annotated[float, "Denominator"]
) -> float:
"""Divide two numbers"""
if denominator == 0:
raise McpToolError("Division by zero")
return numerator / denominator
Expose read-only data via URI patterns. Resources are serialized as JSON.
... [View full README on GitHub](https://github.com/mrexodia/zeromcp#readme)