AGENTWORKFLOWAPI SURFACE
SURFACES
console · app · portal · embed
React · TanStack · Tailwind
DATABASE
PostgreSQL · pgvector · pg_trgm · row-level tenant isolation · audit log
PLATFORM
AWS Lightsail compute · Caddy TLS · paired replicas
EXTERNAL MCP CLIENTS
Claude Desktop · Cursor · outside
OAuth · PKCE · DCR
LLM PROVIDERS
five providers · automatic failover · transcription swap · metered
AGENT SAFETY PERIMETER
framing · directive · markers · tool · content
SIGNALS
semantic triage · kind pills · outcomes · agent-initiated, not user-driven
THE MCP CONTRACT
the platform agent is an MCP client, on the same path any external client uses
DETERMINISTIC LAYER
in-process DAG · typed triggers · typed nodes · typed actions
THE SINGLE SEAM
every call, every client — authorised once · FastAPI · Pydantic · OpenAPI · typed SDK · MCP
01SCHEMA-DRIVEN SUBSTRATE
Extending Actionary is metadata, not React.
entity registry · field metadata · one render pipeline · agent catalogue · no bespoke UI
02AGENT-NATIVE
Every capability is a tool. The agent reads your data.
entity catalogue as world model · agent-readable library · vector search · HNSW · Whisper A/V · visibility gate
03METERED ECONOMICS
Margin on every token, minute, and gigabyte.
per-tenant Stripe cost-plus · agent tokens · embedding calls · Whisper minutes · S3 · prompt caching · routing
04CONTINUOUS DELIVERY
Zero-downtime deploys. Phased migrations.
paired replicas · Caddy round-robin · health-gated rollout · one-shot migrate · expand→contract · sha256
OBSERVABILITY — MEASURED AT EVERY LAYER
OTEL W3C traceconversation logtool-call ledgerp50/p95 per tool50-call drilldown
SECURITY — A PROPERTY OF EVERY LAYER
RBACTenant IsolationAudit LogMaster Key + HKDFOAuth · PKCETLSSOC 2-Ready
SWAP PATHS BUILT IN

Every load-bearing layer is replaceable.

DATA PLANE
PostgreSQL
RDS · Cloud SQL · Supabase · any Postgres-compatible
OBJECT STORAGE
S3 API
Cloudflare R2 · MinIO · Backblaze B2 · any S3-compatible
VECTOR SEARCH
pgvector
in the same database, portable in the same pg_dump
CACHE & QUEUE
Redis wire protocol
KeyDB · Dragonfly · any Redis-compatible
OBSERVABILITY
OpenTelemetry
Tempo · Honeycomb · Datadog · Grafana Cloud · AWS X-Ray
LLM PROVIDER
five streaming adapters
Anthropic · OpenAI · AWS Bedrock · Azure · Gemini · BYOK per tenant
TRANSCRIPTION
TranscriptionProvider protocol
Whisper local · any hosted STT · BYOK per tenant
AGENT TOOL SURFACE
MCP
any DCR-compliant MCP client · Claude Desktop · Cursor · outside
MACHINE AUTH
OAuth + PKCE + DCR
any IETF-standard OAuth authorization server
SSO
OIDC
any OIDC identity provider
RUNTIME
Docker Compose
Kubernetes · ECS · any container orchestrator
TLS + INGRESS
Caddy
any reverse proxy that speaks ACME + HTTP/3

One data plane

Underneath the four hosts sits a small set of backing services. Every one is interchangeable at a config level.

  • PostgreSQL — the single source of truth. Rows, workflow state, audit log, agent reflection memory, and retrieval chunks all live in the same instance. A standard database dump produces a portable backup of the entire stack. Continuous point-in-time recovery at five-minute granularity on managed Postgres today; the connection string is one configuration change away from RDS, Cloud SQL, or Supabase. Every multi-tenant table carries a tenant id and a Postgres row-level-security policy keyed on the request-scoped tenant setting.
  • Vector search in the same Postgres. Retrieval and agent memory ride on the standard Postgres vector extension in the same instance. Reflection embeddings and upload chunks are stored as native vector columns, indexed for cosine search. The same per-row visibility gate that governs every SPA list endpoint governs the vector reads.
  • S3-compatible object store — uploads and backups through a portable storage adapter. Any S3-compatible endpoint — AWS S3, Cloudflare R2, MinIO, Backblaze B2 — is one configuration change away. Browser uploads use presigned PUT URLs; bytes never traverse the application server.
  • Redis — cache, rate limits, workflow-step claims, MFA pending-secret cache, and the upload-indexer queue drained by a single-consumer worker.
  • OpenTelemetry backbone — vendor-neutral OTLP spans and metrics from every service. The exporter (Tempo, Honeycomb, Datadog, Grafana Cloud, AWS X-Ray) is a configuration choice.

Every load-bearing layer at the boundary is a public specification with more than one compatible implementation. See open standards for the full stance.

Isolated services with clean seams

Three stateless application services, each independently horizontally scalable.

  • Core API — the authoritative surface. Serves the JSON API for the SPA, hosts the embedded LLM agent loop, and drives every write to Postgres and object storage. Reads shape metadata from the entity metadata layer on every request.
  • MCP server — the Model Context Protocol surface for external AI clients. OAuth authorisation-code with mandatory PKCE and audience-bound tokens (RFC 8707). Zero authentication tools by design — credentials never travel as tool arguments.
  • SPA bundles — three separately built browser artifacts (staff and tenant workspace, external client portal, embeddable widget) served by minimal static-content containers behind the reverse proxy.

Every service is stateless. Every service scales by adding replicas. Configuration flows via environment variables only, per Wiggins’s Twelve-Factor App from 2011. The MCP server is a thin pass-through to the API service layer — fixes belong in the API, and MCP inherits them. Every capability lands in exactly one place.

The takeaway

Four hosts. One data plane. Two services with one contract. Paired replicas rolling behind an active-health-probed round-robin. Every boundary that matters is a physical boundary; every backing service is portable at a config level. The code is the same across shared-tenancy, vanity-domain, and dedicated deployments — the deployment differs, the connection string differs, the application stays put.

This is the substrate technical buyers audit. Read for CTOs for the buyer-side view.