Skip to content

Configuration Reference

import { Aside } from ‘@astrojs/starlight/components’;

Every cspace project is configured through a .cspace.json file in the repository root. This page documents every configuration key, how configs are merged, and what gets auto-detected.

.cspace.json
{
"project": {
"name": "my-project",
"repo": "owner/my-project",
"prefix": "mp"
},
"container": {
"ports": {
"3000": "dev server",
"4173": "preview server"
},
"environment": {
"VITE_HOST": "0.0.0.0"
}
},
"firewall": {
"enabled": true,
"domains": [
"api.example.com",
"cdn.example.com"
]
},
"claude": {
"model": "opus[1m]",
"effort": "max"
},
"mcpServers": {},
"plugins": {
"enabled": true,
"install": [
"superpowers",
"context7",
"code-review"
]
},
"verify": {
"all": "npm run lint && npm run typecheck && npm run test",
"e2e": "npm run e2e"
},
"agent": {
"issue_label": "ready"
},
"services": ".cspace/docker-compose.yml",
"post_setup": ".cspace/post-setup.sh",
"serviceUrls": {
"convex": ["VITE_CONVEX_URL"],
"convex-site": ["VITE_CONVEX_SITE_URL"]
}
}

Project identity. All three fields are auto-detected if left empty.

KeyTypeDefaultDescription
project.namestring""Project display name. Auto-detected from the directory name if empty.
project.repostring""GitHub repository in owner/repo format. Auto-detected from git remote if empty.
project.prefixstring""Short prefix used for naming Docker resources (compose projects, containers). Auto-derived from the first 2 characters of project.name if empty.

Controls the devcontainer environment.

KeyTypeDefaultDescription
container.portsobject{}Port mappings exposed from the container. Keys are port numbers (as strings), values are human-readable descriptions. Example: {"3000": "dev server"}.
container.environmentobject{}Environment variables injected into the container. Key-value pairs. Example: {"VITE_HOST": "0.0.0.0"}.

Egress firewall configuration. GitHub, npm, and Anthropic domains are always allowed regardless of this setting.

KeyTypeDefaultDescription
firewall.enabledbooleantrueEnable the iptables-based egress firewall. When enabled, only whitelisted domains can be reached from inside the container.
firewall.domainsarray[]Additional domains to whitelist for outbound traffic.

Autonomous supervisor settings. These keys are passed as --model / --effort flags to supervisor.mjs when cspace launches an agent, which maps them to the Claude Agent SDK’s options.model / options.effort — taking precedence for that single query.

They are deliberately not set as container env vars, because ANTHROPIC_MODEL and CLAUDE_CODE_EFFORT_LEVEL override project .claude/settings.json. Interactive claude sessions in an ssh shell instead pick up whatever the project’s settings.json (or user’s ~/.claude/settings.json, or account default) specifies — the normal Claude Code precedence.

KeyTypeDefaultScopeDescription
claude.modelstring"opus[1m]"autonomous onlyClaude model for supervisor-launched agents. opus alias resolves to the latest Opus; [1m] enables the 1M-token context window. Pin a version with "claude-opus-4-7[1m]" or switch classes with "sonnet". Set to "" to fall back to the CLI account default.
claude.effortstring"" (→ max)autonomous onlyReasoning effort for supervisor-launched agents. Accepted: low, medium, high, xhigh, max, auto. Empty means max (the autonomous default).

To control the interactive claude model/effort in a project, commit a .claude/settings.json with model / effortLevel entries to the repo — standard Claude Code configuration.

KeyTypeDefaultDescription
mcpServersobject{}MCP (Model Context Protocol) server configurations. Each key is a server name; the value is the server’s config object. Passed through to Claude Code inside the container.

Controls automatic plugin installation from the official marketplace during instance setup.

KeyTypeDefaultDescription
plugins.enabledbooleantrueEnable automatic plugin installation. Set to false to skip.
plugins.installarraySee belowList of plugin names to install from the official marketplace.

The default plugins.install list includes: superpowers, frontend-design, context7, code-review, code-simplifier, github, feature-dev, security-guidance, commit-commands, pr-review-toolkit, agent-sdk-dev, plugin-dev.

Override the list in .cspace.json to install a different set, or disable entirely:

.cspace.local.json
{
"plugins": { "enabled": false }
}

Commands used to verify code before shipping.

KeyTypeDefaultDescription
verify.allstring""Shell command for running all verification (lint, typecheck, tests). Executed by agents after making changes.
verify.e2estring""Shell command for running end-to-end tests. Executed separately from verify.all because E2E tests often require a running dev server.

Controls autonomous agent behavior.

KeyTypeDefaultDescription
agent.issue_labelstring"ready"GitHub label that marks issues as ready for autonomous processing. Used by the /run-ready workflow to find issues to work on.
KeyTypeDefaultDescription
servicesstring""Path to a Docker Compose file with project-specific services (e.g., ".cspace/docker-compose.yml"). See Project Services.
post_setupstring""Path to a shell script that runs after container initialization (e.g., ".cspace/post-setup.sh"). See Project Services.

Map of Traefik subdomain label → list of framework env var aliases. For each entry, cspace generates a compose override at instance start and injects:

  • CSPACE_SERVICE_<LABEL>_URL — the canonical env var name.
  • Every alias listed in the array, set to the same URL — lets frameworks pick it up on boot without a .env.local entry.

The URL is always http://<label>.<instance>.<project>.cspace.local — the same hostname the host browser, container sidecars, and Playwright all resolve to via Traefik, so there’s one correct value regardless of where the request originates.

.cspace.json
{
"serviceUrls": {
"convex": ["VITE_CONVEX_URL", "CONVEX_URL"],
"convex-site": ["VITE_CONVEX_SITE_URL"]
}
}

The subdomain labels must match the Host(\

Configuration is loaded and merged in order — later sources override earlier ones using recursive deep merge (jq’s * operator). You only need to specify the keys you want to override; everything else inherits from the previous layer.

PrioritySourceDescription
1 (lowest)$CSPACE_HOME/lib/defaults.jsonBuilt-in defaults shipped with cspace.
2.cspace.jsonProject config, committed to git. Shared by the whole team.
3.cspace.local.jsonLocal overrides, gitignored. Per-developer customization.
4 (highest)Environment variablesCSPACE_PROJECT_NAME and CSPACE_PROJECT_REPO override their respective config keys.

Given these two files:

defaults.json
{
"firewall": { "enabled": true, "domains": [] },
"claude": { "model": "opus[1m]", "effort": "" }
}
.cspace.json
{
"firewall": { "domains": ["api.example.com"] }
}

The merged result is:

Effective config
{
"firewall": { "enabled": true, "domains": ["api.example.com"] },
"claude": { "model": "opus[1m]", "effort": "" }
}

The firewall.enabled default is preserved because .cspace.json only overrides firewall.domains.

When a field is left empty (or omitted), cspace auto-detects it at load time:

FieldDetection method
project.nameDerived from the current directory name (basename of the git root).
project.repoExtracted from the origin git remote URL. Supports both HTTPS (https://github.com/owner/repo.git) and SSH (git@github.com:owner/repo.git) formats.
project.prefixFirst 2 characters of project.name.

Two environment variables can override config values at runtime, taking the highest priority:

VariableOverrides
CSPACE_PROJECT_NAMEproject.name
CSPACE_PROJECT_REPOproject.repo

These are applied after file-based merging but before auto-detection, so they also prevent auto-detection from running for those fields.

cspace computes several internal names from the configuration. These are not directly configurable but are useful to know when debugging container and volume naming:

NameFormulaExample
Compose project{prefix}-{instance}mp-mercury
Docker imagecspace-{name}cspace-my-project
Memory volumecspace-{name}-memorycspace-my-project-memory
Logs volumecspace-{name}-logscspace-my-project-logs
Instance labelcspace.project={name}cspace.project=my-project