From 85a9731e1894ee4da556fcaccdf96b1541931105 Mon Sep 17 00:00:00 2001
From: Charles Howard <96023061+charlesrhoward@users.noreply.github.com>
Date: Sat, 10 Oct 2026 13:59:07 -0400
Subject: [PATCH 1/2] docs: add self-hosting guide at /self-hosting
Replace the single self-hosting.md in the app repo with a full section:
overview, quickstart (Vercel and Docker), database and auth, GitHub App,
background jobs and cron routes, sandboxes and models (including the
PLATFORM_ACCESS_* allowlists a deployment without Stripe needs), Slack app
manifest, an env var reference, and operations. Add Integrations and
Self-hosting to the nav tabs and search links.
---
content/docs/meta.json | 3 +-
content/docs/self-hosting/background-jobs.mdx | 118 +++++++++++++
.../docs/self-hosting/database-and-auth.mdx | 117 +++++++++++++
.../self-hosting/environment-variables.mdx | 157 ++++++++++++++++++
content/docs/self-hosting/github-app.mdx | 132 +++++++++++++++
content/docs/self-hosting/index.mdx | 74 +++++++++
content/docs/self-hosting/meta.json | 17 ++
content/docs/self-hosting/operations.mdx | 123 ++++++++++++++
content/docs/self-hosting/quickstart.mdx | 150 +++++++++++++++++
.../self-hosting/sandboxes-and-models.mdx | 95 +++++++++++
content/docs/self-hosting/slack-app.mdx | 122 ++++++++++++++
src/lib/layout.shared.tsx | 2 +
12 files changed, 1109 insertions(+), 1 deletion(-)
create mode 100644 content/docs/self-hosting/background-jobs.mdx
create mode 100644 content/docs/self-hosting/database-and-auth.mdx
create mode 100644 content/docs/self-hosting/environment-variables.mdx
create mode 100644 content/docs/self-hosting/github-app.mdx
create mode 100644 content/docs/self-hosting/index.mdx
create mode 100644 content/docs/self-hosting/meta.json
create mode 100644 content/docs/self-hosting/operations.mdx
create mode 100644 content/docs/self-hosting/quickstart.mdx
create mode 100644 content/docs/self-hosting/sandboxes-and-models.mdx
create mode 100644 content/docs/self-hosting/slack-app.mdx
diff --git a/content/docs/meta.json b/content/docs/meta.json
index 3eb1296..aa6ab60 100644
--- a/content/docs/meta.json
+++ b/content/docs/meta.json
@@ -16,6 +16,7 @@
"configure-and-extend",
"integrations",
"guides",
- "reference"
+ "reference",
+ "self-hosting"
]
}
diff --git a/content/docs/self-hosting/background-jobs.mdx b/content/docs/self-hosting/background-jobs.mdx
new file mode 100644
index 0000000..ad06c2a
--- /dev/null
+++ b/content/docs/self-hosting/background-jobs.mdx
@@ -0,0 +1,118 @@
+---
+title: Background Jobs
+description: Connect a Trigger.dev project for automations and long agent runs, deploy the Mogplex tasks, and schedule the cron routes.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Mogplex runs long and scheduled work outside the web request cycle. Two pieces
+do this work:
+
+- **Trigger.dev tasks** (`trigger/`): automations, Slack runs, agent runs,
+ model syncs, billing reconciliation, and scheduled cleanup.
+- **Cron routes** (`/api/cron/*`): small HTTP endpoints that repair and reap
+ stuck jobs and sandboxes.
+
+## Trigger.dev
+
+Use a project on [Trigger.dev Cloud](https://trigger.dev), or
+[self-host Trigger.dev](https://trigger.dev/docs/self-hosting/overview). The
+self-hosted stack includes a webapp, Postgres, Redis, ClickHouse, object
+storage, a container registry, and worker nodes.
+
+### 1. Configure the app
+
+```bash
+TRIGGER_PROJECT_REF=proj_xxxxxxxxxxxxxxxxxxxx
+TRIGGER_SECRET_KEY=tr_prod_...
+```
+
+
+ If `TRIGGER_PROJECT_REF` is unset, `trigger.config.ts` falls back to the
+ hosted Mogplex project ref. Your deploy then targets a project you do not
+ own and fails.
+
+
+For a self-hosted Trigger.dev instance, also set `TRIGGER_API_URL` to your
+instance URL, both in the app's environment and when you deploy.
+
+### 2. Deploy the tasks
+
+```bash
+pnpm trigger:deploy
+```
+
+The wrapper loads `.env` and `.env.local`, plus any comma-separated files you
+list in `TRIGGER_CLI_ENV_FILES`. Then it runs the Trigger.dev CLI version that
+matches the installed SDK. Authenticate the CLI first with
+`pnpm dlx trigger.dev login`, or set `TRIGGER_ACCESS_TOKEN` in CI.
+
+Deploy the tasks every time you deploy the app, from the same commit. Tasks and
+the app share code in `lib/`, and mismatched versions cause hard-to-trace
+failures.
+
+For local development, `pnpm trigger:dev` runs the tasks against your
+development environment.
+
+### 3. Give the tasks their environment
+
+Tasks import the same server code as the app. They need the same server
+environment: database URLs, AI keys, `CRON_SECRET`, Sentry DSNs, and the GitHub
+and Slack credentials.
+
+- **On Vercel:** when a Vercel token and project ID are available at deploy
+ time (`VERCEL_ACCESS_TOKEN` or `PLATFORM_VERCEL_TOKEN`, plus
+ `VERCEL_PROJECT_ID` or `PLATFORM_VERCEL_PROJECT_ID`, and optionally
+ `VERCEL_TEAM_ID`), the deploy syncs the Vercel project's env vars into
+ Trigger.dev.
+- **Otherwise:** copy the server variables into the Trigger.dev project's
+ environment variables by hand. Update them there whenever you change them in
+ the app.
+
+### Task runtime
+
+`trigger.config.ts` sets Node 22, a maximum run duration of 30 minutes, and one
+attempt per task. Scheduled tasks register themselves on deploy:
+
+| Task | Schedule (UTC) |
+| --- | --- |
+| `sync-models` | `0 6,18 * * *` |
+| `sandbox-reaper` | every 5 minutes |
+| `zombie-row-reaper` | every 5 minutes |
+| `reconcile-ai-call-costs` | every 10 minutes |
+| `vercel-link-reconciliation` | every 15 minutes |
+| `reconcile-sandbox-billing` | every minute |
+| `ai-spend-divergence-check` | `0 5 * * *` |
+| `sandbox-baseline-snapshot-reaper` | `0 5 * * *` |
+| `grant-annual-included-usage` | `30 6 * * *` |
+| `slack-tool-execution-retention` | `17 * * * *` |
+
+## Cron routes
+
+Each cron route accepts `GET` with `Authorization: Bearer `. If
+`CRON_SECRET` is unset, the route returns `503 CRON_SECRET_NOT_CONFIGURED`. A
+wrong token returns `401`.
+
+| Route | Schedule |
+| --- | --- |
+| `/api/cron/sync-models` | `0 6 * * *` |
+| `/api/cron/sandbox-reaper` | `*/5 * * * *` |
+| `/api/cron/repair-jobs` | `*/5 * * * *` |
+| `/api/cron/reconcile-job-runs` | `*/5 * * * *` |
+| `/api/cron/zombie-row-reaper` | `*/5 * * * *` |
+
+**On Vercel**, `vercel.json` schedules these routes and sends the secret for
+you.
+
+**On Docker or another host**, schedule them yourself. Example crontab:
+
+```bash
+*/5 * * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" https:///api/cron/sandbox-reaper
+*/5 * * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" https:///api/cron/repair-jobs
+*/5 * * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" https:///api/cron/reconcile-job-runs
+*/5 * * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" https:///api/cron/zombie-row-reaper
+0 6 * * * curl -fsS -H "Authorization: Bearer $CRON_SECRET" https:///api/cron/sync-models
+```
+
+Without these routes, stuck jobs are not repaired and idle sandboxes keep
+running and billing.
diff --git a/content/docs/self-hosting/database-and-auth.mdx b/content/docs/self-hosting/database-and-auth.mdx
new file mode 100644
index 0000000..047455b
--- /dev/null
+++ b/content/docs/self-hosting/database-and-auth.mdx
@@ -0,0 +1,117 @@
+---
+title: Database and Auth
+description: Provision Postgres, apply Mogplex migrations, set up a least-privilege runtime role, and configure Better Auth sign-in providers and email.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Postgres holds all application state. Better Auth handles sign-in and sessions
+and stores its data in the same database.
+
+## Postgres requirements
+
+- Postgres 17.
+- The `vector` and `pg_trgm` extensions must be **available**. The migration
+ script creates them.
+- An owner role that can create schemas, extensions, and roles.
+
+Production runs on [Neon](https://neon.tech). Any Postgres that meets these
+requirements works.
+
+## Connection URLs
+
+| Variable | Used by | Notes |
+| --- | --- | --- |
+| `DATABASE_URL` | Migrations, and the app as a fallback | Owner connection. Use the pooled URL. |
+| `DATABASE_URL_UNPOOLED` | The app as a fallback | Direct, unpooled URL. `pg LISTEN` needs it. |
+| `MOGPLEX_RUNTIME_DATABASE_URL` | The app (preferred) | Pooled URL for the least-privilege `service_role`. |
+| `MOGPLEX_RUNTIME_DATABASE_URL_UNPOOLED` | The app (preferred) | Direct URL for `service_role`. |
+
+The app uses the first one it finds: `MOGPLEX_RUNTIME_DATABASE_URL`, then
+`DATABASE_URL`. Migrations always use `DATABASE_URL`.
+
+### Use a least-privilege runtime role
+
+Running the app as the database owner works, but production should not. The
+migrations harden a `service_role` that can read and write data but cannot
+create databases, roles, or schema objects. The migrations leave the role
+without `LOGIN`, so enable it yourself through an owner connection:
+
+```sql
+alter role service_role with login password '';
+```
+
+Then point `MOGPLEX_RUNTIME_DATABASE_URL` and
+`MOGPLEX_RUNTIME_DATABASE_URL_UNPOOLED` at `service_role`. Never put this
+password in a migration or a checked-in file.
+
+## Apply migrations
+
+```bash
+# Local: load .env.local
+pnpm exec tsx --env-file=.env.local scripts/apply-neon-migrations.ts
+
+# CI or production: DATABASE_URL already exported
+pnpm exec tsx scripts/apply-neon-migrations.ts
+
+# Preview without changing anything
+pnpm exec tsx --env-file=.env.local scripts/apply-neon-migrations.ts --dry-run
+```
+
+The script does the following:
+
+1. Creates a ledger table, `neon_migrations.schema_migrations`.
+2. On an empty database (no tables in `public`), applies `neon/baseline.sql` and
+ records every migration the baseline covers as applied.
+3. Applies pending `neon/migrations/*.sql` files in filename order, each in its
+ own transaction, and records each one.
+4. Exits with code 1 on the first failure.
+
+The app never changes the schema at startup. Run this script before first boot
+and before you deploy each upgrade.
+
+
+ A statement that cannot run inside a transaction, such as
+ `CREATE INDEX CONCURRENTLY`, must run separately.
+
+
+## Better Auth
+
+| Variable | Required | Value |
+| --- | --- | --- |
+| `BETTER_AUTH_SECRET` | Yes | `openssl rand -base64 32` |
+| `BETTER_AUTH_URL` | No | Defaults to `NEXT_PUBLIC_APP_URL`. |
+
+Better Auth is mounted at `/api/auth/*`. It trusts only the configured app URL
+as an origin.
+
+## Sign-in providers
+
+Configure at least one provider. A provider turns on only when both its client
+ID and secret are set.
+
+| Provider | Variables | Callback URL to register |
+| --- | --- | --- |
+| GitHub | `AUTH_GITHUB_CLIENT_ID`, `AUTH_GITHUB_CLIENT_SECRET` | `https:///api/auth/callback/github` |
+| Google | `AUTH_GOOGLE_CLIENT_ID`, `AUTH_GOOGLE_CLIENT_SECRET` | `https:///api/auth/callback/google` |
+| Microsoft | `AUTH_MICROSOFT_CLIENT_ID`, `AUTH_MICROSOFT_CLIENT_SECRET`, `AUTH_MICROSOFT_TENANT_ID` (default `common`) | `https:///api/auth/callback/microsoft` |
+| Email and password | Resend (below) | None |
+
+GitHub sign-in is identity only. Repository access comes from a separate GitHub
+OAuth app and your [GitHub App](/self-hosting/github-app).
+
+## Email
+
+Email and password sign-up requires address verification. Verification and
+password-reset emails go through [Resend](https://resend.com). If sending fails,
+sign-up fails. It does not skip the check.
+
+| Variable | Purpose |
+| --- | --- |
+| `RESEND_API_KEY` | Sends all transactional email. |
+| `WAITLIST_FROM_EMAIL` | Default sender. It must be on a domain you verified in Resend. |
+| `AUTH_FROM_EMAIL` | Sender for auth email. Falls back to `WAITLIST_FROM_EMAIL`. |
+| `BILLING_FROM_EMAIL` | Sender for billing email. Falls back to `WAITLIST_FROM_EMAIL`. |
+| `EMAIL_UNSUBSCRIBE_SECRET` | Signs unsubscribe links. Required in production. |
+
+If you skip Resend, use social sign-in only.
diff --git a/content/docs/self-hosting/environment-variables.mdx b/content/docs/self-hosting/environment-variables.mdx
new file mode 100644
index 0000000..51da6b5
--- /dev/null
+++ b/content/docs/self-hosting/environment-variables.mdx
@@ -0,0 +1,157 @@
+---
+title: Environment Variables
+description: Every environment variable a self-hosted Mogplex reads, grouped by feature, with required, build-time, and default values marked.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+`.env.example` in the repository is the starting template. Copy it to
+`.env.local` for local development, or to `.env` for Docker.
+
+
+ Next.js compiles every `NEXT_PUBLIC_*` value into the client bundle when it
+ builds. Changing one at runtime has no effect. Rebuild after each change. With
+ Docker, pass them as `--build-arg`.
+
+
+Trigger.dev tasks need the same **server** variables as the app. See
+[Background jobs](/self-hosting/background-jobs#3-give-the-tasks-their-environment).
+
+## Required
+
+| Variable | Notes |
+| --- | --- |
+| `MOGPLEX_DATA_BACKEND` | `neon`. |
+| `NEXT_PUBLIC_MOGPLEX_DATA_BACKEND` | `neon`. Must match `MOGPLEX_DATA_BACKEND`. Build-time. |
+| `NEXT_PUBLIC_APP_URL` | Public URL of the deployment, such as `https://mogplex.example.com`. Build-time. |
+| `DATABASE_URL` | Owner connection. Migrations use it, and the app falls back to it. |
+| `DATABASE_URL_UNPOOLED` | Direct connection, for `pg LISTEN`. |
+| `BETTER_AUTH_SECRET` | `openssl rand -base64 32`. |
+| `CRON_SECRET` | Bearer token for `/api/cron/*` and machine-only routes. |
+| `INTERNAL_API_SECRET` | Server-to-server sandbox actions. |
+| `CONNECTIONS_ENCRYPTION_KEY` | 32-byte hex key (`openssl rand -hex 32`) that encrypts saved connection credentials. Do not rotate without a plan: see [Operations](/self-hosting/operations#secrets). |
+| `EMAIL_UNSUBSCRIBE_SECRET` | Signs unsubscribe links. The app throws in production without it. |
+| One sign-in provider | `AUTH_GITHUB_*`, `AUTH_GOOGLE_*`, `AUTH_MICROSOFT_*`, or Resend for email and password. |
+
+## Database
+
+| Variable | Notes |
+| --- | --- |
+| `MOGPLEX_RUNTIME_DATABASE_URL` | Preferred app connection, as the least-privilege `service_role`. |
+| `MOGPLEX_RUNTIME_DATABASE_URL_UNPOOLED` | Direct URL for `service_role`. |
+
+See [Database and auth](/self-hosting/database-and-auth#use-a-least-privilege-runtime-role).
+
+## Auth and email
+
+| Variable | Notes |
+| --- | --- |
+| `BETTER_AUTH_URL` | Defaults to `NEXT_PUBLIC_APP_URL`. |
+| `BETTER_AUTH_API_KEY` | Optional. Connects the better-auth.com dashboard. |
+| `AUTH_GITHUB_CLIENT_ID`, `AUTH_GITHUB_CLIENT_SECRET` | GitHub sign-in. Callback: `/api/auth/callback/github`. |
+| `AUTH_GOOGLE_CLIENT_ID`, `AUTH_GOOGLE_CLIENT_SECRET` | Google sign-in. Callback: `/api/auth/callback/google`. |
+| `AUTH_MICROSOFT_CLIENT_ID`, `AUTH_MICROSOFT_CLIENT_SECRET` | Microsoft sign-in. Callback: `/api/auth/callback/microsoft`. |
+| `AUTH_MICROSOFT_TENANT_ID` | Default `common` (any Microsoft account). |
+| `RESEND_API_KEY` | Required for email and password sign-up (verification email). |
+| `WAITLIST_FROM_EMAIL` | Default sender, on a domain verified in Resend. |
+| `AUTH_FROM_EMAIL`, `BILLING_FROM_EMAIL` | Optional senders. Fall back to `WAITLIST_FROM_EMAIL`. |
+
+## GitHub
+
+| Variable | Notes |
+| --- | --- |
+| `GITHUB_APP_ID` | GitHub App ID. |
+| `GITHUB_APP_NAME` | GitHub App slug, as in `github.com/apps/`. |
+| `GITHUB_APP_PRIVATE_KEY` | PEM. Write newlines as `\n` in single-line env files. |
+| `GITHUB_WEBHOOK_SECRET` | Must match the App's webhook secret. |
+| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuth app for repository listing and reauthorization. Not in `.env.example`. |
+
+See [GitHub App](/self-hosting/github-app).
+
+## Background jobs
+
+| Variable | Notes |
+| --- | --- |
+| `TRIGGER_PROJECT_REF` | Your Trigger.dev project ref. Always set it. |
+| `TRIGGER_SECRET_KEY` | Secret key for the Trigger.dev environment. |
+| `TRIGGER_API_URL` | Only for a self-hosted Trigger.dev instance. |
+| `TRIGGER_CLI_ENV_FILES` | Optional. Extra comma-separated env files for `pnpm trigger:deploy`. |
+
+## Sandboxes
+
+| Variable | Notes |
+| --- | --- |
+| `PLATFORM_VERCEL_TOKEN` | Vercel token that creates sandboxes. |
+| `PLATFORM_VERCEL_TEAM_ID` | Vercel team that owns the sandboxes. |
+| `VERCEL_PROJECT_ID` or `PLATFORM_VERCEL_PROJECT_ID` | Vercel project for the sandboxes. |
+| `PLATFORM_SANDBOX_COST_CENTS_PER_SECOND` | Optional. Cost-reporting rate. Default `0.0028`. |
+
+## Models and agent features
+
+| Variable | Notes |
+| --- | --- |
+| `AI_GATEWAY_API_KEY` | Platform model access through Vercel AI Gateway. |
+| `OPENROUTER_API_KEY` | Optional. Model catalog sync. |
+| `OPENAI_API_KEY` | Optional. Memory embeddings. Without it, memory search uses plain text matching. |
+| `EXA_API_KEY` | Optional. Agent web search and page extraction. Server-side only. |
+| `EXA_RESEARCH_SECRET` | Optional. Lets Trigger.dev workers use web search through the app. |
+| `AUTOMATION_GATEWAY_CACHING` | Optional. `off` turns off prompt caching for automation jobs. |
+| `AUTOMATION_GATEWAY_FALLBACK_MODELS` | Optional. Comma-separated fallback models for automation jobs. |
+| `DECISION_MODES`, `DECISIONS_DISABLED` | Optional. Overrides for the decision layer. |
+| `MOGPLEX_HARNESS_ACP` | Optional. `off` runs Codex through its CLI instead of the Agent Client Protocol. |
+
+## User access
+
+| Variable | Notes |
+| --- | --- |
+| `PLATFORM_ACCESS_EMAILS` | Comma-separated emails with platform AI and sandbox access. |
+| `PLATFORM_ACCESS_EMAIL_DOMAINS` | Comma-separated domains, such as `example.com`. |
+| `PLATFORM_ACCESS_USER_IDS` | Comma-separated Mogplex user IDs. |
+
+See [Give users access](/self-hosting/sandboxes-and-models#give-users-access).
+
+## Slack
+
+| Variable | Notes |
+| --- | --- |
+| `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` | Slack app OAuth credentials. |
+| `SLACK_SIGNING_SECRET` | Verifies requests to `/api/webhooks/slack`. |
+| `SLACK_REDIRECT_URI` | Optional. Default `${NEXT_PUBLIC_APP_URL}/api/integrations/slack/callback`. |
+
+## Public API and MCP
+
+| Variable | Notes |
+| --- | --- |
+| `MOGPLEX_API_URL` | Optional. Overrides the host for the app's calls to its own API. |
+| `MOGPLEX_MCP_RESOURCE_URL` | Optional. OAuth protected-resource URL. Default `${NEXT_PUBLIC_APP_URL}/api/v1/mogplex/mcp`. |
+| `MOGPLEX_MCP_ALLOWED_ORIGINS` | Optional. Comma-separated browser origins that may call the MCP endpoint. Server-side MCP clients do not need it. |
+
+## Observability
+
+| Variable | Notes |
+| --- | --- |
+| `NEXT_PUBLIC_SENTRY_DSN` | Browser DSN. Build-time. |
+| `SENTRY_DSN` | Server DSN. Defaults to `NEXT_PUBLIC_SENTRY_DSN`. |
+| `SENTRY_ORG`, `SENTRY_PROJECT`, `SENTRY_AUTH_TOKEN` | Source map upload during builds. |
+| `SENTRY_ENVIRONMENT`, `SENTRY_TRACES_SAMPLE_RATE` | Optional overrides. |
+| `NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE`, `NEXT_PUBLIC_SENTRY_REPLAYS_SESSION_SAMPLE_RATE`, `NEXT_PUBLIC_SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE` | Optional browser sampling. Build-time. |
+
+## Billing (optional)
+
+Leave these unset to run without billing. Then grant access with the
+[allowlists](#user-access).
+
+| Variable | Notes |
+| --- | --- |
+| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` | Your Stripe account. Webhook: `/api/webhooks/stripe`. |
+| `CAPACITY_BILLING_OPERATIONS_ENABLED` | Default `false`. Turns on capacity billing operations. |
+| `CAPACITY_BILLING_LIVE_WRITES_ENABLED` | Default `false`. Required with a live Stripe key. |
+| `CAPACITY_BILLING_PILOT_ACCOUNT_IDS` | Comma-separated billing account IDs for the reserved-concurrency pilot. |
+
+## Other
+
+| Variable | Notes |
+| --- | --- |
+| `NEXT_PUBLIC_C15T_URL` | Optional. Hosted cookie-consent backend. If unset, consent is stored only in the browser. Build-time. |
+| `NEXT_PUBLIC_VERCEL_APP_CLIENT_ID`, `VERCEL_APP_CLIENT_SECRET` | Optional. **Sign in with Vercel** (identity only). Callback: `/api/auth/vercel/callback`. Build-time client ID. |
+| `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY` | Legacy Supabase deployments only. Leave them empty for Neon. |
diff --git a/content/docs/self-hosting/github-app.mdx b/content/docs/self-hosting/github-app.mdx
new file mode 100644
index 0000000..a5e3728
--- /dev/null
+++ b/content/docs/self-hosting/github-app.mdx
@@ -0,0 +1,132 @@
+---
+title: GitHub App
+description: Create and configure the GitHub App and OAuth app that give a self-hosted Mogplex repository access, webhooks, checks, and PR reviews.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+A self-hosted deployment needs its **own** GitHub App. The hosted Mogplex App
+sends its webhooks to mogplex.com, not to your deployment.
+
+GitHub has two separate jobs in Mogplex. Configure both:
+
+| Piece | What it unlocks | Variables |
+| --- | --- | --- |
+| GitHub App | Installation-backed repo access, webhooks, check runs, PR reviews, triggers, and automations | `GITHUB_APP_ID`, `GITHUB_APP_NAME`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_WEBHOOK_SECRET` |
+| GitHub OAuth app | Repository listing and import, and reauthorization when a token needs new scopes | `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` |
+
+GitHub *sign-in* (`AUTH_GITHUB_*`) is a third, identity-only setting. See
+[Database and auth](/self-hosting/database-and-auth#sign-in-providers).
+
+## 1. Create the GitHub App
+
+Open **GitHub → Settings → Developer settings → GitHub Apps → New GitHub App**.
+To create the App under an organization, use the organization's settings.
+The repository has no App manifest, so enter these values by hand.
+
+| Field | Value |
+| --- | --- |
+| Homepage URL | `https://` |
+| Setup URL | `https:///api/auth/github/callback` (also select **Redirect on update**) |
+| Webhook | Active |
+| Webhook URL | `https:///api/webhooks/github` |
+| Webhook secret | A random value. Store the same value as `GITHUB_WEBHOOK_SECRET`. |
+| Where can this App be installed? | **Any account**, if users outside your organization will install it |
+
+### Repository permissions
+
+| Permission | Access | Used for |
+| --- | --- | --- |
+| Contents | Read and write | Clone, push branches, read files |
+| Pull requests | Read and write | Open, update, review, and merge PRs |
+| Issues | Read and write | Read and update issues, post comments |
+| Checks | Read and write | The Mogplex PR review check run |
+| Commit statuses | Read and write | Automation `set_status` actions |
+| Actions | Read-only | Read CI workflow runs and job logs |
+| Metadata | Read-only | Required by GitHub |
+| Dependabot alerts | Read-only | [Dependabot remediation](/integrations/dependabot) (optional) |
+
+### Organization permissions
+
+| Permission | Access | Used for |
+| --- | --- | --- |
+| Members | Read-only | Lists org members when you create a team |
+
+### Subscribe to events
+
+- Pull request
+- Push
+- Issues
+- Issue comment
+- Pull request review comment
+- Commit comment
+- Check run
+- Workflow run
+- Repository
+- Dependabot alert (optional, for Dependabot remediation)
+
+GitHub always sends `installation` and `installation_repositories` events to an
+App. Mogplex uses those events to keep repository coverage in sync.
+
+## 2. Generate a private key
+
+On the App page, select **Generate a private key**. Store the PEM as
+`GITHUB_APP_PRIVATE_KEY`. In a single-line env file, replace each newline with
+`\n`.
+
+```bash
+GITHUB_APP_ID=123456
+GITHUB_APP_NAME=my-mogplex # the App's URL slug: github.com/apps/
+GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----\n"
+GITHUB_WEBHOOK_SECRET=...
+```
+
+Mogplex treats the App as configured only when `GITHUB_APP_ID`,
+`GITHUB_APP_PRIVATE_KEY`, and `GITHUB_APP_NAME` are all set.
+`GITHUB_APP_NAME` builds the install link
+`https://github.com/apps//installations/new`.
+
+## 3. Create the GitHub OAuth app
+
+Open **Developer settings → OAuth Apps → New OAuth App**.
+
+| Field | Value |
+| --- | --- |
+| Homepage URL | `https://` |
+| Authorization callback URL | `https:///api/auth/github/callback` |
+
+Mogplex requests the `repo`, `read:org`, `read:user`, and `user:email` scopes.
+Store the credentials:
+
+```bash
+GITHUB_CLIENT_ID=...
+GITHUB_CLIENT_SECRET=...
+```
+
+
+ GitHub accepts any redirect path under an OAuth app's callback URL. If you set
+ the callback URL to `https:///api/auth`, one OAuth app serves both
+ `/api/auth/github/callback` and GitHub sign-in at
+ `/api/auth/callback/github`. Then use the same credentials for
+ `GITHUB_CLIENT_*` and `AUTH_GITHUB_*`.
+
+
+## 4. Install and verify
+
+1. Redeploy so the app reads the new variables.
+2. Sign in, open **Settings → Account**, and connect GitHub. This installs the
+ App on the accounts or organizations that own your repositories.
+3. Open [Installations](/web/installations) and confirm coverage. Then import a
+ repository in [Projects](/web/spaces).
+4. In the App's **Advanced → Recent deliveries**, confirm that deliveries return
+ `2xx`. A `401` means `GITHUB_WEBHOOK_SECRET` does not match the App's
+ webhook secret.
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| **Connect GitHub** opens an OAuth screen instead of the App install | One of `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, or `GITHUB_APP_NAME` is missing. |
+| Repos are listed but triggers never fire | The App is not installed on that owner, or the webhook URL points somewhere else. |
+| `invalid_state` after the GitHub redirect | The callback reached a different domain than the one that started the flow. Make `NEXT_PUBLIC_APP_URL` match the public URL. |
+| New permissions have no effect | Each installation must accept the new permissions on GitHub. |
diff --git a/content/docs/self-hosting/index.mdx b/content/docs/self-hosting/index.mdx
new file mode 100644
index 0000000..935798b
--- /dev/null
+++ b/content/docs/self-hosting/index.mdx
@@ -0,0 +1,74 @@
+---
+title: Self-Hosting
+description: Run Mogplex on your own infrastructure. Learn which services it depends on, what each one unlocks, and which deployment shape to choose.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Mogplex is open source under Apache-2.0. The code in
+[github.com/Mogplex/mogplex](https://github.com/Mogplex/mogplex) is the same code
+that runs [mogplex.com](https://mogplex.com). Self-hosting has no license fee, no
+seat limit, and no gated features.
+
+You run the Next.js app. Your own accounts supply the database, background jobs,
+sandboxes, models, and GitHub App. You control the data, the credentials, and
+the bill.
+
+
+ Self-hosting has no SLA. Ask questions in
+ [GitHub Discussions](https://github.com/Mogplex/mogplex/discussions) and file
+ bugs as [issues](https://github.com/Mogplex/mogplex/issues). The project treats
+ friction in the self-hosting path as a bug.
+
+
+## How a deployment fits together
+
+| Part | Runs on | Required? | Without it |
+| --- | --- | --- | --- |
+| Web app (Next.js) | Vercel, or any container host | Yes | Nothing runs. |
+| Postgres 17 + Better Auth | [Neon](https://neon.tech) or any Postgres 17 with `vector` and `pg_trgm` | Yes | The app cannot boot or sign anyone in. |
+| Email ([Resend](https://resend.com)) | Resend | Yes, for email sign-in | Email and password sign-up cannot verify addresses. Social sign-in still works. |
+| GitHub App | Your own GitHub App | For repo work | No repo access, webhooks, PR reviews, or GitHub triggers. |
+| Background jobs | [Trigger.dev](https://trigger.dev), cloud or self-hosted | For agent work | Automations, Slack runs, syncs, and long agent runs do not start. |
+| Sandboxes | [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox) | For code execution | Agents cannot clone, edit, or run code. |
+| Models | [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) key, or per-user provider keys | For agent work | Chat and agents have no model to call. |
+| Slack app | Your own Slack app | Optional | No Slack integration. |
+| Sentry | Your own Sentry project | Optional | No error tracking. |
+| Stripe | Your own Stripe account | Optional | No billing. See [Give users access](/self-hosting/sandboxes-and-models#give-users-access). |
+
+The app boots with only Postgres configured. Each additional service unlocks one
+feature area, so you can bring Mogplex up in stages.
+
+
+ Hosted AI and sandboxes are gated per user. A user needs a positive billing
+ balance, a profile flag, or an entry in the `PLATFORM_ACCESS_*` allowlists.
+ Without Stripe, nobody has a balance, so add your users to the allowlist. If
+ you skip this step, every run fails with "requires a positive billing
+ balance". See [Give users access](/self-hosting/sandboxes-and-models#give-users-access).
+
+
+## Choose a deployment shape
+
+**Vercel (recommended).** Fork the repo, link it to a project in your own Vercel
+team, set the environment variables, and deploy. Production runs this way every
+day. Vercel also runs the cron routes and syncs env vars to Trigger.dev for you.
+
+**Docker.** Build the image from the repo and run it on any container host. The
+image contains only the web app. You provision every backing service yourself,
+schedule the cron routes yourself, and copy env vars into Trigger.dev by hand.
+Sandboxes still need a Vercel account.
+
+## Time to plan
+
+- **App shell** (Postgres, auth, one sign-in provider): about 15 minutes.
+- **Full product** (GitHub App, Trigger.dev, sandboxes, models, Slack): an
+ afternoon. Each service has its own sign-up, billing, and credential rotation.
+
+## Read next
+
+
+
+
+
+
+
diff --git a/content/docs/self-hosting/meta.json b/content/docs/self-hosting/meta.json
new file mode 100644
index 0000000..e275724
--- /dev/null
+++ b/content/docs/self-hosting/meta.json
@@ -0,0 +1,17 @@
+{
+ "title": "Self-Hosting",
+ "root": true,
+ "pages": [
+ "index",
+ "quickstart",
+ "---Services---",
+ "database-and-auth",
+ "github-app",
+ "background-jobs",
+ "sandboxes-and-models",
+ "slack-app",
+ "---Reference---",
+ "environment-variables",
+ "operations"
+ ]
+}
diff --git a/content/docs/self-hosting/operations.mdx b/content/docs/self-hosting/operations.mdx
new file mode 100644
index 0000000..8a96f72
--- /dev/null
+++ b/content/docs/self-hosting/operations.mdx
@@ -0,0 +1,123 @@
+---
+title: Operations
+description: Upgrade a self-hosted Mogplex safely, manage its secrets, expose the MCP endpoint, and understand the known constraints.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+## Upgrades
+
+Release notes on the [releases page](https://github.com/Mogplex/mogplex/releases)
+list breaking changes to env vars and migrations. For each upgrade:
+
+1. Pull `main` or a tagged release into your fork.
+2. Add any new variables to the app **and** to Trigger.dev.
+3. Apply migrations:
+ `pnpm exec tsx scripts/apply-neon-migrations.ts`.
+4. Deploy the app.
+5. Deploy the Trigger.dev tasks from the same commit: `pnpm trigger:deploy`.
+
+Migrations stay compatible with the previous app release, so apply them
+**before** you deploy the new code. Production uses the same order.
+
+
+ `.github/workflows/deploy-production.yml` is a working example. It applies
+ migrations, deploys with the Vercel CLI, and then calls
+ `/api/cron/production-smoke` to detect schema drift. Point its secrets at your
+ own accounts to reuse it.
+
+
+## Secrets
+
+| Secret | Rotation |
+| --- | --- |
+| `BETTER_AUTH_SECRET` | Rotating it signs out every user. |
+| `CRON_SECRET`, `INTERNAL_API_SECRET` | Rotate freely. On Docker, update your cron jobs at the same time. |
+| `EMAIL_UNSUBSCRIBE_SECRET` | Rotating it invalidates unsubscribe links already sent. |
+| `CONNECTIONS_ENCRYPTION_KEY` | Encrypts saved connection tokens and API keys. **Re-encrypt before you rotate** (below). |
+| `GITHUB_WEBHOOK_SECRET`, `SLACK_SIGNING_SECRET` | Change the value in GitHub or Slack and in your env at the same time. |
+
+Store secrets in your platform's secret store. Never commit them.
+
+### Rotate `CONNECTIONS_ENCRYPTION_KEY`
+
+If you change the key without re-encrypting, every saved connection becomes
+unreadable. Use the rotation script. It runs a dry run by default and backs up
+the original ciphertexts.
+
+```bash
+OLD_CONNECTIONS_ENCRYPTION_KEY= \
+NEW_CONNECTIONS_ENCRYPTION_KEY=$(openssl rand -hex 32) \
+DATABASE_URL= \
+ pnpm exec tsx scripts/rotate-connections-encryption-key.ts # dry run
+# Review the counts, then run again with --execute
+```
+
+Take a database snapshot first, and rotate during low traffic. Switch the env
+var and redeploy right after the script finishes. Then run the script once more
+to re-encrypt rows that were written in between.
+
+## Hosted API and MCP endpoint
+
+Your deployment serves the same [hosted API](/reference/api) and
+[MCP endpoint](/mcp) as mogplex.com, at
+`https:///api/v1/mogplex/mcp`. Users authenticate with a Mogplex key
+from **Settings → Mogplex Keys**, or through OAuth.
+
+Better Auth is the OAuth authorization server. It supports dynamic client
+registration, PKCE, and refresh tokens. No extra setup is needed when the
+public URL is `NEXT_PUBLIC_APP_URL`. Verify it:
+
+```bash
+curl https:///.well-known/oauth-protected-resource/api/v1/mogplex/mcp
+curl https:///.well-known/oauth-authorization-server
+```
+
+The first response must name your domain as both the resource and the
+authorization server.
+
+- Set `MOGPLEX_MCP_RESOURCE_URL` only when the MCP endpoint is served from a
+ different URL than `NEXT_PUBLIC_APP_URL`.
+- Set `MOGPLEX_MCP_ALLOWED_ORIGINS` for browser-based MCP clients.
+
+When you [install MCP clients](/mcp/install), replace `mogplex.com` with your
+domain.
+
+## Mogplex CLI
+
+To point the [Mogplex CLI](/cli) at your deployment instead of mogplex.com, set
+`MOGPLEX_URL`:
+
+```bash
+export MOGPLEX_URL="https://mogplex.example.com"
+```
+
+See [CLI automation](/cli/automation#base-url).
+
+## Known constraints
+
+- **Sandboxes require Vercel Sandbox.** No other sandbox backend exists yet. A
+ pluggable backend would be a welcome contribution. Open a
+ [discussion](https://github.com/Mogplex/mogplex/discussions) before you start
+ so the interface is agreed first.
+- **The Docker image has no health check.** Probe `/` or `/login` from your
+ orchestrator.
+- **Cron routes are not self-scheduling.** Outside Vercel, you must
+ [schedule them](/self-hosting/background-jobs#cron-routes).
+- **Bring-your-own Vercel compute for end users is not available.** Sandboxes
+ always bill to the deployment's `PLATFORM_VERCEL_*` account.
+- **Team-shared connections are not available yet.** Connections belong to
+ personal accounts.
+
+## Troubleshooting
+
+| Symptom | Likely cause |
+| --- | --- |
+| Runs fail with "requires a positive billing balance" | The user is not in the [access allowlist](/self-hosting/sandboxes-and-models#give-users-access). |
+| "Sandbox service not configured" | `PLATFORM_VERCEL_TOKEN` or the project ID is missing. |
+| Automations and Slack runs never start | Trigger.dev is not configured, the tasks are not deployed, or the tasks are missing env vars. |
+| `pnpm trigger:deploy` targets the wrong project | `TRIGGER_PROJECT_REF` is unset. |
+| GitHub deliveries return `401` | `GITHUB_WEBHOOK_SECRET` does not match the App. |
+| A changed `NEXT_PUBLIC_*` value has no effect | Rebuild. These values are fixed at build time. |
+| Auth routes return errors | `DATABASE_URL` and `MOGPLEX_RUNTIME_DATABASE_URL` are both unset, or migrations have not run. |
+| Email sign-up never completes | `RESEND_API_KEY` is missing, or the sender domain is not verified. |
diff --git a/content/docs/self-hosting/quickstart.mdx b/content/docs/self-hosting/quickstart.mdx
new file mode 100644
index 0000000..18d7d06
--- /dev/null
+++ b/content/docs/self-hosting/quickstart.mdx
@@ -0,0 +1,150 @@
+---
+title: Quickstart
+description: Deploy a self-hosted Mogplex on Vercel or Docker, sign in, and add the services that unlock agent work.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
+
+This guide gets a signed-in deployment running first. Then it adds the services
+that let agents work on repositories.
+
+## Prerequisites
+
+- Node.js `22.22.x` (see `.nvmrc`) and pnpm `10` through Corepack
+ (`corepack enable`).
+- A Postgres 17 database with the `vector` and `pg_trgm` extensions available.
+ [Neon](https://neon.tech) has both. For local development, the
+ `pgvector/pgvector:pg17` Docker image works.
+- A public HTTPS domain for the deployment. OAuth callbacks and webhooks must
+ reach it.
+
+## 1. Get the code
+
+```bash
+git clone https://github.com/Mogplex/mogplex.git
+cd mogplex
+pnpm install
+cp .env.example .env.local
+```
+
+Fork the repository first if you plan to change code or deploy from Git.
+
+## 2. Configure the minimum environment
+
+Set these in `.env.local`. Generate each secret with `openssl rand -base64 32`,
+except `CONNECTIONS_ENCRYPTION_KEY`, which must be 32 bytes of hex
+(`openssl rand -hex 32`).
+
+```bash
+# Backend switches. Both must be "neon". The public one is baked in at build time.
+MOGPLEX_DATA_BACKEND=neon
+NEXT_PUBLIC_MOGPLEX_DATA_BACKEND=neon
+
+NEXT_PUBLIC_APP_URL=https://mogplex.example.com
+
+# Database. DATABASE_URL is the owner connection that migrations use.
+DATABASE_URL=postgres://owner:...@host/db?sslmode=require
+DATABASE_URL_UNPOOLED=postgres://owner:...@direct-host/db?sslmode=require
+
+# Auth
+BETTER_AUTH_SECRET=...
+AUTH_GITHUB_CLIENT_ID=... # or AUTH_GOOGLE_* / AUTH_MICROSOFT_*
+AUTH_GITHUB_CLIENT_SECRET=...
+
+# Secrets the app requires
+CRON_SECRET=...
+INTERNAL_API_SECRET=...
+CONNECTIONS_ENCRYPTION_KEY=... # 64 hex characters
+EMAIL_UNSUBSCRIBE_SECRET=... # required in production
+```
+
+[Database and auth](/self-hosting/database-and-auth) explains the database URLs,
+the least-privilege runtime role, and each sign-in provider.
+
+## 3. Apply migrations
+
+```bash
+pnpm exec tsx --env-file=.env.local scripts/apply-neon-migrations.ts
+```
+
+On an empty database, the script applies `neon/baseline.sql` first. Then it
+applies every pending file in `neon/migrations/`. Run it as the database owner,
+because it creates schemas, extensions, and roles. Add `--dry-run` to preview.
+
+## 4. Deploy
+
+
+
+
+`vercel.json` turns off automatic Git deployments, so deploy with the Vercel CLI
+or from your own CI:
+
+```bash
+vercel link # link to a project in your own Vercel team
+vercel env add ... # or paste .env.local into Project → Settings → Environment Variables
+vercel deploy --prod
+```
+
+To deploy on every push instead, remove `"git": { "deploymentEnabled": false }`
+from `vercel.json` in your fork. Vercel runs the cron routes listed in
+`vercel.json` for you.
+
+
+
+
+`NEXT_PUBLIC_*` values are compiled into the client bundle at **build** time.
+Pass them as build args, and rebuild whenever they change.
+
+```bash
+cp .env.local .env
+docker compose build # reads NEXT_PUBLIC_* build args from .env
+docker compose up -d # serves on port 3000
+```
+
+Without Compose:
+
+```bash
+docker build \
+ --build-arg NEXT_PUBLIC_APP_URL=https://mogplex.example.com \
+ --build-arg NEXT_PUBLIC_MOGPLEX_DATA_BACKEND=neon \
+ -t mogplex .
+
+docker run --env-file .env -p 3000:3000 mogplex
+```
+
+The image runs Next.js in standalone mode on Node 22 as a non-root user. It
+contains no database, job runner, or cron scheduler. Put a TLS-terminating proxy
+in front of it, and
+[schedule the cron routes](/self-hosting/background-jobs#cron-routes) yourself.
+
+
+
+
+Open the deployment and sign in. If sign-in works, the app shell is done.
+
+## 5. Add services for agent work
+
+Add these in order. Each one is independent.
+
+1. [GitHub App](/self-hosting/github-app): repository access, webhooks, PR
+ reviews, and GitHub triggers.
+2. [Background jobs](/self-hosting/background-jobs): a Trigger.dev project for
+ automations, Slack runs, and long agent runs.
+3. [Sandboxes and models](/self-hosting/sandboxes-and-models): Vercel Sandbox,
+ an AI Gateway key, and **user access**.
+4. [Slack app](/self-hosting/slack-app) (optional).
+
+
+ After step 3, add your users to `PLATFORM_ACCESS_EMAILS` or
+ `PLATFORM_ACCESS_EMAIL_DOMAINS`. Without Stripe billing, no user has hosted
+ AI or sandbox access until you grant it.
+
+
+## 6. Verify
+
+- Sign in, then open **Settings → Account** and select **Run checks**.
+- Connect GitHub, install your GitHub App, and import a repository.
+- Start a run against that repository. Confirm in
+ [Observability](/web/observability) that a sandbox starts and the job
+ completes.
diff --git a/content/docs/self-hosting/sandboxes-and-models.mdx b/content/docs/self-hosting/sandboxes-and-models.mdx
new file mode 100644
index 0000000..a7ddcc1
--- /dev/null
+++ b/content/docs/self-hosting/sandboxes-and-models.mdx
@@ -0,0 +1,95 @@
+---
+title: Sandboxes and Models
+description: Configure Vercel Sandbox compute, model access through AI Gateway or provider keys, and per-user access on a self-hosted Mogplex.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Agents need two things to work on code: a sandbox to run in, and a model to
+call. On a self-hosted deployment, your accounts provide both. You also decide
+which users may use them.
+
+## Sandboxes (Vercel Sandbox)
+
+Each agent session runs in a [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox)
+microVM. Mogplex has no local or container substitute. Without these variables,
+sandbox features return "Sandbox service not configured".
+
+| Variable | Value |
+| --- | --- |
+| `PLATFORM_VERCEL_TOKEN` | A Vercel access token that can create sandboxes in your team |
+| `PLATFORM_VERCEL_TEAM_ID` | The team that owns and pays for the sandboxes |
+| `VERCEL_PROJECT_ID` or `PLATFORM_VERCEL_PROJECT_ID` | The Vercel project the sandboxes belong to. This can be the project that hosts Mogplex. |
+
+Sandbox usage bills to that Vercel team. Optionally, set
+`PLATFORM_SANDBOX_COST_CENTS_PER_SECOND` (default `0.0028`) so that Mogplex's
+cost reporting matches your Vercel pricing.
+
+## Models
+
+Mogplex resolves model access in this order:
+
+1. **The user's own AI Gateway key** (Settings → Provider Keys). The user's
+ gateway account pays for the usage.
+2. **The platform AI Gateway key**, `AI_GATEWAY_API_KEY`, for users who have
+ [platform access](#give-users-access). Your gateway account pays for the
+ usage.
+3. **The user's direct provider keys**: Anthropic for Claude Code and Claude
+ models, OpenAI for Codex and OpenAI models, and OpenRouter for OpenRouter
+ models.
+
+| Variable | Purpose |
+| --- | --- |
+| `AI_GATEWAY_API_KEY` | Platform model access through [Vercel AI Gateway](https://vercel.com/docs/ai-gateway). |
+| `OPENROUTER_API_KEY` | Refreshes the model catalog. |
+| `OPENAI_API_KEY` | Memory embeddings. Without it, memory search falls back to plain text matching. |
+| `EXA_API_KEY`, `EXA_RESEARCH_SECRET` | Agent web search and page extraction (optional). |
+
+The model catalog syncs twice a day. To populate it on a new deployment, call
+`/api/cron/sync-models` once (see [Cron routes](/self-hosting/background-jobs#cron-routes)).
+
+## Give users access
+
+Platform AI (`AI_GATEWAY_API_KEY`) and platform sandboxes are gated per user. A
+user has access when **any** of these is true:
+
+- The user's billing account has a positive balance (requires Stripe).
+- The user's ID, email, or email domain is in an allowlist variable.
+- The user's profile row has `allow_platform_ai` or `allow_platform_sandbox` set
+ to `true`.
+
+Without Stripe, no account has a balance. Use the allowlists:
+
+```bash
+PLATFORM_ACCESS_EMAIL_DOMAINS=example.com # everyone at example.com
+PLATFORM_ACCESS_EMAILS=alice@example.org,bob@example.org
+PLATFORM_ACCESS_USER_IDS= # Mogplex user IDs
+```
+
+The allowlists grant both AI and sandbox access. To grant one without the
+other, set the profile flag directly:
+
+```sql
+update public.profiles
+set allow_platform_sandbox = true, allow_platform_ai = false
+where email = 'alice@example.org';
+```
+
+
+ Users without access still see the app. Their runs fail with "Hosted AI
+ requires a positive billing balance" or "Hosted sandbox compute requires a
+ positive billing balance". These messages usually mean the user is missing
+ from the allowlist, not that billing is broken.
+
+
+A user without platform AI access can still add their own AI Gateway,
+Anthropic, OpenAI, or OpenRouter key under **Settings → Provider Keys**. See
+[AI provider keys](/integrations/ai-provider-keys).
+
+## Agent harnesses
+
+Runs use the native Mogplex agent, Claude Code, or Codex. Claude Code and
+Codex install inside the sandbox at run time and authenticate with the model
+access above. Codex runs over the Agent Client Protocol by default. Set
+`MOGPLEX_HARNESS_ACP=off` to fall back to the one-shot Codex CLI. See
+[Claude Code and Codex](/integrations/claude-code-and-codex).
diff --git a/content/docs/self-hosting/slack-app.mdx b/content/docs/self-hosting/slack-app.mdx
new file mode 100644
index 0000000..8e9c4ba
--- /dev/null
+++ b/content/docs/self-hosting/slack-app.mdx
@@ -0,0 +1,122 @@
+---
+title: Slack App
+description: Create the Slack app for a self-hosted Mogplex, with a ready-to-paste manifest, the scopes, events, slash commands, and environment variables.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Slack is optional. A self-hosted deployment needs its own Slack app, because the
+hosted app sends its events to mogplex.com. One app can be installed in many
+workspaces. Users install it from **Connections → Slack** in your deployment.
+
+## 1. Create the app from a manifest
+
+Open [api.slack.com/apps](https://api.slack.com/apps), select **Create New App →
+From a manifest**, and paste the manifest below. Replace `mogplex.example.com`
+with your domain.
+
+```yaml
+display_information:
+ name: Mogplex
+ description: Run Mogplex agents from Slack
+features:
+ app_home:
+ messages_tab_enabled: true
+ messages_tab_read_only_enabled: false
+ bot_user:
+ display_name: mogplex
+ always_online: true
+ slash_commands:
+ - command: /mogplex
+ url: https://mogplex.example.com/api/webhooks/slack
+ description: Mogplex commands
+ usage_hint: help | status | cancel | repo | prs | issues | usage | model | harness | agent
+ should_escape: false
+ - command: /mogplex-cancel
+ url: https://mogplex.example.com/api/webhooks/slack
+ description: Cancel your active Mogplex run in this channel
+ usage_hint: "[run-id]"
+ should_escape: false
+ - command: /harness
+ url: https://mogplex.example.com/api/webhooks/slack
+ description: View or choose your repository runner
+ usage_hint: "[mogplex|codex|claude-code]"
+ should_escape: false
+oauth_config:
+ redirect_urls:
+ - https://mogplex.example.com/api/integrations/slack/callback
+ scopes:
+ bot:
+ - app_mentions:read
+ - channels:history
+ - channels:read
+ - chat:write
+ - commands
+ - files:read
+ - groups:history
+ - groups:read
+ - im:history
+ - im:read
+ - mpim:history
+ - mpim:read
+ - users:read
+ - users:read.email
+settings:
+ event_subscriptions:
+ request_url: https://mogplex.example.com/api/webhooks/slack
+ bot_events:
+ - app_mention
+ - message.channels
+ - message.groups
+ - message.im
+ - message.mpim
+ interactivity:
+ is_enabled: true
+ request_url: https://mogplex.example.com/api/webhooks/slack
+ org_deploy_enabled: false
+ socket_mode_enabled: false
+ token_rotation_enabled: false
+```
+
+One endpoint, `/api/webhooks/slack`, receives events, slash commands, and
+interactivity. Deploy the app with the Slack variables set **before** you save
+the manifest, so that Slack's URL verification succeeds.
+
+To distribute the app to workspaces other than the one that created it, turn on
+**Manage Distribution → Public Distribution**.
+
+## 2. Set the environment variables
+
+From **Basic Information → App Credentials**:
+
+```bash
+SLACK_CLIENT_ID=...
+SLACK_CLIENT_SECRET=...
+SLACK_SIGNING_SECRET=...
+# Optional. Defaults to ${NEXT_PUBLIC_APP_URL}/api/integrations/slack/callback
+SLACK_REDIRECT_URI=
+```
+
+Set the same variables in your [Trigger.dev environment](/self-hosting/background-jobs#3-give-the-tasks-their-environment).
+Slack runs execute as Trigger.dev tasks.
+
+## 3. Install and verify
+
+1. In your deployment, open **Connections**, find **Slack**, and select
+ **Install to Slack**.
+2. Link a channel to a repository, and turn on repo-agent runs.
+3. In Slack, run `/mogplex help`. It responds without a linked account.
+4. Mention `@mogplex` with a real instruction in the linked channel. Confirm
+ that a run appears in [Observability](/web/observability).
+
+For channel links, user mapping, and run controls, see
+[Slack](/integrations/slack).
+
+## Scope changes
+
+
+ Changing code cannot expand an existing Slack OAuth grant. When a release adds
+ a scope, add it to the app, then reconnect each workspace from
+ **Connections → Slack**. For example, `files:read` lets agents read images
+ attached to thread messages, and older installs must reconnect to get it.
+
diff --git a/src/lib/layout.shared.tsx b/src/lib/layout.shared.tsx
index e4aaaba..a25cfae 100644
--- a/src/lib/layout.shared.tsx
+++ b/src/lib/layout.shared.tsx
@@ -7,7 +7,9 @@ export const docsNavItems = [
{ label: 'Guides', href: '/guides' },
{ label: 'CLI', href: '/cli' },
{ label: 'Web app', href: '/web' },
+ { label: 'Integrations', href: '/integrations' },
{ label: 'Reference', href: '/reference' },
+ { label: 'Self-hosting', href: '/self-hosting' },
] as const;
export const docsSearchLinks: [string, string][] = [
From d11730c18f4cc250cda59152d9079170267085b1 Mon Sep 17 00:00:00 2001
From: Charles Howard <96023061+charlesrhoward@users.noreply.github.com>
Date: Sat, 10 Oct 2026 13:59:09 -0400
Subject: [PATCH 2/2] docs(integrations): document every integration
Add pages for Dependabot, Linear, Notion, Sentry, Supabase, Neon,
Browserbase, Sanity, Zapier, Trigger.dev, AI provider keys, Claude Code
and Codex, and signed webhooks. Regroup the index and sidebar by kind.
Correct the Vercel page: Vercel project env import and user-owned
compute are not available.
---
.../docs/integrations/ai-provider-keys.mdx | 53 ++++++++
content/docs/integrations/browserbase.mdx | 42 ++++++
.../integrations/claude-code-and-codex.mdx | 59 ++++++++
content/docs/integrations/dependabot.mdx | 63 +++++++++
content/docs/integrations/github.mdx | 7 +
content/docs/integrations/index.mdx | 105 +++++++--------
content/docs/integrations/linear.mdx | 47 +++++++
content/docs/integrations/meta.json | 19 ++-
content/docs/integrations/neon.mdx | 44 ++++++
content/docs/integrations/notion.mdx | 38 ++++++
content/docs/integrations/sanity.mdx | 37 +++++
content/docs/integrations/sentry.mdx | 39 ++++++
content/docs/integrations/supabase.mdx | 46 +++++++
content/docs/integrations/trigger-dev.mdx | 50 +++++++
content/docs/integrations/vercel.mdx | 126 ++++++++----------
content/docs/integrations/webhooks.mdx | 72 ++++++++++
content/docs/integrations/zapier.mdx | 42 ++++++
17 files changed, 763 insertions(+), 126 deletions(-)
create mode 100644 content/docs/integrations/ai-provider-keys.mdx
create mode 100644 content/docs/integrations/browserbase.mdx
create mode 100644 content/docs/integrations/claude-code-and-codex.mdx
create mode 100644 content/docs/integrations/dependabot.mdx
create mode 100644 content/docs/integrations/linear.mdx
create mode 100644 content/docs/integrations/neon.mdx
create mode 100644 content/docs/integrations/notion.mdx
create mode 100644 content/docs/integrations/sanity.mdx
create mode 100644 content/docs/integrations/sentry.mdx
create mode 100644 content/docs/integrations/supabase.mdx
create mode 100644 content/docs/integrations/trigger-dev.mdx
create mode 100644 content/docs/integrations/webhooks.mdx
create mode 100644 content/docs/integrations/zapier.mdx
diff --git a/content/docs/integrations/ai-provider-keys.mdx b/content/docs/integrations/ai-provider-keys.mdx
new file mode 100644
index 0000000..4cd1188
--- /dev/null
+++ b/content/docs/integrations/ai-provider-keys.mdx
@@ -0,0 +1,53 @@
+---
+title: AI Provider Keys
+description: Bring your own Vercel AI Gateway, Anthropic, OpenAI, or OpenRouter key so Mogplex model usage bills to your provider account.
+---
+
+By default, Mogplex bills model usage to your Mogplex plan. Add your own
+provider key to send usage to your own provider account instead, or to use
+models and harnesses that your plan does not include.
+
+## Supported providers
+
+| Provider | Used for | Key format |
+| --- | --- | --- |
+| Vercel AI Gateway | Every model and both CLI harnesses, through one key | AI Gateway API key |
+| Anthropic | Claude models and the [Claude Code](/integrations/claude-code-and-codex) harness | `sk-ant-…` |
+| OpenAI | OpenAI models and the [Codex](/integrations/claude-code-and-codex) harness | `sk-…` |
+| OpenRouter | OpenRouter models | `sk-or-…` |
+
+## Add a key
+
+1. Open **Settings → Provider Keys**.
+2. Paste the key for the provider and select **Save**.
+3. Select **Verify** to confirm that the provider accepts the key.
+
+Personal keys belong to your account. To set keys for a team, open
+**Team Settings → Provider Keys**. Team permissions control who can manage
+them. Keys are stored encrypted and are never shown again after you save them.
+
+## Which key a run uses
+
+For sandbox harness runs (Claude Code and Codex), Mogplex chooses the first
+match:
+
+1. **Your AI Gateway key.** Usage bills to your gateway account.
+2. **Mogplex platform AI**, if your plan includes it. Usage bills to your
+ Mogplex balance.
+3. **Your Anthropic key** (Claude Code) or **OpenAI key** (Codex). Usage bills
+ to that provider.
+
+If none of these is available, the harness is unavailable, and the automation
+harness picker disables it.
+
+Chat and native Mogplex agent runs use the provider of the selected model.
+Models served through OpenRouter need an OpenRouter key.
+
+## Troubleshooting
+
+| Message | Fix |
+| --- | --- |
+| "Hosted AI requires a positive billing balance" | Add funds or choose a plan in **Settings → Billing**, or add your own key. |
+| "No Anthropic API key configured" | Add an Anthropic or AI Gateway key, or choose a different harness. |
+| "No OpenRouter API key configured" | Add an OpenRouter key, or choose a model from another provider. |
+| Verification fails when you save | The key is invalid, revoked, or lacks API access on the provider's side. |
diff --git a/content/docs/integrations/browserbase.mdx b/content/docs/integrations/browserbase.mdx
new file mode 100644
index 0000000..325c3c5
--- /dev/null
+++ b/content/docs/integrations/browserbase.mdx
@@ -0,0 +1,42 @@
+---
+title: Browserbase
+description: Connect Browserbase so Mogplex agents can drive cloud browsers to test pages, scrape content, and automate web flows.
+---
+
+Connect Browserbase to give agents a real cloud browser. Agents can load pages,
+click through flows, take screenshots, and extract content.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.browserbase.com/mcp` |
+| Credential | Browserbase API key (`bb_live_…`) |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Browserbase, copy an API key from the dashboard. See
+ [Browserbase MCP setup](https://docs.browserbase.com/integrations/mcp/setup).
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Browserbase**.
+4. Paste the key, then select **Add**.
+5. Test the saved connection and confirm that it lists tools.
+
+Mogplex sends the key to Browserbase as the `browserbaseApiKey` query parameter.
+The key is stored encrypted and is not shown again.
+
+## Use it
+
+- "Open the preview URL for this PR, sign up with a test account, and report
+ any step that fails."
+- "Capture the pricing page on staging and production and list the
+ differences."
+
+Browser sessions use your Browserbase plan and bill to your Browserbase
+account.
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Test fails | The key is invalid or the Browserbase account has no remaining sessions. |
+| The agent cannot reach a preview URL | The preview is protected. Give the agent a URL it can open without signing in, or a bypass token. |
diff --git a/content/docs/integrations/claude-code-and-codex.mdx b/content/docs/integrations/claude-code-and-codex.mdx
new file mode 100644
index 0000000..69772e4
--- /dev/null
+++ b/content/docs/integrations/claude-code-and-codex.mdx
@@ -0,0 +1,59 @@
+---
+title: Claude Code and Codex
+description: Run Anthropic's Claude Code or OpenAI's Codex as the agent harness for Mogplex runs, automations, and Slack tasks.
+---
+
+A harness is the agent program that does the work inside a sandbox. Mogplex
+runs three harnesses:
+
+| Harness | ID | What runs |
+| --- | --- | --- |
+| Mogplex | `mogplex` | Mogplex's native agent. It is always available and uses any model in your catalog. |
+| Claude Code | `claude-code` | Anthropic's `claude` CLI, in the sandbox. |
+| Codex | `codex` | OpenAI's Codex, in the sandbox. It runs through the Agent Client Protocol (ACP). |
+
+Mogplex installs a pinned version of Claude Code or Codex in the sandbox for each
+run, gives it the repository checkout, and streams its events into
+[Observability](/web/observability). Claude Code runs also receive your MCP
+connections; see [where connection tools load](/configure-and-extend/connections-and-mcp#where-connection-tools-load).
+
+## Requirements
+
+Claude Code and Codex need model access. Each harness is available when you have
+one of these:
+
+- **Claude Code:** an AI Gateway key, Mogplex platform AI on your plan, or an
+ Anthropic key.
+- **Codex:** an AI Gateway key, Mogplex platform AI on your plan, or an OpenAI
+ key.
+
+Add keys in **Settings → Provider Keys**. See
+[AI provider keys](/integrations/ai-provider-keys) for the order in which keys
+are used.
+
+## Choose a harness
+
+| Where | How |
+| --- | --- |
+| [Automations](/web/automations) | Select the agent node, then choose **Harness** in the inspector. Unavailable harnesses are disabled. |
+| Slack | `/mogplex harness claude-code`, `/mogplex harness codex`, or `/mogplex harness mogplex`. The choice applies to your future repository runs in that channel. |
+| [Hosted API](/reference/api) and [MCP](/mcp) | Pass `harness` when you start a run. The API defaults to `codex`. |
+
+## Run modes
+
+Claude Code and Codex runs accept a mode that controls what the harness can do
+in the sandbox:
+
+- `SAFE`: the harness does not change the checkout.
+- `AUTO` (default): the harness edits files and runs commands.
+- `YOLO`: the harness runs without approval prompts. Claude Code still blocks
+ its deny-listed tools and commands.
+
+The Mogplex harness takes no mode. See [Start a run](/reference/api#start-a-run)
+for the details.
+
+## Use Mogplex from Claude Code or Codex on your machine
+
+This page covers Claude Code and Codex running **inside** Mogplex. To let a
+local Claude Code, Codex, Cursor, or OpenCode session call Mogplex, install the
+[Mogplex MCP endpoint](/mcp/install).
diff --git a/content/docs/integrations/dependabot.mdx b/content/docs/integrations/dependabot.mdx
new file mode 100644
index 0000000..ec34a81
--- /dev/null
+++ b/content/docs/integrations/dependabot.mdx
@@ -0,0 +1,63 @@
+---
+title: Dependabot
+description: Have Mogplex open a reviewed fix PR when GitHub reports a new Dependabot alert, using the Dependabot autopilot workflow template.
+---
+
+When GitHub creates a Dependabot alert, Mogplex can start an agent that prepares
+the smallest safe dependency fix and opens a PR for review. GitHub still detects
+vulnerabilities and decides when an alert is fixed.
+
+## Requirements
+
+- The [GitHub](/integrations/github) integration is connected, and the Mogplex
+ GitHub App is installed on the repository.
+- **Dependabot alerts** are turned on for the repository in GitHub.
+- The GitHub App has the **Dependabot alerts: Read-only** permission and
+ subscribes to the **Dependabot alert** event. The hosted Mogplex App already
+ has both. For a self-hosted App, see
+ [GitHub App setup](/self-hosting/github-app). Each installation must accept
+ new permissions.
+
+## Set it up
+
+1. Open [Automations](/web/automations) and create a workflow from the
+ **Dependabot autopilot** template.
+2. Select the GitHub installation, the repository scope, the agent, and the
+ model.
+3. Publish the workflow.
+4. Optional: after you confirm that it works, turn off **Dependabot security
+ updates** in GitHub, so that Mogplex is the only tool that opens remediation
+ PRs. Keep **Dependabot alerts** on.
+
+## What the agent does
+
+1. Reads the alert from GitHub. If the alert is already closed, the agent stops.
+ If no patched version exists, the agent reports that the alert needs a human
+ decision.
+2. Checks open PRs to avoid duplicate work.
+3. Uses the repository's own package manager to make the smallest manifest and
+ lockfile change.
+4. Runs the available install, lint, typecheck, test, and build checks.
+5. Opens a PR that lists the alert, GHSA and CVE IDs, severity, package, old and
+ new versions, and check results.
+
+The agent never merges the PR and never dismisses the alert. Major upgrades,
+risky indirect dependency changes, and failed checks are reported for a human
+to decide.
+
+## Alert events
+
+The workflow start node can match `created`, `dismissed`, `fixed`, `reopened`,
+`reintroduced`, and `auto_dismissed`. The template selects only `created`.
+
+- An omitted action list also means `created`. An empty list matches nothing.
+- The other actions record the alert's state. They do not start remediation,
+ close PRs, or cancel runs.
+- Each GitHub delivery starts each matching workflow at most once.
+ Redelivering the same event does not create a second run.
+
+## Verify
+
+In the GitHub App's **Advanced → Recent deliveries**, find a
+`dependabot_alert.created` delivery and confirm that it started one run in
+[Observability](/web/observability).
diff --git a/content/docs/integrations/github.mdx b/content/docs/integrations/github.mdx
index 328632c..3a3773f 100644
--- a/content/docs/integrations/github.mdx
+++ b/content/docs/integrations/github.mdx
@@ -86,6 +86,12 @@ rules, including entry-agent behavior in automations.
- **PR review work starts in the wrong shape**: use an Assignment for standing
repo responsibility, not a one-off Trigger.
+## Dependabot alerts
+
+GitHub can also start work when it reports a vulnerable dependency. See
+[Dependabot](/integrations/dependabot) to have Mogplex open a reviewed fix PR
+for each new alert.
+
## Read next
@@ -93,4 +99,5 @@ rules, including entry-agent behavior in automations.
+
diff --git a/content/docs/integrations/index.mdx b/content/docs/integrations/index.mdx
index 03a6099..ab385bd 100644
--- a/content/docs/integrations/index.mdx
+++ b/content/docs/integrations/index.mdx
@@ -1,62 +1,63 @@
---
title: Integrations
-description: Connect Mogplex to GitHub, Vercel, Slack, CI, the hosted API, MCP clients, and local agent hosts.
+description: Every system Mogplex connects to, including GitHub, Slack, Linear, Notion, Sentry, Supabase, Neon, model providers, agent harnesses, webhooks, the API, and MCP clients.
---
-Integrations connect Mogplex to the systems that own source code, identity,
-runtime credentials, automation, and external tools.
+Integrations connect Mogplex to the systems that own your code, your
+conversations, your tools, and your models. Start with GitHub. Add the others
+when a workflow needs them.
+
+## Source control and chat
+
+
+
+
+
+
+
+## Tool connections
+
+Agents call these services as tools during chat, Control, Slack, and sandbox
+runs. Add them from **Connections → Integrations**.
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+## Models and agents
+
+
+
+
+
+
+
+## Start work from anywhere
+
+
+
+
+
+
## Integration order
-Start with GitHub identity, GitHub App coverage, and managed account access
-before debugging webhook routing. Add optional Vercel metadata, Slack, MCP
-servers, and CI entry points only after the account can see and cover the repo
-that should run.
+1. Connect GitHub and install the Mogplex GitHub App. Confirm coverage in
+ [Installations](/web/installations) before you debug webhook routing.
+2. Add Slack if your team requests work in chat.
+3. Add tool connections for the services agents must read or change.
+4. Add provider keys only if you want usage billed to your own provider
+ account.
+
+Running Mogplex on your own infrastructure? Each integration needs your own
+app or credentials. See [Self-hosting](/self-hosting).
diff --git a/content/docs/integrations/linear.mdx b/content/docs/integrations/linear.mdx
new file mode 100644
index 0000000..8407996
--- /dev/null
+++ b/content/docs/integrations/linear.mdx
@@ -0,0 +1,47 @@
+---
+title: Linear
+description: Connect Linear so Mogplex agents can read and update issues, projects, and cycles while they work on code.
+---
+
+Connect Linear to let agents read the issue they are working on, search related
+issues, and update issues, projects, and comments as the work moves.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.linear.app/mcp` |
+| Credential | Linear personal API key or OAuth access token (`lin_api_…`) |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Linear, create a personal API key. See
+ [Linear MCP](https://linear.app/docs/mcp).
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Linear**.
+4. Paste the key, then select **Add**.
+5. Test the saved connection and confirm that it lists tools.
+
+Agents act as the Linear user who owns the key. Use a key from an account whose
+access matches what agents should be able to change.
+
+## Use it
+
+- "Read LIN-482, implement the fix, and open a PR that links the issue."
+- "List open bugs in the Platform project and summarize which ones touch the
+ billing code."
+- In an [automation](/web/automations), give an agent node an instruction to
+ comment on the Linear issue when the PR opens.
+
+## What it does not do
+
+Linear is a tool connection only. Mogplex does not receive Linear webhooks, so
+Linear events cannot start runs. Start work from GitHub, Slack, a schedule, a
+[signed webhook](/integrations/webhooks), or the [API](/reference/api).
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Test fails with an auth error | The key was revoked or copied incompletely. Create a new key and update the connection. |
+| Tools are missing in one repo | The connection may be excluded from that repo. See [scope resolution](/configure-and-extend/connections-and-mcp#scope-resolution). |
+| Tools are missing in workspace chat or Slack | The connection is set to **Ask before running tools**. Those surfaces cannot ask, so use Control. |
diff --git a/content/docs/integrations/meta.json b/content/docs/integrations/meta.json
index e7bc780..e0fb2cc 100644
--- a/content/docs/integrations/meta.json
+++ b/content/docs/integrations/meta.json
@@ -3,8 +3,25 @@
"root": true,
"pages": [
"index",
+ "---Source Control and Chat---",
"github",
+ "dependabot",
+ "slack",
+ "---Tool Connections---",
+ "linear",
+ "notion",
+ "sentry",
+ "supabase",
+ "neon",
+ "browserbase",
+ "sanity",
+ "zapier",
+ "trigger-dev",
+ "---Models and Agents---",
+ "ai-provider-keys",
+ "claude-code-and-codex",
"vercel",
- "slack"
+ "---Triggers---",
+ "webhooks"
]
}
diff --git a/content/docs/integrations/neon.mdx b/content/docs/integrations/neon.mdx
new file mode 100644
index 0000000..fb3e2d6
--- /dev/null
+++ b/content/docs/integrations/neon.mdx
@@ -0,0 +1,44 @@
+---
+title: Neon
+description: Connect Neon so Mogplex agents can manage Postgres projects and branches and run SQL.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Connect Neon to let agents create database branches for a change, inspect
+schemas, run SQL, and prepare migrations.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.neon.tech/mcp` |
+| Credential | Neon API key |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Neon, create an API key under
+ [**Account settings → API keys**](https://console.neon.tech/app/settings/api-keys).
+ The preset's **Get a token** link opens this page.
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Neon**.
+4. Paste the key, then select **Add**.
+5. Test the saved connection and confirm that it lists tools.
+
+
+ A Neon API key can manage and delete projects the account owns. Prefer an
+ organization key with limited reach, scope the connection to the repos that
+ need it, and consider **Ask before running tools**.
+
+
+## Use it
+
+- "Create a Neon branch from `main`, apply the migration in this PR to it, and
+ report any errors."
+- "Explain why this query on the `events` table is slow and suggest an index."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Test fails with an auth error | The key was revoked. Create a new key and update the connection. |
+| Agent cannot see a project | The key belongs to a different account or organization. |
diff --git a/content/docs/integrations/notion.mdx b/content/docs/integrations/notion.mdx
new file mode 100644
index 0000000..6282a60
--- /dev/null
+++ b/content/docs/integrations/notion.mdx
@@ -0,0 +1,38 @@
+---
+title: Notion
+description: Connect Notion through OAuth so Mogplex agents can search and update pages, databases, and comments.
+---
+
+Connect Notion to let agents read specs and runbooks, search the workspace, and
+write results back to pages and databases.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.notion.com/mcp` |
+| Credential | OAuth. You sign in to Notion and choose which pages to share. |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. Open **Connections → Integrations**.
+2. Under **Quick Add — MCP Presets**, select **+ Add** on **Notion**, then
+ **Connect**.
+3. Sign in to Notion, select the workspace and pages to share, and approve.
+4. Back in Mogplex, test the saved connection and confirm that it lists tools.
+
+Mogplex registers itself with Notion automatically (dynamic client
+registration with PKCE). You do not need a Notion integration token.
+
+## Use it
+
+- "Read the 'Checkout v2' spec in Notion and list what the current code is
+ missing."
+- "After the PR merges, add a row to the Releases database with the PR link and
+ a summary."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| A page is not found | The page was not shared during the OAuth consent step. Reconnect and include it. |
+| Tools stopped working | The authorization expired or was revoked in Notion. Reconnect from **Connections**. |
diff --git a/content/docs/integrations/sanity.mdx b/content/docs/integrations/sanity.mdx
new file mode 100644
index 0000000..e50eb8e
--- /dev/null
+++ b/content/docs/integrations/sanity.mdx
@@ -0,0 +1,37 @@
+---
+title: Sanity
+description: Connect Sanity CMS so Mogplex agents can query and edit structured content, media, and releases.
+---
+
+Connect Sanity to let agents query documents with GROQ, draft and edit content,
+and work with releases next to the code that renders them.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.sanity.io` |
+| Credential | Sanity API token |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Sanity, create an API token for your project. Give it the least access
+ the agents need, such as **Viewer** for read-only work. See
+ [Sanity MCP server](https://www.sanity.io/docs/ai/mcp-server).
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Sanity CMS**.
+4. Paste the token, then select **Add**.
+5. Test the saved connection and confirm that it lists tools.
+
+## Use it
+
+- "Find every `post` document without an SEO description and draft one for
+ each."
+- "Add a `heroVideo` field to the `landingPage` schema and update the page
+ component to render it."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Writes fail with permission errors | The token's role is read-only. Create a token with **Editor** access if agents should write. |
+| Test fails | The token was deleted, or it belongs to a different project. |
diff --git a/content/docs/integrations/sentry.mdx b/content/docs/integrations/sentry.mdx
new file mode 100644
index 0000000..721e0df
--- /dev/null
+++ b/content/docs/integrations/sentry.mdx
@@ -0,0 +1,39 @@
+---
+title: Sentry
+description: Connect Sentry through OAuth so Mogplex agents can read issues, events, and traces and fix the errors they find.
+---
+
+Connect Sentry to let agents look up the error behind a bug report, read stack
+traces and events, and then fix the code in the same run.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.sentry.dev/mcp` |
+| Credential | OAuth. Requested scopes: `org:read`, `project:write`, `team:write`, `event:write`. |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. Open **Connections → Integrations**.
+2. Under **Quick Add — MCP Presets**, select **+ Add** on **Sentry**, then
+ **Connect**.
+3. Sign in to Sentry, choose the organization, and approve.
+4. Back in Mogplex, test the saved connection and confirm that it lists tools.
+
+The write scopes let agents update issues, for example to resolve or assign
+them. To keep agents read-only, set the connection to
+[**Ask before running tools**](/configure-and-extend/connections-and-mcp#asking-before-a-connections-tools-run)
+and approve calls in Control.
+
+## Use it
+
+- "Find the top unresolved Sentry issue in `web-app` from the last 24 hours,
+ reproduce it, and open a fix PR."
+- "Read the stack trace for this Sentry issue URL and explain the root cause."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| The organization is missing | The Sentry account that approved the connection is not a member of it. Reconnect with the right account. |
+| Tools stopped working | The authorization expired or was revoked. Reconnect from **Connections**. |
diff --git a/content/docs/integrations/supabase.mdx b/content/docs/integrations/supabase.mdx
new file mode 100644
index 0000000..1b3d00a
--- /dev/null
+++ b/content/docs/integrations/supabase.mdx
@@ -0,0 +1,46 @@
+---
+title: Supabase
+description: Connect Supabase so Mogplex agents can inspect and manage databases, auth, storage, and edge functions.
+---
+
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Connect Supabase to let agents inspect schemas, run queries, read logs, and
+manage edge functions in your Supabase projects.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, `https://mcp.supabase.com/mcp` |
+| Credential | Supabase personal access token (`sbp_…`) |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Supabase, create a personal access token under **Account → Access
+ Tokens**. See [Supabase MCP](https://supabase.com/docs/guides/getting-started/mcp).
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Supabase**.
+4. Paste the token, then select **Add**.
+5. Test the saved connection and confirm that it lists tools.
+
+
+ A personal access token can act on every project the account can reach,
+ including production. Scope the connection to the
+ [repos that need it](/configure-and-extend/connections-and-mcp#scope-resolution),
+ and consider **Ask before running tools** so that Control asks before each
+ call.
+
+
+## Use it
+
+- "Check the `orders` table schema in Supabase and write a migration that adds
+ a `refunded_at` column."
+- "Read the last hour of edge function logs for `stripe-webhook` and find why
+ it returns 500."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Test fails with `401` | The token was revoked or copied incompletely. Create a new token. |
+| A project is missing | The token's account is not a member of that organization. |
diff --git a/content/docs/integrations/trigger-dev.mdx b/content/docs/integrations/trigger-dev.mdx
new file mode 100644
index 0000000..a5593aa
--- /dev/null
+++ b/content/docs/integrations/trigger-dev.mdx
@@ -0,0 +1,50 @@
+---
+title: Trigger.dev
+description: Connect Trigger.dev so Mogplex agents can inspect and manage tasks, runs, schedules, and deploys in your Trigger.dev projects.
+---
+
+Connect Trigger.dev to let agents investigate failed runs, replay or cancel
+them, manage schedules, and check deploys in **your** Trigger.dev projects.
+
+| | |
+| --- | --- |
+| Type | Server-side API tools, plus the Trigger.dev MCP server in sandboxes and the CLI |
+| Credential | Trigger.dev personal access token (`tr_pat_…`) |
+| Where tools load | API tools in Control, workspace chat, the Slack agent, and native-harness runs. MCP server in Claude Code sandbox runs and the Mogplex CLI. |
+
+## Connect
+
+1. In Trigger.dev, create a personal access token under
+ [**Account → Tokens**](https://cloud.trigger.dev/account/tokens). The
+ preset's **Get a token** link opens this page.
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Trigger.dev**.
+4. Paste the token, then select **Add**.
+5. Test the saved connection. The test confirms that Trigger.dev accepts the
+ token and reports how many API tools are available.
+
+## How it works
+
+One token gives agents two tool sets:
+
+- **API tools that need no sandbox.** Mogplex calls the Trigger.dev management
+ API directly, so the tools work in chat and Slack without a running sandbox.
+- **The Trigger.dev MCP server.** In sandboxes and the CLI, Mogplex starts
+ `npx -y trigger.dev@latest mcp` with your token. The command is fixed in the
+ preset, so nothing you type is ever executed.
+
+See [How the Trigger preset works](/configure-and-extend/connections-and-mcp#how-the-trigger-preset-works)
+for the full list of API tool areas.
+
+## Use it
+
+- "Why did the `sync-orders` task fail in prod in the last hour? Show the error
+ and the run IDs."
+- "Pause the `nightly-report` schedule until Monday."
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| Test fails | The token was revoked, or it is a project secret key (`tr_prod_…`) instead of a personal access token (`tr_pat_…`). |
+| A project is missing | The token's account is not a member of that organization. |
diff --git a/content/docs/integrations/vercel.mdx b/content/docs/integrations/vercel.mdx
index b39119a..8f4a96e 100644
--- a/content/docs/integrations/vercel.mdx
+++ b/content/docs/integrations/vercel.mdx
@@ -1,86 +1,66 @@
---
title: Vercel
-description: Configure repo-linked Vercel project metadata, environment sync, and preview troubleshooting for Mogplex.
+description: How Mogplex uses Vercel Sandbox for agent compute, how to configure a repo's runtime and environment variables, and which Vercel features are not available.
---
-Vercel is optional integration metadata for repos that need project-aware
-preview settings.
-
-Mogplex-managed billing owns sandbox access. Use the Vercel integration when a
-repo needs Vercel-linked project settings for previews, root directories, and
-environment sync. Do not use it as an external sandbox account path.
-
-## Where Vercel is configured
-
-Vercel setup is primarily repo state:
-
-- [Projects](/web/spaces) owns repo-specific Vercel team, project, root
- directory, env mapping, install command, dev command, port, and timeout
- settings.
-- [Sandboxes](/web/sandboxes) shows live and pending runtime state after a
- sandbox exists.
-- [Observability](/web/observability) shows the call, job, sandbox, model, and
- cost trail after work starts.
-
-## Billing model
-
-Sandbox usage is billed through Mogplex. A linked Vercel project can provide
-preview metadata and environment sync, but it is not the billing source for
-Mogplex sandboxes.
-
-That means you can configure GitHub coverage, repo import, agents, triggers,
-assignments, and automations without asking users to attach their own sandbox
-account.
-
-## Repo-linked project settings
-
-Use [Projects](/web/spaces) when one repo needs Vercel-specific runtime
-configuration:
-
-- Vercel team and project mapping
-- root directory for monorepos
-- install command
-- dev command
-- dev port
-- sandbox timeout override
-- environment mapping mode
-- manual environment variables in `.env`-style `KEY=value` format
-
-This matters most for monorepos and preview apps where the default repo root is
-not the app Mogplex should run.
-
-## Environment sync
-
-Repo settings control how sandbox environment variables are assembled.
-
-Use manual repo variables when Mogplex needs values that are not sourced from a
-Vercel project. Use Vercel-linked sync when the repo should inherit environment
-state from the selected Vercel project, with repo settings acting as the
-Mogplex-side control point.
-
-If a preview boots but behaves like the wrong app or misses expected env vars,
-check the repo root, env mapping mode, Vercel project mapping, and manual repo
-vars together.
+import { Callout } from 'fumadocs-ui/components/callout';
+
+Mogplex runs every agent sandbox on
+[Vercel Sandbox](https://vercel.com/docs/vercel-sandbox), inside Mogplex's own
+Vercel project. **You do not need a Vercel account.** Sandbox usage bills
+through your [Mogplex plan](/plans-and-billing).
+
+
+ Mogplex cannot yet bill sandboxes to your own Vercel account or import
+ environment variables from your Vercel projects. Both features need an
+ API-capable Vercel integration that does not exist yet. "Sign in with Vercel"
+ is an identity grant only and cannot read projects or env vars. Add sandbox
+ variables by hand, as described below.
+
+
+## Configure a repo's runtime
+
+Open the repo in [Projects](/web/spaces) and edit its settings. These settings
+control how a sandbox installs and starts your app:
+
+| Setting | Use it when |
+| --- | --- |
+| Launch Branch | Sandboxes should start from a branch other than the default. |
+| Runtime | Auto-detection picks the wrong runtime. |
+| Root Directory | The app lives in a subfolder of a monorepo, such as `apps/web`. |
+| Install Command | The default install command for the package manager is wrong. |
+| Dev Command | The preview needs a specific start command. |
+| Dev Port | The dev server does not use the auto-detected port. |
+| Env Mapping | **Sandbox only** passes only your variables. **Sandbox + preview conventions** also sets Vercel preview variables (`VERCEL=1`, `VERCEL_ENV=preview`, `VERCEL_URL`, `NEXT_PUBLIC_APP_URL`, and similar) unless you define them yourself. |
+| Environment Variables | The app needs env vars. Paste `.env`-style `KEY=value` lines. Surrounding quotes are removed. |
+| Sandbox Billing | Always Mogplex billing. |
## Preview and sandbox troubleshooting
Start from the surface that owns the failure:
- Repo configuration problem: [Projects](/web/spaces)
-- Runtime already exists but looks stuck: [Sandboxes](/web/sandboxes)
-- Need the call or job trail behind the runtime: [Observability](/web/observability)
-- Account lacks managed sandbox access: [Plans & Billing](/plans-and-billing)
-
-Common failure modes:
-
-- **Sandbox launch says access is unavailable**: the account plan may not
- include managed sandbox access yet.
-- **Preview opens the wrong app**: set the repo root directory, install
- command, dev command, and dev port explicitly.
-- **Env values are missing**: inspect env mapping mode, linked Vercel project
- state, and manual repo variables in Projects.
-- **Runtime exists but workspace open lands wrong**: open the workspace from
- [Sandboxes](/web/sandboxes) so it binds to the exact sandbox instance.
+- The sandbox exists but looks stuck: [Sandboxes](/web/sandboxes)
+- You need the call or job trail behind the sandbox:
+ [Observability](/web/observability)
+- The account cannot launch sandboxes: [Plans & Billing](/plans-and-billing)
+
+Common failures:
+
+- **Sandbox launch says access is unavailable**: the plan or balance does not
+ include sandbox compute yet.
+- **Preview opens the wrong app**: set Root Directory, Install Command, Dev
+ Command, and Dev Port explicitly.
+- **Env values are missing**: add them under Environment Variables in the repo
+ settings. Mogplex does not read them from a Vercel project.
+- **The workspace opens the wrong sandbox**: open it from
+ [Sandboxes](/web/sandboxes), so that it binds to that exact sandbox.
+
+## Self-hosting
+
+A self-hosted deployment runs sandboxes on **your** Vercel team, through the
+`PLATFORM_VERCEL_*` variables. See
+[Sandboxes and models](/self-hosting/sandboxes-and-models).
## Read next
diff --git a/content/docs/integrations/webhooks.mdx b/content/docs/integrations/webhooks.mdx
new file mode 100644
index 0000000..50cc809
--- /dev/null
+++ b/content/docs/integrations/webhooks.mdx
@@ -0,0 +1,72 @@
+---
+title: Signed Webhooks
+description: Start a Mogplex automation from any system that can send an HTTP POST, using an HMAC-signed webhook.
+---
+
+A signed webhook lets any system start a Mogplex automation, including CI,
+monitoring alerts, internal tools, Zapier, or a cron job. The system sends JSON
+to a URL unique to the workflow. Mogplex verifies the signature and starts the
+published workflow with the payload.
+
+## Set up the workflow
+
+1. Open [Automations](/web/automations) and select the workflow's start node.
+2. Set the trigger event to **Signed webhook**.
+3. Select the repository that runs should use.
+4. Copy the **Endpoint**:
+ `https://mogplex.com/api/webhooks/flows/`.
+5. Select **Generate signing secret** and copy the secret. Mogplex shows it
+ only once. **Rotate signing secret** replaces it.
+6. Write each agent node's instructions. Use the test payload field to try it.
+7. Publish the workflow. Webhooks start only active, published workflows.
+
+## Send a request
+
+Every request must:
+
+- Use `POST` with a JSON **object** body, at most 1 MB.
+- Include `x-mogplex-delivery`: a unique ID for this event, at most 200
+ characters. Mogplex starts at most one run per delivery ID, so retries are
+ safe.
+- Include `x-mogplex-signature`: `sha256=` followed by the hex HMAC-SHA256 of
+ the raw request body, keyed with the signing secret.
+
+```bash
+BODY='{"prompt":"Investigate the failing checkout test","build":"4821"}'
+SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MOGPLEX_WEBHOOK_SECRET" -hex | sed 's/^.* //')"
+
+curl -X POST "https://mogplex.com/api/webhooks/flows/$WORKFLOW_ID" \
+ -H "content-type: application/json" \
+ -H "x-mogplex-delivery: build-4821" \
+ -H "x-mogplex-signature: $SIG" \
+ --data "$BODY"
+```
+
+Sign the exact bytes you send. Re-serializing the JSON after signing changes
+the body and fails verification.
+
+```ts
+import { createHmac } from 'node:crypto';
+
+const body = JSON.stringify(payload);
+const signature = `sha256=${createHmac('sha256', secret).update(body).digest('hex')}`;
+```
+
+## Use the payload
+
+The payload is available to the workflow under `metadata.webhook`. Refer to
+its fields in agent instructions and branch conditions.
+
+## Responses
+
+| Status | Meaning |
+| --- | --- |
+| `202` | Accepted. A run was queued. |
+| `200` | Accepted, but no new run started. The response `reason` explains why, for example `REPO_NOT_FOUND` or a delivery ID that was already used. |
+| `400` | The `x-mogplex-delivery` header is missing or too long, or the body is not a JSON object. |
+| `401` | The signature is invalid. |
+| `404` | The workflow has no signing secret, is not active and published, or its start node is not **Signed webhook**. |
+| `413` | The body is larger than 1 MB. |
+
+Treat the signing secret like a password. Store it in your sender's secret
+store, and rotate it if it leaks.
diff --git a/content/docs/integrations/zapier.mdx b/content/docs/integrations/zapier.mdx
new file mode 100644
index 0000000..1e13850
--- /dev/null
+++ b/content/docs/integrations/zapier.mdx
@@ -0,0 +1,42 @@
+---
+title: Zapier
+description: Connect your Zapier MCP server so Mogplex agents can run actions across thousands of apps.
+---
+
+Connect Zapier to give agents the actions you configured in Zapier MCP, such as
+sending email, creating calendar events, updating a CRM, or posting to a channel.
+
+| | |
+| --- | --- |
+| Type | Remote MCP server, at a URL unique to your Zapier account |
+| Credential | The secret Zapier MCP server URL |
+| Where tools load | Every surface that loads [connection tools](/configure-and-extend/connections-and-mcp#where-connection-tools-load) |
+
+## Connect
+
+1. In Zapier MCP, choose the actions that agents may run. Then copy your
+ server URL from the **Connect** tab. See
+ [Use Zapier MCP with your client](https://help.zapier.com/hc/en-us/articles/36265392843917-Use-Zapier-MCP-with-your-client).
+2. In Mogplex, open **Connections → Integrations**.
+3. Under **Quick Add — MCP Presets**, select **+ Add** on **Zapier**.
+4. Paste the full server URL, then select **Add**.
+5. Test the saved connection and confirm that it lists your actions.
+
+The URL is the credential. Anyone who has it can run your actions, so Mogplex
+stores it encrypted. If the URL leaks, rotate it in Zapier and update the
+connection.
+
+## Use it
+
+- "When the deploy finishes, email the release notes to the team using Zapier."
+- "Create a HubSpot task for each customer issue mentioned in this thread."
+
+Agents can use only the actions you enabled in Zapier. To add an action, enable
+it in Zapier, then test the connection again.
+
+## Troubleshooting
+
+| Symptom | Check |
+| --- | --- |
+| An action is missing | It is not enabled in Zapier MCP. |
+| Test fails | The URL was rotated in Zapier. Paste the new URL. |