Skip to content

Built for agents ​

A coding agent working in your repo needs what you need: the stack running, a way to restart one service, the logs, the right environment for a script. stackctl gives an agent the same tool you use, with an interface made for it.

PieceWhat the agent gets
Agent guidanceKnows when and how to use stackctl in this repo.
Headless modeRuns the stack without a terminal UI.
The control APIReads state and drives a running session over HTTP.
llms.txtThese docs as Markdown, on the web and inside the package.

What it looks like ​

Two real Claude Code conversations in the example workspace, replayed with their outputs folded as Claude Code folds them. The agent has the rules file and the skill stackctl offers to install, and nothing else.

The app is down. Someone restarted Postgres from another terminal, and the backend crashed. The agent finds who in the event log:

Running the tests. They call the backend, so the agent runs them against a test-mode session of their own:

Agent guidance ​

The first time you start a session in a terminal, stackctl asks once:

◆  Tell coding agents about stackctl in this repo? (a rules file and a skill under .claude/)
│  ● Yes / ○ No

Both are a few lines that say what stackctl runs here and point at the index inside the installed package, so an agent reads the page it needs, for the version you have. Without them an agent does what it would in any repo: kill whatever holds a port, run a bare docker compose, run the test script outside a session.

  • Nothing is installed unasked. A no is remembered, and an agent, a script or CI is never asked. stackctl init -y installs them from a script.
  • They stay current. A newer stackctl refreshes a copy you haven't edited.
  • For other agents, stackctl init --agents-md adds the same lines to AGENTS.md.

Headless mode ​

bash
stackctl --headless -s web

The same session as the terminal UI, without the UI: logs stream to stdout, and the process runs until it is told to quit. An agent runs it as a background task, waits for it on the control API, and stops it when done. See Start a stack.

For an e2e suite, startStack() gives the test runner a stack that ends with the test run.

The control API ​

Every session serves a localhost HTTP API. It answers the questions an agent would otherwise guess at:

bash
curl -s http://127.0.0.1:$port/query/status                           # what is running, and is it healthy
curl -sN http://127.0.0.1:$port/events                                # tell me when that changes
curl -s -X POST http://127.0.0.1:$port/command/service/restart/api    # restart one service

It works on a session you started too. An agent can restart the API in the terminal UI you have open, and you see it happen in your log:

16:41:22 [control ] [INFO] restart
16:41:22 [control ]   service: api

Every command that changes the stack, from a key, the control API or a stackctl command, is written to the mode's event log with who asked, and /events streams it. stackctl status shows the last ones, so an agent asked why something broke can see what was done to it, and by whom.

Without a session, stackctl show-config prints every service's resolved port and URL as JSON, so an agent never has to guess a port from a .env file.

llms.txt ​

The docs follow the llms.txt convention, generated from the same Markdown as this site:

URLWhat it is
https://stackctl.dev/llms.txtAn index: one line per page, with a description.
https://stackctl.dev/llms-full.txtEvery page in one file.
https://stackctl.dev/<page>.mdAny page as Markdown: add .md to its URL.

The same index and pages ship inside the npm package:

node_modules/stackctl/docs/llms.txt
node_modules/stackctl/docs/guide/…
node_modules/stackctl/docs/config/…

That copy matches the installed version, works offline, and is what the agent guidance points at. The index opens by sending an agent to the playbook, which has the rules and a recipe for each task.

Guard rails ​

An agent shares the machine with you, so stackctl draws a few lines:

  • An agent can't take over your session. Starting a second session in a mode quits the first. stackctl allows that between two agent-started sessions, and refuses it when a person started the running one. See Taking over a running session.
  • An agent can't leave a session behind. --detach is refused for an agent outside CI. A session an agent starts runs in its own background task and ends with it.
  • Graceful stops only. The playbook tells agents to stop and restart through the control API, never with kill.
  • Data is deleted only on request. infra reset and infra destroy are documented to agents as destructive.

stackctl recognizes an agent by the environment variables agents set (CLAUDECODE, CURSOR_AGENT, GEMINI_CLI, CODEX_SANDBOX, AGENT, …). A session reports it as startedByAgent on /query/status.

For the agent ​

The agent playbook is the page written for the agent itself: short recipes for the tasks above.

Released under the MIT License.