Expose your program to any AI agent — an MCP server in one route
MCP is JSON-RPC. In Synsema the whole server is a dispatcher task and one POST route. Tools are tasks with real bodies, secrets stay sealed, and untrusted input runs under a capability ceiling.
The Model Context Protocol is how Claude, Cursor and every other MCP client call tools you expose. It is JSON-RPC over HTTP, so in a language with a native server and native JSON, an MCP server is a task that dispatches three methods and a route that calls it.
The whole server§
require serve(8080)
task rpc(id, result)
give {"jsonrpc": "2.0", "id": id, "result": result}
task tool_greet(args)
give {"content": [{"type": "text", "text": "Hello, " + args["name"] + "!"}]}
task mcp(req)
let id be req["id"]
when req["method"] == "initialize"
give rpc(id, {"protocolVersion": "2025-06-18", "serverInfo": {"name": "demo", "version": "1.0"}, "capabilities": {"tools": {}}})
otherwise when req["method"] == "tools/list"
give rpc(id, {"tools": [{"name": "greet", "description": "Greet someone", "inputSchema": {"type": "object", "properties": {"name": {"type": "string"}}, "required": ["name"]}}]})
otherwise when req["method"] == "tools/call"
let p be req["params"]
when p["name"] == "greet"
give rpc(id, tool_greet(p["arguments"]))
give rpc(id, {"content": [{"type": "text", "text": "unknown tool"}], "isError": true})
give rpc(id, {})
serve on 8080
route "POST /mcp"
give mcp(json of request)
Point a client at http://host/mcp and greet is in its tool list. The dispatcher is a pure task, so it is unit-tested with synsema test like any other.
Tools that do real work§
A tool is a task with a body. Query a database, call an API, compute — and return content:
task tool_orders(args)
require db("./store.db")
let rows be sql("SELECT id, total FROM orders WHERE customer = ?", [args["customer"]])
give {"content": [{"type": "text", "text": json_encode(rows)}]}
Wrapping a legacy REST API is the same shape with http_get inside — the agent gets a typed tool, you keep the API untouched, and the API key travels as a sealed secret the model never sees.
Untrusted input, bounded§
If a tool runs code or input you do not trust, run that part under a host ceiling (--cap-set). The Synsema docs site does exactly this: its /mcp endpoint offers run_synsema and test_synsema tools that execute snippets in a sandbox, so an agent can verify the code it writes.
Next step: the MCP page in the docs, and — to distribute a tool with its permissions attached — Lamps.