Headless mode lets you run Kiro CLI as part of your CI/CD pipeline to automate code reviews, generate tests, or troubleshoot build failures — no interactive terminal required. Authenticate with an API key, pass a prompt, and Kiro executes it end-to-end.
Headless mode requires an API key set as the KIRO_API_KEY environment variable. If you haven't created one yet, follow the steps in Generate an API key.
For details on authentication precedence and checking your active credentials, see Authentication.
Pass --no-interactive with your initial instruction. The instruction can be a positional argument or supplied through piped stdin. When stdin is piped and no positional argument is given, Kiro reads the full stream as the instruction. A local headless run that names no harness runs V2, with the exceptions listed under Scripts and CI; add --v3 or --v2 so the run does not depend on the default.
# Positional argument kiro-cli chat --no-interactive "your prompt here" # Stdin only: pipe the entire instruction printf '%s\n' "your prompt here" | kiro-cli chat --no-interactive
Since there is no user to approve tool calls, local V3 sessions can use --trust-all-tools for session-wide approval or --trust-tools with exact internal tool IDs. Use scoped permissions.yaml rules for reusable capability policies. CLI 2.x uses its own tool names with --trust-tools.
# V3: trust all tools for this session kiro-cli chat --v3 --no-interactive --trust-all-tools "Write tests for the auth module and run them" # V3: trust only the exact tools needed kiro-cli chat --v3 --no-interactive --trust-tools=read_file,grep_search "Find all TODO comments in src/"
In V3, a sub-agent's tool call runs without approval only when the parent session's policy also allows it. Otherwise the call needs approval, so a headless run denies it with this error:
[denied] tool permission approval is not supported in non-interactive mode. Use --trust-all-tools to auto-approve.
Adding the sub-agent to trustedAgents doesn't change this. Add the sub-agent's allow rules to the parent agent's permissions.rules or to permissions.yaml, or use --trust-all-tools. See Sub-agent permissions.
In Kiro CLI 2.33 or later, a first message that starts with @<prompt-name> runs that prompt instead of sending the text as typed, both in an interactive session and with --no-interactive. The name matches a workspace, global, or MCP prompt, case-insensitively; @agent-sop:<name> runs the named SOP. Text after the name becomes the prompt's arguments. Before 2.33, a first message that named a prompt from an MCP server still starting was sent as typed.
kiro-cli chat --agent <agent> --no-interactive "@agent-sop:<name> Payments eu-west-1"
Kiro waits for the MCP servers that serve prompts to finish starting, up to 30 seconds by default, before it decides. A name that no prompt matches once every server has started is sent as typed. A path-like mention such as @src/main.rs stays a file reference. To confirm the SOP is available to the agent, start an interactive session with the same --agent and run /prompts list; the SOP appears under its agent-sop: name.
Starting with Kiro CLI 2.27.1, V3 non-interactive runs load Hooks from the selected agent and workspace. PreToolUse Hooks run before a tool call and can deny it. See Hooks for supported triggers and actions.
--trust-all-tools approves Hook confirmation requests automatically. --trust-tools cannot, because a Hook request is not tied to a tool ID. Without --trust-all-tools, Kiro denies it. A Hook that blocks is final under either flag. For automation, write Hooks that return a final allow or deny decision.
V3 non-interactive runs enable knowledge and code intelligence by default. Set chat.enableKnowledge or chat.enableCodeIntelligence to false to turn either tool off. See Built-in tools and the settings reference.
Kiro CLI 2.31.1 and later applies saved compaction and Tool Search settings to V3 non-interactive runs.
| Purpose | Settings |
|---|---|
| Automatic compaction | chat.disableAutoCompaction, compaction.excludeMessages, compaction.excludeContextWindowPercent |
| Tool Search | toolSearch.enabled, toolSearch.minPct, toolSearch.minTokens |
To apply saved Tool Search thresholds, also save toolSearch.enabled true.
Save values with kiro-cli settings, as you do for interactive sessions:
kiro-cli settings compaction.excludeMessages 4 kiro-cli settings toolSearch.enabled true
If a headless run behaves differently after upgrading, run kiro-cli settings list to find saved compaction.* or toolSearch.* values. Remove an unwanted global value with kiro-cli settings --delete <name>. For a value marked (workspace), add --workspace after settings. Removing a value also affects interactive sessions.
See Compaction, Tool Search, and the settings reference for each setting.
Kiro CLI 2.31 and later V3 headless runs read global and project sandbox.json settings. When the resolved settings have enabled: true, Kiro requests sandboxing without an extra flag. If Kiro cannot activate the sandbox, the run warns and continues without sandboxing. If requested MCP wrapping fails, sandboxed commands stay protected, but the affected MCP servers do not.
Add --sandbox when your script must stop instead of continuing without all requested protection:
kiro-cli chat --v3 --sandbox --no-interactive "Run the test suite"
The run exits before the task starts when the sandbox cannot activate. It also exits when mcpSandboxing is enabled but local MCP servers cannot be wrapped. See Local command sandbox for platform setup, configuration, and recovery.
name: Kiro Code Review on: [pull_request] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Kiro CLI run: curl -fsSL https://cli.kiro.dev/install | bash - name: Review PR changes env: KIRO_API_KEY: ${{ secrets.KIRO_API_KEY }} run: kiro-cli chat --v3 --no-interactive --trust-tools=read_file,grep_search "Review the changes in this PR for security issues"
# Generate and run tests kiro-cli chat --v3 --no-interactive --trust-all-tools "Write tests for the auth module and run them" # Troubleshoot a failing build with the full instruction on stdin { printf '%s\n\n' "Explain this build failure and suggest a fix:" cat build-error.log } | kiro-cli chat --v3 --no-interactive --trust-tools=read_file
Use --require-mcp-startup when a non-interactive run depends on MCP tools. V2 and V3 wait for configured MCP servers before submitting the instruction. In V3, Kiro exits with code 3 if a server fails, its startup state cannot be determined, or it does not report a status within 30 seconds. Without the flag, Kiro logs MCP startup problems and continues. See exit codes for handling failures in scripts.
Pass --agent <name> to run a non-interactive command with a specific agent. Without --agent, a fresh V3 run uses chat.defaultAgent when configured. If no default is configured, it uses the built-in default. Without an explicit model, a new V3 run applies chat.defaultModel when configured; a selected agent that specifies a model can override it. V2 resolves its default agent and model internally.
kiro-cli settings chat.defaultAgent my-project-agent kiro-cli chat --v3 --no-interactive "Write tests for the auth module" # runs on my-project-agent
Pass --model <id> to pin the model for a run. On V2 and V3, an explicit value overrides the selected agent's configured model; on V3, it also overrides chat.defaultModel, and on V2, it overrides a resumed session's saved model. V2 trims surrounding whitespace before passing an unlisted, non-empty ID to the backend; a blank value sends no override and leaves the current model selection unchanged. Without --model, a resumed session keeps its original agent and model.
Pass --effort <level> to set the reasoning effort for a non-interactive run. Supported levels depend on the selected model. In V3, the flag applies only to the session Kiro starts and does not change the saved per-model default.
Pass --output-format stream-json to receive run events as JSON Lines on stdout. Each line is a self-contained JSON object, making the output easier to process in scripts, logging pipelines, and CI jobs than formatted text.
kiro-cli chat --v3 --no-interactive --trust-all-tools --output-format stream-json "Summarize open TODOs in src/"
--output-format stream-json requires V2 or V3 (--agent-engine v2 or --agent-engine v3).
In V3, an interrupted non-interactive run writes a final interruption record to stream-json. Treat that final record as the end of the interrupted run instead of waiting for another completion record.
If your instruction starts a workflow and the turn ends before it settles, a non-interactive V3 run waits for it before exiting. The default timeout is six hours.
Override the timeout with the KIRO_HEADLESS_WORKFLOW_TIMEOUT_SECS environment variable, in seconds:
# Wait up to 10 minutes for workflows to settle KIRO_HEADLESS_WORKFLOW_TIMEOUT_SECS=600 kiro-cli chat --v3 --no-interactive "Run the release-check workflow"
The value must be a positive whole number of seconds no greater than the six-hour default. An invalid, zero, or over-cap value falls back silently to the six-hour default rather than erroring.
Each workflow's progress is written to the run's output as it happens. When a workflow finishes, it reports one of these outcomes:
| Outcome | Meaning |
|---|---|
completed | The workflow finished successfully. |
failed | The workflow ended in a failure state. |
aborted | The workflow was stopped before completion. |
paused | The workflow is waiting at a pause point. |
| (unknown status) | Kiro couldn't determine the workflow's final state. |
If a workflow doesn't finish within the timeout, the run reports workflow run incomplete (<outcomes>) with a recovery hint. It does not report plain success.
Kiro CLI V3 can start a cloud session interactively or non-interactively. Add --cloud to run the task in a managed cloud sandbox, and --repo to start with one or more repositories.
kiro-cli --cloud --repo owner/repository kiro-cli chat --v3 --no-interactive --cloud --repo owner/repository "Review the open pull request"
For every cloud-session flag, the startup flow, repository setup, output, resume and delete behavior, and what differs from local sessions, see Cloud sessions.
Plain-text runs explain when a turn was cancelled or refused. They also print why a session could not be created or resumed. A failed tool call includes its error message when one is available. If stdout closes before completion, Kiro exits with a nonzero status instead of finishing the turn.
| Flag | Description |
|---|---|
--no-interactive | Run without an interactive session. Requires a non-empty instruction, either as a positional argument or via piped stdin |
--cloud | Run the V3 task in a cloud session |
--repo <owner/repository> | Add one or more comma-separated repositories to a V3 cloud session |
--resume-id <ID> | Resume a local or cloud session by ID |
--agent <name> | Run with a specific agent. When omitted, a fresh V3 run uses chat.defaultAgent when configured, or the built-in default otherwise |
--model <id> | Pin the model for the run. Takes precedence over a model named in the agent configuration and, on V3, over chat.defaultModel |
--effort <level> | Set reasoning effort for the run when the selected model supports it |
--agent-engine <v1|v2|v3> | Select the agent harness version. Shorthand flags --v2 and --v3 are also accepted. In Kiro CLI 3.0.0 or later, a headless run that names no harness uses V2, with the exceptions under Scripts and CI |
--output-format stream-json | Emit run events as JSON Lines on stdout for programmatic use (V2/V3 only) |
--trust-all-tools | Auto-approve all tool calls without prompting |
--trust-tools=<tool-ids> | Non-interactive V3: auto-approve exact internal tool IDs. CLI 2.x accepts its own tool names. Ignored by interactive V3 |
--sandbox | Require the local command sandbox and exit if protection cannot start |
--require-mcp-startup | Wait for required MCP servers and exit with code 3 if startup fails |
Environment variables
| Variable | Description |
|---|---|
KIRO_API_KEY | API key used for headless authentication |
KIRO_HEADLESS_WORKFLOW_TIMEOUT_SECS | Seconds a non-interactive V3 run waits for in-flight workflows to settle before exiting. Default: 21600 (six hours). Invalid, zero, or over-cap values fall back to the default |
- Store
KIRO_API_KEYas a secret in your CI/CD platform — never hardcode it in pipeline configs or commit it to source control. - Name the harness with
--v2or--v3in every headless command, so the run does not change harness when you add or remove--trust-all-tools. - In local headless V3 sessions, prefer
--trust-toolswith exact internal tool IDs over--trust-all-tools. Use scopedpermissions.yamlallow rules when the policy should be reusable. - Add
--require-mcp-startupwhen your pipeline depends on MCP servers, so the task stops before it begins instead of running without the expected tools. - When using V2 or V3, supply your instruction as a positional argument or pipe it through stdin, but not both. V2 and V3 only read stdin when no positional argument is present.
- Check exit codes in your pipeline to handle failures gracefully.
- Rotate API keys regularly and revoke any that are no longer in use from the Kiro portal.
- You must provide a non-empty initial instruction, either as a positional argument or through piped stdin.
- No mid-session user input is possible.
- Interactive slash commands (
/modelpicker,/agentpicker) are not available. - Terminal UI features are disabled.
- Authentication — API key setup and authentication methods
- Exit codes — Handle failures in scripts
- CLI commands — Full CLI flag reference
Headless mode