Save Research Notebook
napjon/krisk
Convert a completed data-analysis conversation into evidence-backed, reproducible living research through the Krisk MCP server.
Author and run CAO Python workflow scripts — multi-step, parameterized, fan-out orchestrations executed by cao workflow run.
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflow --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/cao-workflow .claude/skills/cao-workflow && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .claude/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflowType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflow --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/cao-workflow .agents/skills/cao-workflow && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .agents/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflow --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/cao-workflow .cursor/skills/cao-workflow && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .cursor/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/awslabs/cli-agent-orchestrator.git --path skills/cao-workflow--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflow --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/cao-workflow .gemini/skills/cao-workflow && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .gemini/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflowInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/cao-workflow .github/skills/cao-workflow && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .github/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install awslabs/cli-agent-orchestrator cao-workflow --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/awslabs/cli-agent-orchestrator.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/cao-workflow .opencode/skills/cao-workflow && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "cao-workflow" agent skill from https://github.com/awslabs/cli-agent-orchestrator/tree/main/skills/cao-workflow into .opencode/skills/cao-workflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cao-workflow", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
cao-workflowAuthor and run CAO Python workflow scripts — multi-step, parameterized, fan-out orchestrations executed by cao workflow run.
Cao Workflow is an agent skill from awslabs/cli-agent-orchestrator, published by the product's own GitHub organization. Author and run CAO Python workflow scripts — multi-step, parameterized, fan-out orchestrations executed by cao workflow run. Use when the user wants a repeatable multi-step job (e.g. data analysis over many files, a review pipeline, a parameterized batch). Authoring ends at a validated script file; running it is a separate, user-approved step.
Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Data & Analytics, covering Data analysis. It works with Python and Model Context Protocol. The repository describes itself as: Multi-agent orchestration for AI coding CLIs — Claude Code, Kiro, Codex, and more, coordinated in isolated tmux sessions. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit b29f40a. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Cao Workflow loads about 4.3k tokens when it runs. Until then it costs about 90 tokens; SKILL.md has 2,085 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from awslabs/cli-agent-orchestrator at commit b29f40a, republished under its Apache-2.0 licence (© awslabs). 2,085 words, ~4,278 tokens.
.claude/skills/cao-workflow/SKILL.md (or your agent's skills folder).A CAO workflow is a Python script you write, validate, and — only after asking the user —
run through cao workflow run. Each script drives one or more agent steps through CAO's
shared substrate, so you can fan work out across agents, collect their results, and resume a
run that was interrupted.
Your job as an author ends at a validated script file on disk. Authoring does NOT run the workflow. Never claim a workflow ran, or will run, when all you did was write it. Running is a separate step the user must approve (see Lifecycle step c).
Reach for this skill when the user asks to build or run a multi-step or parameterized workflow — for example:
reports/ and summarize the findings."If the work is a single one-off agent call, you don't need a workflow. Workflows earn their keep when there are multiple steps, fan-out, parameterization, or a need to resume.
Author scripts import from the cao_workflow package. This package runs only in the script
subprocess and imports nothing from cli_agent_orchestrator.* — it talks to CAO over HTTP.
Its public surface:
step(provider, agent, prompt, *, recovery, step_id=None, timeout=None, **opts) -> StepHandle —
run one agent step and declare what re-running it would mean. recovery is keyword-only
with no default, so omitting it is a TypeError at the call. See "Declaring a recovery
policy" below before you pick a value.run_step(provider, agent, prompt, *, step_id=None, timeout=None, **opts) -> StepHandle —
the same call, declaring no policy. That is the only difference between the two. A
recovery= passed to run_step lands in **opts; the server validates it, the shim does
not — see below.StepHandle has five fields: .step_id, .terminal_id, .output, .status, and
.replayed. .replayed qualifies .terminal_id. When it is True the server returned
a stored result and ran nothing, and .terminal_id is the ORIGINAL id — it names a terminal
that no longer exists. That flag is the only thing standing between you and reading,
writing to, or waiting on a dead id, so check it before you touch .terminal_id.get_inputs() -> dict — the run's resolved inputs (see Parameterized workflows). Returns
{} when nothing was declared; never raises on absence.emit_output(value) — print the run-level CAO_WORKFLOW_OUTPUT: sentinel (the run's return).ShimError (and ShimIdentityError, ShimTransportError, ShimHTTPError) — the failure
hierarchy step and run_step raise. Failures surface unchanged — the shim never
retries. A structured HTTP error with a non-empty string detail.kind prints as
run-step returned HTTP <status> (<kind>): <message> (without the message suffix when
absent); an unstructured error keeps the original run-step returned HTTP <status> text.recovery= is the author's claim about the step, and nothing more. CAO has no mechanism to
prove what a step does to the outside world, so it cannot and does not verify the claim. A
recovery policy DECLARES what re-running this step would mean; it never grants permission.
The three values, all of which are statements you are making, not protections you are getting:
| Value | What you are asserting |
|---|---|
"idempotent" | re-running this step has the same effect as running it once |
"reconcile" | re-running it needs a reconciliation step first (deferred — today CAO treats it exactly like idempotent) |
"manual" | do not decide this one without me — halt and ask |
"idempotent" grants nothing and protects nothing. It does not make a step safe to re-run;
it tells the resume gate that you believe it already is — and wherever the gate would otherwise
stop and ask a human, it re-executes the step on your word instead. Declare it on a step that
charges a card, sends mail, or files a ticket and CAO will charge the card again, exactly as
instructed. If you cannot show the step is safe to repeat, "manual" is the honest declaration.
Omitting a policy is a fourth, distinct state — it is never silently read as "manual". Use
run_step for it deliberately: an undeclared step still replays (replay executes nothing), but
where the alternative is re-execution it halts for a human.
recovery= on run_step is checked late, not never. run_step has no recovery
parameter, so the value rides **opts to the server, which stores it, lets the resume gate
honour it, and rejects an unknown value with a 422 — the route types that field as the
closed policy enum. What run_step lacks is step()'s client-side check, which refuses a bad
value before any HTTP attempt; on run_step a typo instead fails that step mid-run. Neither
surface has its value checked by validate (the linter sees the keyword, not its contents),
which is why validate reports the run_step form as unenforced-recovery-policy. Use
step() to declare, and run_step only to declare nothing.
Follow every step in order. No step may be skipped — validate is mandatory, and you must ask before running.
Write a .py file to ~/.aws/cli-agent-orchestrator/workflows/<name>.py. The workflow is
run by its stem (<name>), so:
.yaml sibling — a <name>.yaml next to <name>.py collides
on the run surface.cao workflow validate ~/.aws/cli-agent-orchestrator/workflows/<name>.pyFix every finding before proceeding — the lint findings are load-bearing, not style nits:
import cli_agent_orchestrator is banned. The script runs in a separate subprocess and
must reach CAO only over HTTP (the cao_workflow shim). Importing the server package breaks
that boundary.random / time / datetime / uuid warnings. Resume re-executes the script
top-to-bottom and replays journaled step results. Any nondeterministic value computed at
the top level will differ on replay and raise ReplayDivergenceError. Keep the script
deterministic: derive IDs from inputs, not from the clock or an RNG.missing-recovery-policy is a blocking ERROR. A step() call with no recovery=
keyword fails validation — the signature requires one and so does the linter. Two related
warnings fire without blocking: unverifiable-recovery-policy (a step() call passing
**kwargs, so the linter cannot see whether a policy is in there) and
unenforced-recovery-policy (a recovery= on run_step, which is honoured at resume and
validated by the server with a 422, but is not checked client-side before it is sent). See
"Declaring a recovery policy" above.The script tier executes generated Python. Never run a workflow without the user's explicit approval. Present the validated file and ask before doing anything in step d.
Announce the run-id before you start so the user can cancel it:
"Starting run kb-1 — cancel with cao workflow cancel kb-1."
Choose the invocation by how the run is triggered, because the two paths have very different client-side ceilings:
cao workflow run (CLI) uses a client socket timeout of ~8820s (~2.45h) — the CLI
itself won't give up early.workflow_run MCP tool is bounded by the MCP host's own per-tool-call timeout — a
host-dependent, much-shorter limit that can drop a long blocking call and lose its return
value even though the server run keeps going.So:
workflow_run MCP tool (blocking) and read the result directly.cao workflow run <name> --run-id <id> --json &cao workflow resume <run-id>Resume re-executes the script top-to-bottom — that is what step b's determinism warning is about — and the server decides each step call as it arrives. Never assume your top-level code does not re-run. Each step lands on one of three outcomes:
StepHandle.replayed is
True, and its .terminal_id names a terminal that no longer exists.A fourth outcome ends the whole run rather than one step: if the script changed at a step's key,
that step diverges and the run fails with ReplayDivergenceError. Deterministic scripts (see
step b) resume clean; nondeterministic ones diverge.
A halt reaches your script as a ShimHTTPError whose .status is 409 and whose .body names
kind: "decision_required", the step_id, and which condition halted it; str(exc) now shows
(decision_required) and the message too. A step halts when its outcome is genuinely unknown or
unverifiable: it was dispatched and never settled and no declared policy permits re-execution; its
stored result is unreadable; its recorded provenance cannot be verified under the current scheme;
or its author declared recovery="manual" and asked to see it.
Resolve it by naming a decision per halted step and resuming again:
cao workflow resume <run-id> --decide <step_id>=rerun # re-execute that step
cao workflow resume <run-id> --decide <step_id>=skip # accept its stored result--decide is repeatable, one per halted step.
A decision authorises exactly ONE attempt. If that attempt crashes before it settles, the
next resume asks again rather than re-executing on the old consent. Consent does not carry
forward — never present one rerun to a user as standing authorisation for later resumes.
Do not let a blanket except ShimError swallow a halt (see R4): ShimHTTPError is a
ShimError, so a catch-all around a step absorbs the 409 and the run finishes with a sentinel
where a human decision was required. Re-raise when .status == 409.
Instead of editing a constant per run, declare inputs once and pass values at invocation time.
Add a module-level INPUTS dict and read the resolved values at runtime with
get_inputs():
from cao_workflow import get_inputs
INPUTS = {
"target_dir": {"type": "path", "required": True},
"max_files": {"type": "int", "required": False, "default": 20},
"verbose": {"type": "bool", "required": False, "default": False},
}
inputs = get_inputs()
target_dir = inputs["target_dir"]
max_files = inputs.get("max_files", 20)Each entry declares type (string | int | bool | path), required, and an optional
default. This makes one authored script reusable — "author once, invoke with inputs."
These rules are load-bearing. Each is paired with the reason it exists.
To run steps concurrently, use a ThreadPoolExecutor and give every concurrent run_step an
explicit, stable step_id. The sequential call-N counter fallback is race-free but not
deterministic across runs under concurrent scheduling — so resume would replay the wrong
results. Iterate over sorted() inputs so the mapping from item → step_id is stable.
Default max_workers=2 for claude_code (measured: 4 starved the heaviest lens). Expose it as
a tunable input; higher values are fine when steps are light.
Inputs are journaled in plaintext and replayed on resume. Never pass a literal secret (token, key, password) as an input. Pass a name/reference and resolve the actual secret at step time (env var, secrets manager) inside the step.
Only write-capable roles (e.g. developer) should be told to write files. A read-only
role (e.g. reviewer) instructed to write will hang the full step budget waiting on a
permission it can't get. Read-only steps must READ their inputs and RETURN findings inline.
Catch ShimError inside each fan-out unit so one step's timeout degrades to a survivor set
rather than failing the whole run with a 504. Return a sentinel/None for the failed unit and
let the aggregate proceed.
But do not swallow a halt or a divergence. ShimHTTPError is a ShimError, so the same
catch also absorbs the 409 a resume raises when a step halts or diverges — and the run then
completes with a sentinel in place of a result a human was supposed to decide on. Re-raise when
.status == 409 (see Resolving a halt).
For large results, have the step write to a file and return the path — don't return
megabytes inline. Per-step output is null for schema-less steps; the files (and the aggregate
you build) are the source of truth.
Prefer claude_code as the step provider. kiro_cli currently launches an interactive TUI
that hangs run_step. This is interim guidance — a kiro mitigation is a tracked follow-up,
not a permanent verdict — but until it lands, use a headless provider.
The runtime journal is the primary truth for progress and UI — it reflects what actually ran. A static script→YAML preview is optional and lossy; never treat it as the truth source and never author against it.
If you lack write permission (you can't create the .py file), hand off authoring to a
developer agent, and pass this skill's name (cao-workflow) in the handoff message so the
developer follows the same lifecycle.
ShimErrors and non-zero validate findings; don't paper
over them.A script that summarizes each file in a directory concurrently, with a stable step_id per
file, per-unit fault tolerance, and results written to disk:
"""summarize_dir — fan out a summary step over every file in target_dir."""
import os
from concurrent.futures import ThreadPoolExecutor
from cao_workflow import run_step, emit_output, get_inputs, ShimError
# Parameterized: author once, invoke with different inputs.
INPUTS = {
"target_dir": {"type": "path", "required": True},
"max_workers": {"type": "int", "required": False, "default": 2},
}
inputs = get_inputs()
target_dir = inputs["target_dir"]
max_workers = inputs.get("max_workers", 2)
# sorted() → the item→step_id mapping is stable across runs (R1 determinism).
files = sorted(
name for name in os.listdir(target_dir)
if os.path.isfile(os.path.join(target_dir, name))
)
def summarize(filename: str):
path = os.path.join(target_dir, filename)
try:
# Explicit, STABLE step_id per concurrent call (R1). Read-only role
# RETURNS its summary inline (R3) — it does not write files.
handle = run_step(
provider="claude_code", # headless (R5)
agent="reviewer",
prompt=f"Summarize the file at {path} in 3 bullet points. Return the summary only.",
step_id=f"summarize:{filename}",
)
return filename, handle.output
except ShimError as exc:
# Per-unit tolerance (R4): one timeout degrades to a survivor, not a 504.
return filename, f"ERROR: {exc}"
with ThreadPoolExecutor(max_workers=max_workers) as pool:
results = dict(pool.map(summarize, files))
# Big output → write to a file, return the path (big-outputs discipline).
out_path = os.path.join(target_dir, "_summaries.json")
with open(out_path, "w") as fh:
import json
json.dump(results, fh, indent=2)
emit_output({"summarized": len(results), "output_file": out_path})Validate it, ask the user, then run with a pre-announced run-id:
cao workflow validate ~/.aws/cli-agent-orchestrator/workflows/summarize_dir.py
# fix findings, then — after the user approves:
cao workflow run summarize_dir --run-id sum-1 --json &© awslabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/cao-workflow of awslabs/cli-agent-orchestrator.
Open the folder on GitHubat commit b29f40a
Cao Workflow next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Cao Workflow this skillawslabs/cli-agent-orchestrator | 1.4k | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| Save Research Notebooknapjon/krisk | 118 | — | ~702 | Automated safety check: Pass | BSD-3-Clause | |
| Querying Indonesian Gov Datasuryast/indonesia-gov-apis | 172 | — | ~997 | Automated safety check: Pass | MIT | |
| Openbb Data Fetchermonarchjuno/vibe-investing | 299 | — | ~2.9k | Automated safety check: Notes | MIT | |
| Diagnosekbanc85/claudia | 296 | — | ~1.8k | Automated safety check: Pass | Custom licence | |
| Scraplingforyourhealth111-pixel/Vibe-Skills | 3.6k | — | ~1.1k | Automated safety check: Pass | Apache-2.0 |
napjon/krisk
Convert a completed data-analysis conversation into evidence-backed, reproducible living research through the Krisk MCP server.
suryast/indonesia-gov-apis
Query 57 Indonesian government APIs and data sources — BPJPH halal certification, BPOM food safety, OJK financial legality, BPS statistics, BMKG weather/earthquakes, Bank Indonesia exchange rates…
monarchjuno/vibe-investing
Fetch financial, market, economic, fundamental, news, options, crypto, ETF, index, and macro data through the OpenBB Python interface instead of the OpenBB MCP server.
kbanc85/claudia
Check memory system health and troubleshoot connectivity issues.
foryourhealth111-pixel/Vibe-Skills
CLI-first web scraping & content extraction with optional MCP server.
SCStelz/security-investigator
A skill your agent uses when asked to write, create, or help with KQL (Kusto Query Language) queries for Microsoft Sentinel, Defender XDR, or Azure Data Explorer.
awslabs/cli-agent-orchestrator
Enable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman).
awslabs/cli-agent-orchestrator
Author live dashboard UI from an agent via the emitui MCP tool.
awslabs/cli-agent-orchestrator
Load the official MCP Apps builder skills (create-mcp-app, migrate-oai-app, add-app-to-server, convert-web-app) from github.com/modelcontextprotocol/ext-apps.
awslabs/cli-agent-orchestrator
Create a new CAO (CLI Agent Orchestrator) plugin. An agent skill from awslabs/cli-agent-orchestrator.
awslabs/cli-agent-orchestrator
Create a new CLI agent provider for CAO (CLI Agent Orchestrator).
awslabs/cli-agent-orchestrator
Find and select the best installed CAO agent profile for a task before delegating with assign or handoff.
Works with
Categories
Author and run CAO Python workflow scripts — multi-step, parameterized, fan-out orchestrations executed by cao workflow run. Cao Workflow is an agent skill from awslabs/cli-agent-orchestrator, published by the product's own GitHub organization. Author and run CAO Python workflow scripts — multi-step, parameterized, fan-out orchestrations executed by cao workflow run.
Cao Workflow fits situations like: the user wants a repeatable multi-step job (e.g; tasks that involve Data analysis.
Run `npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a claude-code`. Or copy the skill folder (skills/cao-workflow in awslabs/cli-agent-orchestrator) into .claude/skills/cao-workflow in your project. Claude Code loads it when a task matches its description.
Run `npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a codex`. Or copy the skill folder (skills/cao-workflow in awslabs/cli-agent-orchestrator) into .agents/skills/cao-workflow in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add awslabs/cli-agent-orchestrator --skill cao-workflow -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cao-workflow, .gemini/skills/cao-workflow, .github/skills/cao-workflow and .opencode/skills/cao-workflow in your project.
SKILL.md names no scripts, command-line tools or credentials: Cao Workflow is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Cao Workflow is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.3k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Cao Workflow: Save Research Notebook (napjon/krisk, 118 stars), Querying Indonesian Gov Data (suryast/indonesia-gov-apis, 172 stars), Openbb Data Fetcher (monarchjuno/vibe-investing, 299 stars) and Diagnose (kbanc85/claudia, 296 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
awslabs (a GitHub organization, an official publisher) maintains it in awslabs/cli-agent-orchestrator, which has 1,396 GitHub stars. The repository holds 14 skills in this directory. The repository was last updated on October 8, 2026.
Source: awslabs/cli-agent-orchestrator on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.