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. | 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][] = [