Agent orchestration:
a layer over the OpenClaw runtime
OpenClaw is an open-source CLI agent runtime designed to run on a personal machine. I built the layer that turned it into a multi-tenant service — an HTTP orchestration API, per-user agent assignment, a custom tool extension and an MCP server — deployed across two products.
Internal platform. Built on the open-source OpenClaw agent runtime.
THE RUNTIME — NOT MINE
OpenClaw
An existing open-source CLI agent runtime, authored by its own maintainers and designed to run for one person on one laptop.
Single-user by design
No concept of organisations, no per-user agent ownership, no HTTP service boundary.
Everything on this page sits above that boundary. The runtime was consumed as a dependency, not modified into one.
Status
The per-user agent-assignment layer is dormant. It ran in production across both products; the surrounding products have since moved on.
THE ORCHESTRATION LAYER — WHAT I BUILT
Two FastAPI orchestration backends
OpenClawApi and NetworkChainApi expose the runtime over HTTP — agent CRUD, chat, scheduled jobs, knowledge contexts, integrations and billing.
Custom TypeScript tool extension
265 tools across 57 integrations, loaded into the runtime as an extension rather than forked into it.
MCP server
40 tools over stdio or SSE, a second front-door onto the same surface.
WebSocket JSON-RPC client
One persistent multiplexed connection drives the runtime, replacing per-session process control.
Billing and metering
Usage metered against a versioned price book, with wallet gates on top.
PER-USER AGENT ASSIGNMENT
Per-user / per-org assignment
Agents are assigned to users and organisations on a runtime that had no concept of either.
Row-level scoping
Org and user scoping applied at the row level, with soft deletes so removals stay recoverable.
Federated identity
Identity comes from an upstream backend behind a constant-time shared-secret check — no local user table.
RBAC at the proxy
Filtering is applied at the proxy, so a foreign agent id returns an empty result rather than leaking that it exists.
TOOL SURFACE
TypeScript extension — 265 tools
The broad surface, spanning 57 integrations, 36 of them OAuth 2.0 providers.
MCP server — 40 tools
Exposed over stdio or SSE for external MCP clients.
Per-agent lazy filtering
Tools are resolved per agent behind a 5-second cache.
Cache-invalidation route
A newly assigned integration appears on the agent's next attempt rather than waiting out the TTL.
Public Q&A guard
Hides all but 5 read-only context tools, so a founder's private integration data can never surface on a public page.
AGENT RUNTIME LINK
Multiplexed WebSocket
One persistent JSON-RPC connection carrying every agent session, so the runtime is driven as a remote peer rather than per-session process control.
device_id
The sha256 of the raw 32-byte Ed25519 public key.
Signed payload
A pipe-joined protocol-v3 string, signed on handshake.
KNOWLEDGE & MEMORY
agent_memory
A single 1536-d Qdrant collection on text-embedding-3-small.
Two sources, one collection
Third-party integration data and manual knowledge contexts, separated by payload filter.
Chunking
800-character chunks with 100-character overlap.
Scheduled agent jobs
Celery and Celery-Beat run agent jobs and a daily integration sync, with a dead-letter queue and hourly retry.
TENANCY & BILLING CONTROLS
Locked model selection
The model is chosen at agent creation from the allowlist and never updated by PATCH.
Local validation
An unknown model fails fast with a 400 instead of the gateway erroring mid-chat.
Fernet-encrypted credentials
Every stored OAuth credential value is encrypted at rest, across 36 providers.
Versioned price book
Usage metered against a versioned price book so historical spend never shifts under a repricing.
Wallet gates
Balance gates on usage, with automatic cron disabling on a negative balance.
PER-AGENT MODEL ALLOWLIST
The model is locked at agent creation and validated locally, so an unknown value fails fast with a 400 instead of the gateway erroring mid-chat.
TECHNICAL ARCHITECTURE
backend
Python + FastAPI
Two orchestration backends over the runtime
SQLAlchemy 2 + Alembic
Tenancy, agents, integrations and billing
PostgreSQL + Redis
Primary store and broker
platform
TypeScript tool extension
265 tools across 57 integrations
MCP server
40 tools over stdio or SSE
Celery + Celery-Beat
Scheduled jobs with a dead-letter queue
retrieval
Qdrant
agent_memory collection, 1536-d
text-embedding-3-small
800-character chunks, 100-character overlap
Docker
Containerised services end to end
