Serving Agency Code
Agency can serve your functions and nodes over MCP (stdio) or HTTP REST, letting external tools and services call into your agents.
Exporting Functions and Nodes
Only items marked with export are exposed by the serve system:
export safe def add(a: number, b: number): number {
"""
Adds two numbers together.
@param a - First number
@param b - Second number
"""
return a + b
}
export node main(message: string) {
// This node will be callable via the serve system
return process(message)
}
def internal(): string {
// This function is NOT exported — it won't appear in the serve API
return "only used internally"
}The safe modifier tells the serve system that a function is read-only (no side effects). MCP clients see this as a readOnlyHint annotation.
MCP Server
Start an MCP server over stdio:
agency serve mcp myagent.agency
agency serve mcp myagent.agency --name "My Agent"Options:
--name <name>— Server name reported to MCP clients (defaults to filename)
The server implements the MCP protocol (JSON-RPC 2.0 over stdio) with tools/list and tools/call. Each exported function becomes an MCP tool with its description and Zod-derived JSON Schema.
HTTP Server
Start an HTTP REST server:
agency serve http myagent.agency
agency serve http myagent.agency --port 8080
agency serve http myagent.agency --api-key my-secret-keyOptions:
--port <port>— Port to listen on (default: 3545)--api-key <key>— Require Bearer token authentication--standalone— Generate a bundledserver.jsfile instead of starting a server
Routes
GET /list — Returns a manifest of available functions and nodes:
{
"functions": [
{ "name": "add", "description": "Adds two numbers together.", "safe": true }
],
"nodes": [
{ "name": "main", "parameters": ["message"] }
]
}POST /functions/:name — Call an exported function:
curl -X POST http://localhost:3545/functions/add \
-H 'Content-Type: application/json' \
-d '{"a": 3, "b": 4}'Response:
{ "success": true, "value": 7 }POST /nodes/:name — Run an exported node:
curl -X POST http://localhost:3545/nodes/main \
-H 'Content-Type: application/json' \
-d '{"message": "hello"}'Response:
{ "success": true, "value": { "result": "processed hello" } }Interrupts
If a node triggers an interrupt during execution, the response includes the interrupt data:
{
"success": true,
"value": {
"interrupts": [
{ "type": "interrupt", "effect": "std::read", "message": "Do you approve?" }
],
"state": "..."
}
}To resume after an interrupt, use POST /resume with the interrupts and your responses:
curl -X POST http://localhost:3545/resume \
-H 'Content-Type: application/json' \
-d '{
"interrupts": [... the interrupts array from above ...],
"responses": [{"type": "approve"}]
}'The responses array corresponds positionally to the interrupts array.
Authentication
When --api-key is set, all requests must include a Bearer token:
curl -H 'Authorization: Bearer my-secret-key' http://localhost:3545/listRequests without a valid token receive a 401 Unauthorized response.
Standalone Mode
Generate a self-contained server file that can be deployed without the Agency CLI:
agency serve http myagent.agency --standaloneThis produces a bundled .server.js file via esbuild.
What Gets Exported
| Syntax | Served as |
|---|---|
export def foo() | MCP tool / HTTP function |
export safe def foo() | MCP tool (with readOnlyHint) / HTTP function |
export node main() | HTTP node |
export static const x = ... | Available in module but not directly callable |
def foo() (no export) | Not served |
node main() (no export) | Not served |