Implement the request handler of a minimal MCP server: handle(raw: str) -> str | None takes one raw
JSON-RPC 2.0 message and returns the raw JSON response (or None when no response is due).
-32700 (Parse error) with "id": null."jsonrpc": "2.0" and a string method → -32600 (Invalid
Request). Use its id if it has a valid one (string or integer), else null.-32600; if every item was a notification, return None.id key) gets no response, even if it fails.initialize → result {"protocolVersion": "2025-06-18", "capabilities": {"tools": {}}, "serverInfo": {"name": "practice", "version": "1.0.0"}}tools/list → {"tools": [{"name", "description", "inputSchema"}]} from the provided TOOLS, sorted
by name.tools/call with params: {"name", "arguments"}: unknown tool or arguments that violate the tool's
inputSchema (required keys; property types string / integer / number / boolean; integer excludes
booleans) → -32602 (Invalid params). Otherwise call the tool: result
{"content": [{"type": "text", "text": str(result)}], "isError": false}. If the tool raises, return
a result with isError: true and the exception message as text (tool errors are not protocol
errors).-32601 (Method not found).Error objects are {"code": ..., "message": ...} with the standard messages shown above.
Implement handle. Input: raw: str. Returns: str | None (JSON).
This code runs before yours (fake clients, clocks and the test harness). You can use its names; don't edit them.
import json
def _add(a, b):
return a + b
def _greet(name, excited=False):
return f"Hello, {name}{'!' if excited else '.'}"
def _divide(a, b):
return a / b
TOOLS = {
"add": {"description": "Add two integers.", "fn": _add,
"inputSchema": {"type": "object", "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}}, "required": ["a", "b"]}},
"greet": {"description": "Greet someone.", "fn": _greet,
"inputSchema": {"type": "object", "properties": {"name": {"type": "string"}, "excited": {"type": "boolean"}}, "required": ["name"]}},
"divide": {"description": "Divide two numbers.", "fn": _divide,
"inputSchema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]}},
}
def __harness__(fn, messages):
out = []
for m in messages:
raw = fn(m)
out.append(None if raw is None else json.loads(raw))
return out
import json
def handle(raw: str):
msg = json.loads(raw)
return json.dumps({"jsonrpc": "2.0", "id": msg["id"], "result": {}})
Run executes the public tests. Submit grades against public and hidden tests.
Implement the request handler of a minimal MCP server: handle(raw: str) -> str | None takes one raw
JSON-RPC 2.0 message and returns the raw JSON response (or None when no response is due).
-32700 (Parse error) with "id": null."jsonrpc": "2.0" and a string method → -32600 (Invalid
Request). Use its id if it has a valid one (string or integer), else null.-32600; if every item was a notification, return None.id key) gets no response, even if it fails.initialize → result {"protocolVersion": "2025-06-18", "capabilities": {"tools": {}}, "serverInfo": {"name": "practice", "version": "1.0.0"}}tools/list → {"tools": [{"name", "description", "inputSchema"}]} from the provided TOOLS, sorted
by name.tools/call with params: {"name", "arguments"}: unknown tool or arguments that violate the tool's
inputSchema (required keys; property types string / integer / number / boolean; integer excludes
booleans) → -32602 (Invalid params). Otherwise call the tool: result
{"content": [{"type": "text", "text": str(result)}], "isError": false}. If the tool raises, return
a result with isError: true and the exception message as text (tool errors are not protocol
errors).-32601 (Method not found).Error objects are {"code": ..., "message": ...} with the standard messages shown above.
Implement handle. Input: raw: str. Returns: str | None (JSON).
This code runs before yours (fake clients, clocks and the test harness). You can use its names; don't edit them.
import json
def _add(a, b):
return a + b
def _greet(name, excited=False):
return f"Hello, {name}{'!' if excited else '.'}"
def _divide(a, b):
return a / b
TOOLS = {
"add": {"description": "Add two integers.", "fn": _add,
"inputSchema": {"type": "object", "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}}, "required": ["a", "b"]}},
"greet": {"description": "Greet someone.", "fn": _greet,
"inputSchema": {"type": "object", "properties": {"name": {"type": "string"}, "excited": {"type": "boolean"}}, "required": ["name"]}},
"divide": {"description": "Divide two numbers.", "fn": _divide,
"inputSchema": {"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "number"}}, "required": ["a", "b"]}},
}
def __harness__(fn, messages):
out = []
for m in messages:
raw = fn(m)
out.append(None if raw is None else json.loads(raw))
return out
import json
def handle(raw: str):
msg = json.loads(raw)
return json.dumps({"jsonrpc": "2.0", "id": msg["id"], "result": {}})
Run executes the public tests. Submit grades against public and hidden tests.