Architecture
Web shell, API control plane, MCP server, deploy adapters, and where each runs.
Showly is a small set of services with hard, observable boundaries. This page is a tour of what each one does and how they connect.
Components
Web (apps/web) — Next.js App Router app. Renders the public marketing surface, /app workspace shell, /docs, and acts as the auth front end. Talks to the API via a server-side proxy so client components never see API tokens.
API (apps/api) — Fastify control plane. Owns the database, RBAC, audit log, pipeline orchestration, and tenant-aware reads/writes. Every mutation passes through this service.
MCP (apps/mcp) — MCP server exposing ~27 scoped tools covering the full loop: read (list_projects, list_sites, get_site_context, get_site_files, …), plan/apply (create_change_plan, apply_site_patch), build (create_preview, run_checks, retry_deployment), ship (request_publish on approval-workflow plans; publish_site and rollback_to_version act directly via a two-step in-conversation confirmation), inspect (get_deployment_logs, diagnose_deployment, list_deployments, diff_site_versions), and onboarding (list_templates, create_site_from_template, create_site_from_html, trial sites, signed upload/download URLs). See the tool reference for the full list. Backed by the API; MCP itself is a thin authentication + tool-schema layer.
Status (apps/status) — Public status page service. Reads /status-page from the API and renders HTML.
Ops jobs (apps/ops-jobs) — Background workers: domain verification, preview cleanup, audit archive, dunning, restore drills, cost attribution.
Analytics ingest (apps/analytics-ingest) — Edge pixel + server-side ingest for the Showly Analytics package.
Publish gateway (apps/publish-gateway-rs) — Rust edge service that serves visitor traffic for every deployed site: the *.showly.site wildcard, preview subdomains, and verified custom domains. Resolves the hostname to the site's current production (or preview) artifact and serves it from object storage.
Forms gateway — Receives form submissions from deployed sites and forwards them to the API. Admin CLI — Operator tooling for support and maintenance tasks against the control plane. These are supporting utilities; production publish is owned by the web UI/agent confirmation flow plus the API, with plan-required approval but no mandatory OTP enrollment.
Trust boundaries
┌────────────────┐ browser
│ apps/web │◄──────────── user (cookie session)
└──┬─────────────┘
│ service token + bridged web session
▼
┌────────────────┐
│ apps/api │◄──── apps/mcp ◄──── agent (MCP token)
└──┬─────────────┘
│ Drizzle ORM
▼
PostgreSQL + managed secrets store (AWS Secrets Manager)
Three trust planes:
- Browser ↔ Web. Cookie session, server actions, server-side proxy. Web never trusts the browser for cross-tenant claims.
- Web ↔ API. Internal bearer token plus a _web session bridge_ secret so API can verify the cookie was issued by a trusted Web instance.
- Agent ↔ MCP ↔ API. Per-MCP-client token with explicit scopes. Every tool call audits with the client id and the action.
Data residency
The API treats the workspace (organization) as the residency boundary. Multi-region is a planned Iteration 7+ concern; today everything is in the primary region.
Deploy targets
Showly deploys _user_ sites (your application code) and _Showly itself_. AWS is the primary cloud; GCP is the backup:
serverless-containeron AWS — primary target for server-rendered sites: container build, ECS Fargate service behind the platform load balancer.static-cdn— for SSG output: the artifact lands in S3 and the publish gateway serves it on the*.showly.siteedge.serverless-containeron GCP (Cloud Run) — the backup-cloud target; the scheduler prefers AWS and falls back here.- Enterprise workspaces can additionally register deployment targets in their own cloud accounts (AWS or GCP via OIDC).
Where to read next
- Site manifest — the document that drives every build.
- Previews and publishing — the publish loop in detail.
- RBAC and approvals — how access is scoped and gated.