Skip to content

Instantly share code, notes, and snippets.

@runekaagaard
Created May 20, 2025 19:56
Show Gist options
  • Save runekaagaard/959d0bcf9a6425a78882a0c93bbb0f5b to your computer and use it in GitHub Desktop.
Save runekaagaard/959d0bcf9a6425a78882a0c93bbb0f5b to your computer and use it in GitHub Desktop.
Minimal vanilla mcp server in python
import sys, json, inspect
from typing import get_type_hints
## MCP Server "Framework" ##
TOOLS, TOOL_DEFINITIONS = {}, []
def tool(f):
TOOLS[f.__name__] = f
TOOL_DEFINITIONS.append(tool_definition(f))
return f
def write(data):
data["jsonrpc"] = "2.0"
print(json.dumps(data), flush=True)
def tool_definition(func):
type_hints = get_type_hints(func)
properties, required = {}, []
type_map = {int: "integer", str: "string", float: "number", bool: "boolean", list: "array", dict: "object"}
for name, param in inspect.signature(func).parameters.items():
if param.default is inspect.Parameter.empty:
required.append(name)
properties[name] = {"title": name, "type": type_map[type_hints[name]]}
return {
"name": func.__name__,
"description": (inspect.getdoc(func) or "").strip(),
"inputSchema": {
"properties": properties,
"required": required,
"type": "object"
}
}
def initialize(title, data):
return {
"id": data["id"],
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": title,
"version": "1.0"
}
}
}
def tools_list(data):
return {"id": data["id"], "result": {"tools": TOOL_DEFINITIONS}}
def tools_call(data):
try:
tool_func = TOOLS[data["params"]["name"]]
result, is_error = tool_func(**data["params"]["arguments"]), False
except Exception as e:
result, is_error = e, True
return {
"id": data["id"],
"result": {
"content": [{
"type": "text",
"text": str(result),
}],
"isError": is_error
}
}
def run(title):
for line in sys.stdin:
try:
data = json.loads(line)
except json.JSONDecodeError:
continue
method = data["method"]
if method == "initialize":
write(initialize(title, data))
elif method == "tools/list":
write(tools_list(data))
elif method == "tools/call":
write(tools_call(data))
## Example MCP server ##
@tool
def addition(num1: int, num2: int):
"""Addition of two numbers."""
return num1 + num2
@tool
def subtraction(num1: int, num2: int):
"""Subtraction of two numbers."""
return num1 - num2
@tool
def multiplication(num1: int, num2: int):
"""Multiplication of two numbers."""
return num1 * num2
@tool
def division(num1: float, num2: float):
"""Division of two numbers."""
if num2 == 0:
raise ValueError("Cannot divide by zero")
return num1 / num2
run("Basic math")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment