Configuration¶
CodePlane works out of the box with sensible defaults. This page covers the settings you're most likely to change.
First-Time Setup¶
Run the interactive setup wizard:
This walks you through registering a repository, selecting a default agent, and setting preferences.
Global Config File¶
Location: ~/.codeplane/config.yaml (created on first run or via cpl setup).
Agent Defaults¶
agent:
default_sdk: copilot # agent CLI to use: copilot | claude
default_model: ~ # model name, or ~ for agent default
Action Policy¶
The action policy system controls what an agent can do without your approval. Configure the default preset:
| Preset | Behavior |
|---|---|
autonomous |
Only non-contained actions (outside worktree, external calls) require approval |
supervised |
Contained and reversible actions proceed; all others require approval (default) |
locked |
Even safe actions create a git checkpoint first; non-contained/irreversible actions require approval |
The preset and all policy rules are managed in Settings → Policy in the UI, or via the REST API (/settings/policy/). These settings are stored in the database and can be changed at runtime (running jobs reload automatically).
See Usage Guide > Action Policy for full details on tiers, rules, and overrides.
Server¶
Retention¶
retention:
max_completed_jobs: 100 # auto-cleanup oldest when exceeded
max_worktree_age_hours: 72 # auto-delete old worktrees
Per-Repository Overrides¶
Place a .codeplane.yml file in any repository root to override global settings for jobs in that repo:
Remote Access¶
Run the agent on your workstation, control it from your phone or any browser. CodePlane supports two tunnel providers.
Dev Tunnels (default)¶
Prerequisite: Install the Dev Tunnels CLI, or run cpl setup which handles it for you.
cpl up --remote # password auto-generated
cpl up --remote --password my-secret # explicit password
cpl up --remote --tunnel-name my-tunnel # reuse a named tunnel
A password is always required for remote access. By default one is auto-generated; set it explicitly via --password or the CPL_PASSWORD env var.
After startup, run cpl info to print the tunnel URL and a QR code you can scan from your phone.
Cloudflare Tunnels¶
Use Cloudflare Tunnels when you want a stable public hostname (e.g., codeplane.yourdomain.com) instead of the auto-provisioned Dev Tunnels URL.
Cloudflare Access is required
Cloudflare Tunnels have no identity gate by default. CodePlane will refuse to start unless it detects a Cloudflare Access application on the hostname.
Prerequisites:
- Install
cloudflared - Create a named tunnel and route a public hostname to
http://localhost:8080 - Create a Cloudflare Access application on that hostname with an identity policy. Email OTP is the simplest option; SSO and mTLS are also supported.
Start CodePlane:
export CPL_CLOUDFLARE_TUNNEL_TOKEN=eyJhIjo... # from tunnel setup
export CPL_CLOUDFLARE_HOSTNAME=codeplane.yourdomain.com
cpl up --remote --provider cloudflare
At startup, CodePlane probes the hostname for a Cloudflare Access gate. If none is detected, the server exits with an error.
Cloudflare Access JWT Verification¶
When cloudflared is managed externally (e.g., a systemd service or Docker sidecar) and CodePlane is not started with --remote --provider cloudflare, you can still delegate authentication to Cloudflare Access by configuring JWT verification:
export CPL_CF_ACCESS_TEAM=yourteam # <team> in <team>.cloudflareaccess.com
export CPL_CF_ACCESS_AUD=your-aud-tag-here # Application Audience Tag from Zero Trust dashboard
At startup CodePlane fetches Cloudflare's JWKS signing keys (validating the Access gate exists) and then cryptographically verifies the Cf-Access-Jwt-Assertion header on every request — checking signature, audience, and expiry. If either variable is missing, the header is ignored and normal password auth applies.
You can find the AUD tag in the Cloudflare Zero Trust dashboard under Access → Applications → your app → Overview → Application Audience (AUD) Tag.
Tunnel Lifecycle¶
Both providers are supported on Linux, macOS, native Windows, and WSL.
The connector is tied to the server. CodePlane starts the connector process (devtunnel host or cloudflared) as a child of the server and stops it again when the server stops — via cpl down, cpl restart, or Ctrl-C. After a normal shutdown no connector is left behind and the public origin reports no host connections.
Reusing an existing connector. If a cloudflared process is already serving the configured tunnel — a systemd/Docker-managed connector, or one orphaned by a previous run — CodePlane detects it at startup, reuses it instead of starting a second one, and leaves it running at shutdown. Detection matches the tunnel token (or the tunnel ID derived from it) on the running process's command line, so a cloudflared serving some other tunnel on the same machine is ignored and CodePlane starts its own connector. Externally managed connectors are never terminated by CodePlane.
Named Dev Tunnels are reusable. --tunnel-name reuses the same tunnel and port registration across restarts, so the URL stays stable. Re-running against a tunnel whose port is already registered is expected and handled.
Connector supervision. A watchdog restarts the connector if the connector process exits, or if the public relay stops forwarding while the local server is healthy. It deliberately does not restart the connector when the local server itself is unreachable (for example during a slow startup) — restarting a connector cannot fix a down origin.
cpl down is not graceful on Windows
Windows has no process signals: cpl down terminates the server and every process below it outright. The connector is stopped first, so the public origin closes promptly and no connector is orphaned — but the server's own shutdown handlers do not run, so worktree cleanup and lease release are skipped. Running sessions are paused over the API before the stop, which is what preserves session state. On Linux, macOS, and WSL, cpl down sends SIGTERM and the full graceful shutdown runs.
Hard kills can orphan the connector
If the server is killed abruptly (kill -9, Task Manager, a crash), it gets no chance to stop the connector and the process may survive. The next cpl up detects the surviving connector and reuses it. To remove it manually, stop the devtunnel host / cloudflared process for your origin.
If the server is killed abruptly (kill -9, Task Manager, a crash), it gets no chance to stop the connector and the process may survive. The next cpl up detects the surviving connector and reuses it. To remove it manually, stop the devtunnel host / cloudflared process for your origin.
All Remote Options¶
| CLI Flag | Env Var | Description |
|---|---|---|
--remote |
— | Enable remote access (required) |
--provider |
— | devtunnel (default) or cloudflare |
--password SECRET |
CPL_PASSWORD |
Auth password (auto-generated if omitted) |
--tunnel-name NAME |
CPL_DEVTUNNEL_NAME |
Reuse a named Dev Tunnel across restarts |
| — | CPL_CLOUDFLARE_TUNNEL_TOKEN |
Cloudflare Tunnel token |
| — | CPL_CLOUDFLARE_HOSTNAME |
Cloudflare public hostname |
| — | CPL_CF_ACCESS_TEAM |
CF Access team name (for JWT verification) |
| — | CPL_CF_ACCESS_AUD |
CF Access Application Audience tag |
Other Environment Variables¶
| Variable | Description | Default |
|---|---|---|
OTEL_EXPORTER_ENDPOINT |
OTLP endpoint for exporting metrics/traces | — (local only) |
MCP Server Discovery¶
When a job starts, CodePlane discovers MCP servers to make available to the agent. Servers are merged from two sources (repo-level wins on name conflicts):
- Repo-level:
.vscode/mcp.jsonin the repository (VS Code / Copilot convention) - Global:
tools.mcpin~/.codeplane/config.yaml
Global config example¶
tools:
mcp:
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
postgres:
command: uvx
args: ["mcp-postgres"]
env:
DATABASE_URL: "${DATABASE_URL}"
Repo-level example (.vscode/mcp.json)¶
{
"servers": {
"github": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"]
}
}
}
Disabling servers per-repo¶
Add a .codeplane.yml file to the repository root:
This prevents the postgres MCP server from starting for jobs in this repo, even if it's defined globally.
UI Settings¶
Additional preferences are available in Settings (Ctrl+,): registered repositories, default agent, model preferences, and push notification settings.
Push Notifications¶
Toggle push notifications in Settings → Notifications. Notifications are delivered via the Web Push protocol. When enabled for the first time, your browser will ask for permission.
VAPID keys are generated automatically on first startup and stored in ~/.codeplane/vapid.json. No manual configuration is required.
Notifications fire on three events:
| Event | Notification |
|---|---|
approval_requested |
"Approval needed" — a job is waiting for your decision |
job_completed |
"Job completed" — the agent finished |
job_failed |
"Job failed" — the run encountered an error |
Job Sharing¶
Share tokens are generated on demand from the job detail toolbar (Share button). Tokens expire after 24 hours and are stored in-memory — a server restart invalidates all tokens.
Shared links bypass CodePlane's password for read-only access to job status and live events. The viewer must still be able to reach the server (e.g. via the same tunnel or LAN). No configuration is required.
Port Preview Proxy¶
A reverse proxy at /api/preview/{port}/ forwards to 127.0.0.1:{port}. This is useful when combined with --remote to access development servers from another device. Only ports 1024–65535 are allowed.
CodeRecon (Structural Analysis)¶
CodePlane integrates with CodeRecon for structural code review — semantic diffs, risk scoring, merge confidence, and dependency analysis.
coderecon:
enabled: true # enable structural analysis (default: false)
binary: /path/to/coderecon # path to CodeRecon binary (auto-detected if on PATH)
home: ~/.coderecon # daemon state directory (default)
tool_tier: standard # minimal | standard | full
| Tool Tier | Description |
|---|---|
minimal |
Basic structural diff only |
standard |
Diff + risk scoring + reference analysis (default) |
full |
All features including community detection and story generation |
When enabled, a structural review dashboard appears on job completion with change risk analysis and merge confidence verdicts. See Usage Guide > Structural Review for details.