AGENTS.md
Recommended operating contract for coding agents using Deku from a repo or shell.
The full checked-in AGENTS.md from the repository root is included at the bottom of the page so users can copy it directly.
If an agent needs a known-good starter app quickly, use the local App templates catalog before building a fresh project from scratch.
Supported Agent Contract
Section titled “Supported Agent Contract”Defaults:
- Primary interface:
dekuCLI - Fallback machine interface: Daemon HTTP API with an operator-provisioned dashboard token
- Preferred deploy method: Archive or image deploy via CLI or HTTP API
- Secondary deploy method:
git pushover SSH - Supported operator model: Coding agents running in a shell or repo
- Supported workflow class: Deploy + inspect
Supported today:
- App create / inspect
- Config set / list / unset
- Deploy run / list / rollback
- Domains add / list / remove
- Logs and process/status inspection
Out of scope today:
- Full autonomous platform administration
- Dynamic plugin authoring
- MCP implementation
Why CLI + API First
Section titled “Why CLI + API First”The CLI and daemon API already cover the core workflow agents need today.
For most agent-driven deployments, archive and image deploys are a better fit than git push because they are:
- Easier to script deterministically
- Easier to reason about from an agent loop
- Easier to inspect and retry
SSH git push deploys remain supported, but they are not the recommended default path for agents.
On packaged installs, Deku’s embedded SSH deploy endpoint defaults to port 2222 so the daemon can coexist with a host sshd on port 22.
Canonical Agent Workflow
Section titled “Canonical Agent Workflow”The standard agent flow is:
- Ensure
dekudis reachable. - Prefer the local
dekuCLI over the trusted Unix socket; only use direct HTTP if you already have a dashboard token. - Create or inspect app state.
- Set required config.
- Deploy via archive or image path.
- Poll deployment status and inspect logs.
- Verify resulting app state.
Preflight Checks
Section titled “Preflight Checks”Recommended checks before an agent attempts a deploy:
TOKEN="dku_REPLACE_WITH_OPERATOR_TOKEN"deku apps listdeku apps info <app>deku config list <app>curl -H "Authorization: Bearer ${TOKEN}" \ http://127.0.0.1:2810/api/appsIf the app does not exist yet:
deku apps create <app>Starter App Catalog
Section titled “Starter App Catalog”Before scaffolding a new app from nothing, check the local templates/ directory in this repository.
Common examples:
deku deploy run agent-demo --path /absolute/path/to/repo/templates/node-expressdeku deploy run agent-demo --path /absolute/path/to/repo/templates/nextjsdeku deploy run agent-demo --path /absolute/path/to/repo/templates/djangoThese starters are adapted for Deku:
- They use Deku-supported
dockerfileorrailpackbuilders - They expect Deku-managed services instead of bundled sidecars
- They stay local to the repo so agents can inspect and modify them directly
CLI Workflow Examples
Section titled “CLI Workflow Examples”Create app state:
deku apps create agent-demodeku apps info agent-demodeku config set agent-demo NODE_ENV=production PORT=3000deku domains add agent-demo demo.localDeploy from source archive path:
deku deploy run agent-demo --path /absolute/path/to/appdeku deploy list agent-demoDeploy from a pre-built image:
deku deploy run agent-demo --image nginx:alpinedeku deploy list agent-demoInspect state after deploy:
deku logs agent-demo -n 100deku ps list agent-demodeku apps info agent-demoHTTP API Workflow Examples
Section titled “HTTP API Workflow Examples”If an agent needs direct HTTP access, use a dashboard token that was captured during deku setup or minted explicitly with deku dashboard reset-token.
Example session:
TOKEN="dku_REPLACE_WITH_OPERATOR_TOKEN"List apps:
curl -H "Authorization: Bearer ${TOKEN}" \ http://127.0.0.1:2810/api/appsCreate an app:
curl -X POST \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"name":"agent-demo"}' \ http://127.0.0.1:2810/api/appsSet config:
curl -X POST \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"key":"NODE_ENV","value":"production"}' \ http://127.0.0.1:2810/api/apps/agent-demo/configDeploy from a pre-built image:
curl -X POST \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"source":"image","image":"nginx:alpine"}' \ http://127.0.0.1:2810/api/apps/agent-demo/deployDeploy from a source archive:
tar -czf /tmp/agent-demo.tar.gz -C /absolute/path/to/app .
curl -X POST \ -H "Authorization: Bearer ${TOKEN}" \ -F archive=@/tmp/agent-demo.tar.gz \ http://127.0.0.1:2810/api/apps/agent-demo/deploy/archiveList deployments:
curl -H "Authorization: Bearer ${TOKEN}" \ http://127.0.0.1:2810/api/apps/agent-demo/deploymentsFetch recent logs:
curl -H "Authorization: Bearer ${TOKEN}" \ "http://127.0.0.1:2810/api/apps/agent-demo/logs?n=100"Inspect app state:
curl -H "Authorization: Bearer ${TOKEN}" \ http://127.0.0.1:2810/api/apps/agent-demoWhen To Use CLI vs API vs SSH
Section titled “When To Use CLI vs API vs SSH”Use the CLI when:
- The agent already has shell access
- The workflow benefits from built-in command ergonomics
- Source archive deploy is needed
Use the HTTP API when:
- The agent needs machine-structured output directly
- The workflow is built around authenticated HTTP calls
- App inspection or control loops are easier through JSON responses
Use SSH git push when:
- You explicitly want to exercise the Git remote deploy path
- The workflow is already organized around server-side Git remotes
Do not make SSH git push the default path for agents.
Failure Handling
Section titled “Failure Handling”If the daemon is missing or unreachable:
- Verify
dekudis running - Verify you have a valid dashboard token if you are using direct HTTP
- Verify authenticated requests to
/api/appssucceed
If the app does not exist:
- Create it before attempting config or deploy operations
If a deploy fails:
- Inspect
deku deploy list <app> - Inspect
deku logs <app> -n 100 - Confirm app config and domains are correct
If domains or config do not match expectations:
- Re-read app info and config
- Treat CLI/API output as the source of truth
If a service dependency is missing:
- Verify object store, managed services, or other optional integrations before depending on them
- Treat missing integrations as preconditions, not implicit defaults
Current Limitations
Section titled “Current Limitations”The current product shape still has important constraints:
- The dashboard is useful, but the agent contract is CLI/API-first
- Dynamic plugin support exists, but it is not the primary first-party integration model
- Installation and packaging are still maturing
MCP Later
Section titled “MCP Later”MCP is not required for the current agent workflow because the CLI and daemon HTTP API already cover the target coding-agent workflow.
MCP becomes worthwhile when Deku needs:
- External assistants without shell access
- Richer machine-readable resource discovery
- Structured tool invocation across apps, deploy, config, domains, logs, and deployments
If Deku adds MCP later, the first MCP server should expose only stable platform primitives:
- Apps
- Deploy
- Config
- Domains
- Logs
- Deployments
The first MCP design should not include dynamic plugin surfaces.
Start MCP-later work only after the CLI/API workflow documented on this page is stable and verified.
AGENTS.md
Section titled “AGENTS.md”This copy is generated from the repository’s AGENTS.md at build time, so it always matches the file agents actually read.
# AGENTS
Agent operating guide for Deku.
This file is for coding agents with shell access on the same machine as the Deku project or server. It covers what to use, what to avoid, and the safest default path for deploying and inspecting apps.
Do not read this file as permission for broad unattended platform administration.
## Supported Agent Model
- Primary interface: the `deku` CLI- Fallback machine interface: the daemon HTTP API, with an operator-provisioned dashboard token- Preferred deploy path: archive or image deploy through `deku deploy run`- Secondary deploy path: `git push` over SSH- Default workflow: deploy, then inspect
## Preferred Workflow
1. Confirm `dekud` is running and reachable.2. Inspect or create the target app.3. Set the config vars the app needs.4. Deploy with `deku deploy run <app> --path <dir>` or `--image <ref>`.5. Read the deploy output to the end. A failed deploy names the failing step, and the previous version keeps serving.6. Verify before moving on: `deku deploy list <app>`, `deku logs <app> -n 100`, `deku doctor`.7. Stop when the app reports `deployed` and the newest deployment reports `live`.
Prefer deterministic, non-interactive commands. Use the CLI over the trusted Unix socket; use direct HTTP only when you already have a dashboard token. Use `git push` only when you specifically need to exercise the SSH remote path.
## Preflight Checks
Run these before a deploy. They read state and change nothing:
```bashdeku doctordeku apps info <app>deku config list <app>```
`deku doctor` exits `1` when a check has failed. A non-zero exit means the host is not healthy: fix it before deploying.
If the app does not exist yet, create it:
```bashdeku apps create <app>```
## Starter App Catalog
Check the local `templates/` directory in this repository before building an app from scratch:
```bashdeku deploy run <app> --path /absolute/path/to/repo/templates/node-expressdeku deploy run <app> --path /absolute/path/to/repo/templates/nextjsdeku deploy run <app> --path /absolute/path/to/repo/templates/django```
The templates are adapted for Deku: they use the `dockerfile` or `railpack` builder, expect Deku-managed services instead of bundled sidecars, and stay local to the repo so you can inspect and copy them.
## Common Operations
Create and configure an app:
```bashdeku apps create <app>deku apps info <app>deku apps destroy <app> # the CLI verb is destroy, not deletedeku config set <app> KEY=VALUEdeku config list <app>deku domains add <app> example.test```
Deploy and roll back:
```bashdeku deploy run <app> --path /absolute/path/to/sourcedeku deploy run <app> --image nginx:alpinedeku deploy list <app>deku deploy rollback <app>```
Put migrations in a `release:` entry in the image's Procfile. That entry runs on every deploy, and a failure fails the deploy, so a broken migration never reaches the running app. Use `deku run` only for one-off tasks you trigger by hand.
Inspect a running app:
```bashdeku logs <app> -n 100deku logs <app> --follow --timeout 30 # stop after 30 seconds without outputdeku ps list <app>deku apps info <app>```
Run a command in the app's environment. Both forms are non-interactive, stream output, and exit with the command's status:
```bashdeku run <app> python manage.py migrate # fresh container, removed when it exitsdeku exec <app> ls -la /app # inside the running web container```
Use `exec` for inspection only. It writes to the live container, and the change is lost on the next deploy.
Control traffic and resources:
```bashdeku maintenance on <app> --message "Deploying"deku maintenance off <app>deku redirects add <app> /old /new --code 301deku redirects list <app>deku ps limits <app> --memory 512m --cpu 0.5```
Turn on maintenance mode before a change that briefly breaks the app, and turn it off once the deploy reports `live`.
Back up a managed service:
```bashdeku postgres backup <service>deku postgres backups <service>deku postgres restore <service> <backup-id>deku backup schedule <service> --interval-hours 24 --keep 7deku backup schedules```
Backups need a configured object store. Check it with `deku objectstore test` before you rely on one.
An operator may have offloaded builds to another host. Check before assuming a deploy builds locally:
```bashdeku build-host infodeku build-host check```
`deku deploy run <app> --path <dir> --build-host local` forces a local build for one deploy.
## HTTP API Fallback
Use the daemon API when you need machine-structured output and already have a dashboard token. `deku dashboard` prints the base URL and the current token status.
```bashTOKEN="dku_REPLACE_WITH_OPERATOR_TOKEN"BASE="http://127.0.0.1:2810"
curl -H "Authorization: Bearer ${TOKEN}" "${BASE}/api/apps"curl -H "Authorization: Bearer ${TOKEN}" "${BASE}/api/doctor"curl -H "Authorization: Bearer ${TOKEN}" "${BASE}/api/apps/<app>/deployments"
curl -X POST -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" \ -d '{"source":"image","image":"nginx:alpine"}' \ "${BASE}/api/apps/<app>/deploy"
tar -czf /tmp/app.tar.gz -C /absolute/path/to/app .curl -X POST -H "Authorization: Bearer ${TOKEN}" \ -F archive=@/tmp/app.tar.gz \ "${BASE}/api/apps/<app>/deploy/archive"```
Every route is documented at `/api/docs`, with the OpenAPI 3.1 document at `/api/openapi.json`.
## Failure Handling
If a `deku` command cannot reach the daemon, `dekud` is stopped or listening somewhere else. Start or restart it, then run `deku doctor` to confirm the database, Docker, and proxy config are healthy.
If an app does not exist, create it with `deku apps create <app>`.
If a deploy fails, the deploy output names the failing step. Then:
- `deku deploy list <app>` shows whether the previous deployment is still `live`- `deku logs <app> -n 100` shows the container's own output- `deku doctor` rules out the host underneath it- Confirm config vars, domains, and process scale are correct
If a feature is missing, treat it as a precondition rather than assuming it is configured, and verify it:
```bashdeku objectstore info # object store, required for backupsdeku build-host info # build host, for offloaded buildsdeku letsencrypt status <app> # TLS certificates```
## What Not To Do
- Do not make `git push` the default deployment path- Do not use the dynamic plugin runtime for first-party workflows: it is compiled out by default, and HTTP lifecycle hooks are the supported integration point- Do not attempt broad unattended platform administration- Do not assume MCP exists today- Do not run interactive commands: `deku run` and `deku exec` do not attach a terminal
## Scope Today
Supported today:
- App create, inspect, and destroy- Config vars, domains, and ports- Deploy run, list, and rollback- Logs and process inspection- Runtime access with `deku run` and `deku exec`- Maintenance mode and redirects- Resource limits- Object-store and service backups, on demand and on a schedule- Host diagnostics with `deku doctor`- Managed Postgres, MySQL, MariaDB, Redis, and MongoDB services
Out of scope today:
- Plugin authoring with a dynamic `cdylib`- MCP implementation- Broad unattended platform administration
## MCP Later
The CLI and daemon HTTP API already cover the coding-agent workflow, so MCP is not required today.
Revisit MCP when external assistants without shell access need structured access to a stable subset: apps, deploy, config, domains, logs, and deployments. Leave dynamic plugin surfaces out of any first design.