Skip to content

Gateway & Routing

The gateway is the central entry point for all agent interactions. It exposes a single actx tool (~300 tokens) that accepts CTX strings, parses them into typed ASTs, routes them through a middleware pipeline, and returns structured results.

Agent → CTX Statement → Gateway → Middleware Pipeline → Plane Handler → Response
Sidecar (optional)
Signed Translation

Every CTX operation follows the same 5-step path:

  1. ParseCTXParser.parse() converts raw text into a typed CTXStatement AST
  2. Route — Gateway dispatches by operator × plane to the correct handler
  3. Execute — Plane handler fulfills the request (MCP call, DB query, etc.)
  4. Respond — Structured GatewayResult with { ok, op, ms, data }
  5. Translate — Sidecar (optional) creates Ed25519-signed human-readable log

The gateway uses a composable middleware architecture. Each concern is an independent, pluggable function:

OrderMiddlewarePurpose
1IdentityResolve agent identity from keypair
2DelegationMulti-agent delegation routing
3RBACRole-based access control validation
4*AlignmentSentinel alignment checks (opt-in via config)
5*HydrationEnrich request with agent memory context (opt-in)
6BudgetToken budget enforcement
7EconomyCost tracking via resource broker
8ScopeProject namespace scoping
9CTX EnforceGrammar validation and op×plane enforcement
10Scope EnforcePlugin scope boundary enforcement
11Tool FilterBackend role-based tool visibility
12TraceCTX cognition trace capture
13FormatResponse formatting (&json, &compact, etc.)
14RouterDispatch to the appropriate plane handler
15*AuditLog operations for compliance (opt-in)
  • = conditional middleware, only active when configured

Middleware is composable — each function receives a RequestContext and either modifies it, short-circuits with an error, or passes it to the next function.

Every gateway response follows the same structure:

interface GatewayResult {
ok: boolean; // Success or failure
op: string; // The operator-plane pair (e.g., "?k", ">t")
ms: number; // Execution time in milliseconds
data: unknown; // Plane-specific response data
error?: string; // Error message (when ok=false)
code?: string; // Machine-switchable error code
}

Example response:

{
"ok": true,
"op": "?t",
"ms": 4,
"data": {
"results": [
{ "name": "github.issues.list", "score": 0.95 },
{ "name": "github.issues.create", "score": 0.91 }
],
"count": 2
}
}

The gateway accepts input through multiple transport protocols:

ProtocolModuleUse Case
CLIcli/Direct queries via actx query
MCP (stdio/SSE)mcp/IDE extensions, agent frameworks
HTTPentry/REST clients, webhooks
TCPentry/High-throughput persistent connections
CTXB (binary)ctxb/Machine-to-machine transport (>2M ops/sec)

All transports converge into the same gateway pipeline — identical behavior regardless of how the agent connects.

MCP backends are managed through the BackendRegistry:

// Backends are configured in actx.yaml
backends:
- id: github
cmd: "npx -y @modelcontextprotocol/server-github"
roles: [code, issues]
transport: stdio
lazy: true
  • Lazy spawning — backends start on first tool query, not at gateway boot
  • Role scoping — agents only see tools from backends matching their roles
  • Namespace isolation — tool names are prefixed with the backend ID (e.g., github.issues.create)

The gateway is configured through GatewayConfig:

interface GatewayConfig {
backends: BackendConfig[];
planes: PlaneConfig;
contextDir: string;
surrealUrl?: string;
natsUrl?: string;
}

See Configuration for the full actx.yaml reference.