Concepts

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:

  1. Browser ↔ Web. Cookie session, server actions, server-side proxy. Web never trusts the browser for cross-tenant claims.
  2. Web ↔ API. Internal bearer token plus a _web session bridge_ secret so API can verify the cookie was issued by a trusted Web instance.
  3. 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-container on 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.site edge.
  • serverless-container on 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).