-
-
Notifications
You must be signed in to change notification settings - Fork 2
Unattended Mode
Coyote supports two unattended operation modes for scripting and programmatic use:
-
--headlesssuppresses all interactive prompts and runs as a non-interactive CLI process. -
--acp-serverexposes a full agent server over stdio using JSON-RPC 2.0, suitable for host-side orchestration. It implies--headless.
The --headless flag runs Coyote in fully unattended mode. It is designed for use in scripts, CI pipelines, and
sandboxed environments where no user is present to respond to prompts.
When --headless is active:
- All interactive prompts (confirmations, selections, free-text inputs) return structured JSON instead of blocking.
-
AUTO_CONFIRM=trueis set for the process and all spawned tools. - REPL mode is not supported; a prompt must be provided via
-f <file>or as an inline argument.
coyote --headless -f prompt.txt
coyote --headless "Summarize this project for me"User-interaction tool calls (e.g. user__confirm, user__select) return a structured JSON object instead of prompting.
The response shape matches the tool's normal output, so agents handle it transparently.
--acp-server starts Coyote as an ACP agent server over stdio. It is designed for host applications that need to drive
Coyote programmatically — the host sends JSON-RPC requests over stdin and reads JSON-RPC responses from stdout.
Every byte on stdout is a valid JSON-RPC 2.0 frame. Diagnostic logs go to stderr (or to the log file if COYOTE_LOG_FILE
is configured). The flag implies --headless.
coyote --acp-serverAll normal context flags work alongside --acp-server and are applied before the server starts listening:
coyote --acp-server --role diagnose
coyote --acp-server --agent sisyphus
coyote --acp-server --rag my-index --no-memory
coyote --acp-server --model gpt-4oThe server then inherits the fully-configured context — the client manages sessions via session/new / session/load
as normal.
Each request and response is a single JSON object on one line, terminated by \n. Send requests line-by-line; the
server processes them sequentially and writes a response (or nothing, for notifications) before reading the next line.
Request:
{"jsonrpc": "2.0", "id": 1, "method": "method/name", "params": {...}}Success response:
{"jsonrpc": "2.0", "id": 1, "result": {...}}Error response:
{"jsonrpc": "2.0", "id": 1, "error": {"code": -32601, "message": "Method not found: ..."}}| Method | Params | Result | Notes |
|---|---|---|---|
initialize |
none | {name, version, protocolVersion} |
Returns server identity. Call this first. |
session/new |
none | {sessionId: "default"} |
Starts a new temporary session. Only one session per process. |
session/load |
{sessionId: "<name>"} |
{sessionId: "<name>"} |
Loads a previously saved session by name (as shown in coyote --list-sessions). |
session/prompt |
{text: "<prompt>"} |
{output, stopReason} |
Runs one conversation turn. Requires an active session. |
session/cancel |
none (notification) |
{} if an id was given, else no response |
Sets the abort flag for the next call. See Known Limitations. |
The server may emit notifications (messages without an id) between a request and its response.
| Notification | Params | When |
|---|---|---|
session/request_permission |
{action, question, options} |
Emitted when a tool triggers a user-interaction call (e.g. user__confirm, user__select). Sent before the turn's final response. |
| Code | Meaning |
|---|---|
-32700 |
Parse error — request line was not valid JSON |
-32601 |
Method not found |
-32602 |
Invalid params — a required field is missing |
-32600 |
Invalid request — e.g. session/prompt before session/new
|
-32000 |
Application error — e.g. no active session, session already active |
Build the binary first (cargo build), then use a heredoc to send multiple requests:
Structural test (no LLM required):
./target/debug/coyote --acp-server << 'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"unknown/method","params":{}}
EOFExpected: initialize succeeds, then -32601 method-not-found.
Parse error recovery:
./target/debug/coyote --acp-server << 'EOF'
not valid json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
EOFExpected: -32700 for the bad line, then a valid initialize response. The server continues processing after a parse
error.
Full session (requires a configured model):
coyote --acp-server << 'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"session/new","params":{}}
{"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{"text":"Reply with the single word: pong"}}
EOFMulti-turn context:
coyote --acp-server << 'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"session/new","params":{}}
{"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{"text":"Count to 3 and stop."}}
{"jsonrpc":"2.0","id":4,"method":"session/prompt","params":{"text":"What was the last number you said?"}}
EOFid=4 should answer "3", confirming session history threads across turns.
Load a saved session:
coyote --acp-server << 'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
{"jsonrpc":"2.0","id":2,"method":"session/load","params":{"sessionId":"my-saved-session"}}
{"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{"text":"Summarize what we've discussed."}}
EOFsession/cancel cannot interrupt a running session/prompt. The server processes requests sequentially. While a
session/prompt turn is executing, the server is not reading stdin. session/cancel sets an abort flag that takes
effect on the next invocation.
session/request_permission notifications are post-turn. They are emitted immediately before the turn's final
response, not mid-stream. A real-time permission bridge would require a concurrent server design.
The embedded sbx kit ships a headless profile for running Coyote in unattended mode inside a sandbox. Set
COYOTE_PROMPT_FILE to the path of a prompt file before launching:
export COYOTE_PROMPT_FILE=/path/to/prompt.txt
sbx run coyote --profile headlessThe headless profile passes --headless -f "${COYOTE_PROMPT_FILE}" to Coyote and sets COYOTE_LOG_LEVEL=WARN to
reduce noise on stderr. For ACP use inside a sandbox, override the entrypoint directly via sbx run --entrypoint.