Introduction
SOAT is open-source infrastructure for production-ready AI agents: IAM, file and document storage, vector search, conversational memory, agent orchestration, multi-agent workflows, RAG, declarative stack deployment, and a full MCP server in one self-hostable Node.js service backed by PostgreSQL.
The platform is organized around the four layers of an agent system: harness (what an agent can reach), loop (what proves a run did the job), graph (what happens next), ratchet (what proves a change was an improvement). The ratchet is the active build front: Where SOAT is going.
What you get out of the box
Identity & access management
- Users, projects, and project memberships
- Per-resource permissions via reusable IAM policy documents
- User JWTs, project API keys, and personal API keys with policy attachments
Storage & retrieval
- Files and structured documents scoped to projects
- pgvector embeddings and semantic search with score thresholds
- Memories as durable context stores, plus Knowledge for unified search across documents and memory entries
Agents & conversations
- Configurable agents with HTTP, MCP, client-side, and
builtin-platform tools - Multi-step reasoning loops with
tool_choice, step rules, and boundary policies - Multi-agent workflows: agents call other agents as tools
- Async generations: long-running jobs you can poll or wait on
- Sessions — 1↔1 user/agent interface that hides actors and conversations
- Conversations — multi-party message engine
- Chats — raw LLM completions without an agent
Orchestration & automation
- Orchestrations — deterministic DAG pipelines with parallel rounds, conditions, retries, and durable resumption
- Workflows — state graphs that durable tasks live in and move through, including backward
- Triggers start a flow on a cron schedule, an inbound webhook, or on demand
Governance & safety
- Guardrails classify every tool call from its arguments, deterministically, before execution
- Approvals — a human-decision queue with frozen evidence, hard expiry, and a recurrence view over repeated corrections
- Quotas fail closed on request, token, or cost caps; Usage meters every call with alert thresholds
- Append-only agent versions with staged canary rollout and served-version stamping
Operations
- Encrypted secrets for provider keys
- HMAC-signed webhooks with event-pattern subscriptions
- Traces for every generation — tool calls, latency, and cost-relevant fields — plus exceptions, activity, and an audit log
Declarative deployment
- Agent formations to define full agent stacks (providers, memories, tools, agents) in JSON/YAML
- Dependency-aware provisioning with operation history and event logs for each deployment
Where SOAT is going
The ratchet: produce a verdict from evidence, gate every change on it, keep history append-only. Versioned agents, canary rollout, the approvals recurrence view, and:
- Evaluations — datasets, scorers, and scored runs of the real agent compared against a baseline; a pass/fail verdict
- Eval-gated promotion — a canary release promotes only on a passing eval run against that canary
Promotion stays human-gated. Framing: The Layers of an Agent System; sequencing: roadmap.
Architecture
One Node.js process backed by PostgreSQL with pgvector exposes the REST API and the Streamable HTTP MCP endpoint; both call the same business-logic layer and permission engine.
One backend, four surfaces
| Surface | Best for | Docs |
|---|---|---|
| REST API | Backend services, custom integrations | API Reference |
| MCP server | Claude Desktop, Cursor, and other MCP-aware runtimes | MCP |
CLI (soat) | Scripts, CI pipelines, and local exploration | CLI |
SDK (@soat/sdk) | TypeScript and JavaScript applications | SDK |
All four share one permission check, one business-logic layer, and one response shape: each operation is gated by one permission action (e.g. documents:CreateDocument) on every surface (IAM & Policies). Trade-offs: Choosing a Client Surface.
Example — create a document
- CLI
- SDK
- curl
soat create-document \
--project-id proj_ABC \
--title "Release Notes" \
--content "Initial release."
import { SoatClient } from '@soat/sdk';
const soat = new SoatClient({
baseUrl: 'https://api.example.com',
token: 'sk_...',
});
const { data, error } = await soat.documents.createDocument({
body: {
project_id: 'proj_ABC',
title: 'Release Notes',
content: 'Initial release.',
},
});
curl -X POST https://api.example.com/api/v1/documents \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"project_id":"proj_ABC","title":"Release Notes","content":"Initial release."}'
Where to next
- Get started — Docker Compose in five minutes
- Key concepts — projects, agents, sessions
- Choosing a client surface — REST, SDK, CLI, or MCP
- Platform modules — every resource type