Ask Cargo
One agent the whole team @mentions in Slack, sitting on top of your GTM repo and workspace: it answers from context, cadence and live runs, turns change requests into pull requests, captures a thread worth keeping into the cadence log and context, and hands work to the other deployed agents only after a go in the thread.
Set up the ask-cargo cookbook in this project.
1. If the Cargo CLI is not installed yet, follow every step in https://api.getcargo.io/INSTALL.md
2. From the Cargo project, run: cargo-ai cdk add cookbook/ask-cargo
3. Then follow .claude/skills/ask-cargo/SKILL.md. Stop for my approval before any paid call, and stop at "cargo-ai project plan" before deploying anything.$cargo-ai cdk add cookbook/ask-cargoSay this to your agent
Put one agent in our #gtm Slack channel that answers from this repo, opens a pull request for any edit, and runs nothing until someone says go.
Illustrative output #
Fictional records, to show the shape of what comes back.
#gtm
Dana: @Cargo add Globex to our competitors, they keep showing up in fintech deals
Cargo: Opened https://github.com/northwind-example/gtm/pull/212 on branch ask-cargo/add-globex-competitor.
• Adds Globex to context/ competitors with the fintech positioning from this thread
• `cargo-ai cdk check` passes; nothing under infra/ changed
Want a battlecard section too? Reply @Cargo with what to add.
Dana: @Cargo also note they undercut on price for teams under 50 seats
Cargo: Pushed a second commit to the same pull request (#212): pricing note added.
Review and merge it when it reads right; I never merge.
One thread became one reviewable pull request with two commits; a request that spends, such as
re-scoring an account, would instead get a proposal with its live price and wait for @Cargo go.
Done when #
node --import tsx evals/contract.mjspasses: harness isclaudeCodeon an Anthropic connector, one Slack trigger onallChannels, nothing onuses, no capabilitycargo-ai cdk planreports the agent, the three connectors and the folder- a question in a channel the bot is in (“what is our ICP?”) got an answer in the thread that cites a file under
context/ - a question about the workspace (“what failed yesterday?”) cites the
cargo-aicommand it ran; a read that errored says so instead of a number - a change request opened exactly one unmerged pull request, and a follow-up in the same thread added a commit to it rather than opening a second
- a request that spends replied with a proposal and a live price and ran nothing; the same request ran only after
@Cargo go - a request an installed agent owns was handed to it with
cargo-ai ai message create, and the reply names the chat or pull request it produced - a mention in a channel another agent lists got that agent’s reply, not this one’s
- “@Cargo capture this” in an internal thread wrote
cadence/log/raw/slack/andcadence/log/slack/files with the thread’ssource:line on the thread’s pull request, reacted :white_check_mark:, and replied with the entry path and the pull request; a second mention with no new replies wrote nothing; the same request in a shared channel was refused - every mention produced exactly one reply, and no reply contains a
<@…>mention
What it costs #
Every turn is a harness run: a sandbox, a clone of the repository, and LLM tokens billed through the
bound Anthropic connector. A turn that only answers a question costs tokens and nothing else. The
read-only cargo-ai calls are API calls, not connector actions, and bill nothing.
What spends is what someone approves with a go: the connector actions, batches and agent handoffs in
§3 of the prompt. The agent reads each price live (cargo-ai connection integration get <slug>) and
says the total before it asks for the go, so the proposal is the cost line. Nothing runs on a
schedule.
One agent the whole team @mentions in Slack, on top of the GTM repository and the workspace it deploys. It answers from what is written and what actually ran, turns change requests into pull requests, and hands work to the agents that own it, but only after someone in the thread says go. A Claude Code harness agent with a Slack connector trigger; nothing else is deployed.
What it does #
- Answers. Reads
context/,cadence/,infra/and read-onlycargo-aicalls (runs, batches, usage, what is deployed), and cites the file or command behind every answer. - Changes. Edits the repository on a branch and replies with the pull request. One thread is one pull request; a follow-up adds a commit. It never merges and never deploys.
- Runs, on a go. Proposes what will run, over how many records, at the live price, and waits for
@Cargo goin the thread. Batches over 25 records run a sample of 5 first. - Captures. “@Cargo capture this” turns the thread into a raw capture and a log entry under
cadence/log/slack/, and promotes a claim intocontext/only once it repeats across calls and threads, on the thread’s pull request. It reads only that thread (getThread), and refuses shared channels and DMs. - Hands off. When a deployed agent owns the job (standup, weekly planning, the account scorer), it
messages that agent with
cargo-ai ai message createinstead of redoing the work.
How it works #
- Someone @mentions the bot in any channel it is in. The Slack trigger opens one chat per thread (keyed on the channel and the thread’s first message) and marks the thread “is working…”.
- The harness clones the repository, resolved from the checkout’s git origin at deploy.
- The agent reads, then either answers, opens or updates the thread’s pull request, or replies with a proposal ending in the exact text to type to approve it.
- The platform streams the final text into the thread. The agent posts nothing itself.
- A follow-up @mention in the same thread lands in the same chat, so the agent sees its own proposal and the go together.
Adds 5 resources.
| File | Resource | Role |
|---|---|---|
infra/agents/ask-cargo.ts | defineAgent (claudeCode) | the Slack trigger, repository binding, model |
infra/agents/ask-cargo.prompt.ts | (not a resource) | the rules: what it reads, changes, and waits for a go on |
infra/connectors/slack.ts | defineConnector (slack) | the trigger; the platform replies through it |
infra/connectors/git.ts | defineConnector (github) | the clone, branch, push and pull request path |
infra/connectors/anthropic.ts | defineConnector (anthropic) | the model the harness runs on, billed and metered |
infra/folders/index.ts | defineFolder | the workspace folder this cookbook’s agent is filed in |
references/roster.md | (not a resource) | which deployed agent owns which job |
references/capture-entry.md | (not a resource) | what a capture writes, and how a re-mention is handled |
Why a trigger and not a Slack bot #
A Slack connector trigger already is the bot. It acknowledges Slack inside the three-second window, de-duplicates retries, keeps one chat per thread, shows a working status, streams the answer back, and gives the thread a stop button. Everything a hand-built bot would need a worker, a token and a queue for is platform behaviour here. The cost is what the trigger does not do, and the design is shaped around those gaps:
- Only @mentions wake it, follow-ups included, and a mention sent mid-turn is dropped. So the
confirmation is itself a mention (
@Cargo go), and every reply that needs one says so. - The model is not told who wrote a message. Multiplayer means anyone in the thread can steer and approve; it does not mean the agent knows who they are. Pull requests quote the request and name no one.
- The trigger adds Slack tools with no channel lock (
postMessage, history, thread, reactions). The prompt forbids them, except reading and reacting to the summoning thread during a capture: a new chat only receives the mention and the thread’s first message, so a capture has to read the replies itself. The reply is still the final text, in the thread it was asked in.
Why the CLI for handoffs, not uses #
uses accepts other agents, and a sub-agent there would be the obvious way to build an
orchestrator. It is the wrong one here for two reasons. A handle on uses imports another cookbook’s
file, which breaks the isolation that lets a customer install exactly one cookbook. And it freezes
the roster at deploy: the agent could only reach the agents that existed when it shipped. From the
sandbox, cargo-ai ai agent list sees what the workspace runs today, and ai message create sits
behind the same go as every other action, which a sub-agent tool call would skip.
Why not the built-in Master Agent #
Workspaces ship a read-only Master Agent that answers from context and models and can run actions.
If that is all the team needs, put a Slack trigger on it and skip this cookbook (master-agent-slack
in SKILL.md). Ask Cargo is for what needs a checkout: reading what is declared in infra/,
answering from the cadence log, and turning a Slack message into a diff someone reviews.
Placeholders (edit before deploy) #
- Where the bot is — the trigger is
allChannels, so the agent answers in every channel the bot has been invited to. Keep it out of customer shared channels, or switch tochannelIds. languageModel—infra/agents/ask-cargo.ts: any Anthropic model the workspace’s connector can reach.references/roster.md— the agents your workspace runs, fromcargo-ai ai agent list.
What it does not do #
It does not deploy, merge, destroy or remove anything, mint tokens, change members, post to any channel but the thread it was asked in, send to people the workspace has no consent basis for, or run anything that spends without a go in the thread.