Skip to main content

Open source · Self-hosted

Everything an agent needs, except the model.

Memory, knowledge, permissions, orchestration, evaluations and traces in one open-source server you run yourself. The model comes from the provider you choose, hosted or local.

docker compose up -dwith the quick start's Compose file: PostgreSQL, Ollama and the server, offline.

soat · bashexit 0
# 1. create the agentsoat create-agent \  --project-id "$PROJECT_ID" \  --ai-provider-id "$PROVIDER_ID" \  --name support-bot \  --instructions "You are a helpful support assistant."# 2. open a sessionsoat create-session \  --agent-id "$AGENT_ID" \  --name user-chat-42# 3. add the messagesoat add-session-message \  --session-id "$SESSION_ID" \  --message "Hello!"# 4. generate the answersoat generate-session-response \  --session-id "$SESSION_ID" \  --wait true# the reply, plus a trace_id recording every tool call and token
The CLI is the whole API as sub-commands, so the path to a working agent is also a script you can commit.
Apache 2.0
licensed, nothing withheld
1 process
Node.js on PostgreSQL + pgvector
4 surfaces
REST, MCP, CLI, SDK from one OpenAPI document
v0.77.0
latest release, pre-1.0

When to use SOAT

Reach for SOAT when the agent has to be trusted with something.

A single model call needs no infrastructure. SOAT earns its place the moment an agent has to remember, retrieve, coordinate, stay inside its permissions, or account for what it did. These are the jobs it is built for, the same list an agent reads at /agents.md, where each one names the call that does it.

  1. 01

    Give an agent memory that survives the process

    Sessions and conversations persist message history in PostgreSQL.

    Sessions
  2. 02

    Ground an agent in your own documents

    Ingest files into chunked, embedded documents and search them with pgvector.

    Documents
  3. 03

    Run multi-step work deterministically instead of hoping one prompt covers it

    Orchestrations are DAGs of agent, tool, and human nodes; workflows are state machines for long-running work.

    Orchestrations
  4. 04

    Bound what an agent is allowed to do

    IAM policies gate every action, API keys scope to one project, guardrails screen input and output, and quotas cap spend.

    IAM
  5. 05

    Put a human in the loop without stopping the run

    Approval nodes and exceptions pause a run, record who decided what, and resume from the same point.

    Approvals
  6. 06

    Prove after the fact what an agent did and what it cost

    Every generation writes a trace with each tool call, model response, and token count, alongside an append-only audit log.

    Traces
  7. 07

    Change an agent in production without guessing whether it got worse

    Agent versions are append-only; a canary release splits traffic, and promotion is gated on a passing eval run.

    Agents
  8. 08

    Expose your own backend to an MCP client (Claude, Cursor, VS Code)

    Every REST operation is also an MCP tool, behind the same permission engine, with OAuth 2.1 discovery and Dynamic Client Registration.

    MCP
  9. 09

    Stand up a whole agent stack reproducibly

    Agent Formations declare providers, tools, agents, orchestrations, and webhooks in one template, resolve the dependency graph, and apply it.

    Formations

How a call flows

Every caller reaches the same logic through the same permissions.

SOAT is open-source infrastructure for production-ready AI agents. You bring the product; SOAT handles the layer underneath it.

The REST API and the MCP endpoint are one Node.js process calling the same business logic through the same permission engine, so a resource created on one surface is already visible on the others. The server and its PostgreSQL database are the whole stack. Each module below links to its documentation.

Nothing else to run:a message queuea vector databasean auth servera trace collectora scheduler

Callers

BackendREST /api/v1
Claude, Cursor, VS CodeMCP /mcp
CI and scriptssoat CLI
TypeScript app@soat/sdk
Browserweb app /app
SOAT serverone Node.js process · :5047
REST /api/v1MCP /mcp
Business logicPermission engine

State

PostgreSQL+ pgvector
  • rows and files
  • embeddings
  • message history
  • traces and audit log

Client surfaces

One backend. Four ways to call it.

The CLI, the SDK and the MCP tool surface are generated from the same OpenAPI documents the REST API is described by, so an operation that exists on one surface exists on all four. Pick the one that fits where your code runs. This is the same call, four times.

POST /api/v1/agents
curl -X POST http://localhost:5047/api/v1/agents \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{
"project_id": "proj_01HXYZ",
"ai_provider_id": "aip_01HXYZ",
"name": "support-bot",
"instructions": "You are a helpful support assistant."
}'
REST API docs
Authentication
one sk_ key or user JWT
Permission
agents:CreateAgent
Data
one PostgreSQL database
Contract
one OpenAPI document

Agent formations

Deploy a whole agent stack from one template.

Formations are the declarative layer. Describe the stack once, preview the plan, and SOAT creates or updates every dependent resource in the right order, with the same permissions and the same traceable operations as a hand-made call. Formations docs.

support-stack.yaml
resources:
Provider:
type: ai_provider
properties:
name: openai
provider: openai
default_model: gpt-4o
Docs:
type: memory
properties:
name: product-docs
Lookup:
type: tool
properties:
name: order-lookup
type: http
execute:
url: https://api.example.com/orders/{order_id}
method: GET
Support:
type: agent
properties:
name: support-bot
ai_provider_id: { ref: Provider }
knowledge_config:
memory_ids: [{ ref: Docs }]
tool_bindings:
- tool_id: { ref: Lookup }
Hook:
type: webhook
depends_on: [Support]
properties:
name: session-events
url: https://example.com/hooks/soat
events: ['sessions.*']

plan-formation resolves the template into this graph.

  1. 01

    Declare

    soat validate-formation

    One template, JSON or YAML: providers, memories, tools, agents, orchestrations and webhooks. Refs point at logical IDs, not at IDs that exist yet.

  2. 02

    Resolve

    soat plan-formation

    SOAT builds the dependency graph from refs and depends_on, rejects cycles, and provisions in topological rounds. Independent resources go in parallel.

  3. 03

    Operate

    soat list-formation-events

    Every create, update and delete lands in an immutable event log with the resources it touched and the outputs it produced. A failed deploy rolls back.

How SOAT compares

13 alternatives, one rubric, gaps included.

Every solution is rated on the same 15 capability clusters from its public documentation, checked between 2026-08-14 and 2026-08-18. SOAT is rated like the rest, and its own gaps are on the table: Channels (absent), Code execution (absent), Skill learning (absent).

SolutionTypeRunsAgent runtimeOrchestrationKnowledge & memoryTools & integrationIdentity & governanceObservabilityData & secretsEvaluationChannelsCode executionHuman-in-the-loopMulti-tenancyDeclarative deploymentVersioning & rolloutSkill learningNative
SOATInfrastructureself-hostedNativeNativeNativeNativeNativeNativeNativeNativeAbsentAbsentNativeNativeNativeNativeAbsent12/15
Amazon Bedrock AgentCoreManaged platformmanagedNativeNativeNativeNativeNativeNativePartialNativeAbsentNativeNativePartialNativeNativeAbsent11/15
Claude Developer PlatformManaged platformmanagedNativePartialPartialNativePartialNativeNativePartialAbsentNativeNativeNativePartialPartialPartial7/15
CrewAIFrameworkself-hosted / managedNativeNativeNativeNativePartialPartialAbsentPartialPartialNativeNativePartialPartialAbsentAbsent6/15
DeepSeek HarnessFrameworkself-hostedNativePartialVia pluginNativeAbsentPartialPartialAbsentVia pluginNativeNativeAbsentPartialAbsentAbsent4/15
DifyInfrastructureself-hosted / managedNativeNativeNativeNativePartialNativeNativeAbsentPartialNativeNativePartialPartialPartialAbsent8/15
Hermes AgentFrameworkself-hostedNativePartialNativeNativeAbsentPartialAbsentPartialNativeNativeNativeAbsentAbsentAbsentNative7/15
LangChain / LangGraphFrameworkself-hosted / managedNativeNativeNativeNativePartialPartialAbsentPartialVia pluginVia pluginNativePartialPartialPartialVia plugin5/15
LettaInfrastructureself-hosted / managedNativeNativeNativeNativePartialPartialAbsentAbsentNativePartialNativePartialVia pluginVia pluginNative7/15
Microsoft Agent FrameworkFrameworkself-hosted / managedNativeNativePartialNativePartialNativeAbsentNativePartialPartialNativeAbsentPartialAbsentAbsent6/15
Microsoft Foundry Agent ServiceManaged platformmanagedNativeNativeNativeNativeNativeNativePartialNativeNativeNativeNativePartialNativeNativePartial12/15
OpenAI Agents platformManaged platformmanagedNativeNativeNativeNativePartialNativePartialPartialPartialNativeNativeNativeAbsentPartialAbsent8/15
OpenClawFrameworkself-hostedNativePartialNativeNativePartialAbsentAbsentAbsentNativeNativeNativeAbsentAbsentAbsentPartial6/15
Vertex AI Agent BuilderManaged platformmanagedNativeNativeNativeNativePartialNativePartialNativePartialNativePartialPartialPartialNativeAbsent8/15

Built for agents

Everything on this site is readable by a machine.

Every page is server-rendered with its full text in the HTML and has a Markdown twin one URL away. The REST surface is one OpenAPI description and errors are a catalog of stable codes, so a client can be generated without scraping a page.

curl -H "Accept: text/markdown" https://soat.ttoss.dev/9 entries
pathtypewhat an agent gets
/agents.mdtext/markdownInstructions for an agent: which jobs SOAT is the right tool for, which it is not, how to authenticate and call it, and how to get access.
/llms.txttext/plainIndex of every documentation page, with a one-line summary and a link to each Markdown twin.
/llms-full.txttext/plainThe whole prose documentation corpus in one file, ready to be chunked and embedded.
/openapi.jsonapplication/jsonEvery REST operation of the SOAT API in a single OpenAPI 3.0 description — paths, schemas, and security schemes.
/openapi.yamlapplication/yamlThe same merged OpenAPI description in YAML, also served at /api/openapi.yaml.
/errors.jsonapplication/jsonCatalog of every error code the API can return, with its HTTP status and what to do about it.
/docs/openapi-specstext/htmlOne YAML spec per module under /openapi/<module>.yaml, for tools that prefer a narrower surface.
/sitemap.xmlapplication/xmlEvery canonical page with its last-modified date, so a crawler can fetch only what changed.
/robots.txttext/plainCrawl policy: everything is allowed, plus the sitemap link.

Send Accept: text/markdown to any documentation URL, or append .md, as in /docs/introduction.md. A dead URL answers a real 404 with a Markdown recovery map.

The four layers of an agent system

Harness first. Loop second. Graph last. Then the ratchet.

An agent system decomposes into four layers, and the investment order is not equal. SOAT is built around that order: every module owns one layer, so when a layer is the one failing you know which part of the platform to reach for. Read the framing.

  1. Harness

    What can this agent reach, and what is it forbidden?

    Most failures live here, and so do the cheapest wins. Tools are first-class resources, knowledge and memory are scoped, and every permission is a policy document.

  2. Loop

    What proves it did the job, and when does it stop?

    Output schemas, step limits and stop conditions bound the run. Guardrails classify every tool call before it executes, quotas fail closed, and each generation writes a trace.

  3. Graph

    What is allowed to happen next?

    DAG orchestrations with parallel rounds, state-machine workflows for long-running work, and triggers on a cron, a webhook or an event. Built last, because it is needed least often.

  4. Ratchetgoverns change itself

    How does the system change, and what proves the change was an improvement?

    Agent versions are append-only, a canary splits traffic, and promotion waits for a passing eval run against that canary. The platform owns the verdict; a human owns the judgment.

Getting access

No signup. No sales call. No waitlist.

SOAT is Apache-2.0 software you run yourself. A local deployment is the same software as a production one: the sandbox, the free tier and the product are one thing. Keys are minted by an API call, which matters because an agent cannot fill in a contact form.

Run it locally
  1. Nothing to sign up for

    SOAT is Apache-2.0 licensed and self-hosted. There is no account to create, no key to request, no trial to start, and no quota you have to ask anyone to raise.

  2. Run the stack

    Copy the Compose file from the quick start and run docker compose up -d. It brings up PostgreSQL with pgvector, a local Ollama for models, and the SOAT server on port 5047 — so the whole platform runs offline, with no third-party credential.

  3. Get the first credential

    POST /api/v1/users/bootstrap creates the first admin. It is open only until that admin exists, then closed for good, so the same call cannot be replayed against a running deployment.

  4. Issue your own API key

    POST /api/v1/api-keys (or soat create-api-key) mints a project-scoped sk_… key with exactly the actions of the policy you attach. Keys are self-serve and rotatable — POST /api/v1/api-keys/{api_key_id}/rotate.

  5. The sandbox is the same software

    There is no separate sandbox tier to request: a local instance is the product, so throwaway projects, seeded data, and destructive tests all run against your own deployment. Delete the volumes to reset.

Stop rebuilding agent infrastructure.

Self-host SOAT and ship agents that can reach what they need, prove they did the job, and improve on evidence.