Tutorial: running Cognition Protocols over AgentBridge¶
Agents on separate processes, joined by AgentBridge
AgentBridge (agentbridge
and shadictl, from the
agntcy/shadi repository) registers each coding harness instance as a live agent and lets
one instance send a prompt to another with agentbridge delegate. Agents talk
A2A, either natively or over a SLIM
message bus. It is used purely as process launcher and transport: the protocol is unchanged,
and the initiator uses agentbridge delegate as its delegation primitive, where an in-process
orchestrator would use its sub-agent tool.
Any Cognition Protocol can run this way, on any team of agents. The tutorial describes the steps to run one: independent coding-harness processes, one initiator and one per specialist. It uses the SLIM transport; the certificate and identity steps are specific to it. The examples are complete implementations with the real commands and prompts.
flowchart LR
you(["<b>You</b><br/>agentbridge delegate"])
slim{{"<b>SLIM node</b><br/>127.0.0.1"}}
subgraph init ["Initiator process"]
direction TB
I["<b>initiator</b><br/><protocol>-initiator"]
end
subgraph spec ["Specialist processes · <protocol>-receiver + role"]
direction TB
S1["<b>specialist 1</b>"]
S2["<b>specialist 2</b>"]
S3["<b>specialist …</b>"]
end
you -- "task + kickoff" --> I
I -- "agentbridge delegate" --> slim
slim --> S1
slim --> S2
slim --> S3
I -. "final outcome" .-> you
Local setup
The agents could run on different systems, each reaching the others over the network. To keep
this tutorial simple, everything runs on one machine, and the SLIM node listens on the
loopback address 127.0.0.1.
1. Prerequisites¶
- A coding harness for each agent, with its credentials. AgentBridge can run Claude Code, Codex, Copilot, Cursor Agent, Goose and opencode, and agents of one team can use different harnesses.
-
agentbridgeandshadictlfromagntcy/shadi, on yourPATH. On macOS:
Other operating systems
The commands above are for macOS. On another system, follow the installation instructions
in the agntcy/shadi repository instead.
2. Create your agents¶
A run needs a task, a team of specialists, and a role for each of them, plus the initiator that starts the protocol. Each agent has its own directory, and three things in it: a harness, the protocol's skills, and an instruction file.
agents/
├── initiator/
│ ├── <instruction file> # working rules
│ └── <skills folder> # the protocol's skills
├── <specialist id>/
│ ├── <instruction file> # the role of the specialist
│ └── <skills folder>
└── ...
-
Pick a harness. Pick one for each agent. The harness is the program AgentBridge launches whenever the agent receives a message.
-
Install the protocol's skills. The harness discovers skills from its project directory, so install the protocol there, in each agent, as described in Installing a skill. With Claude Code, install the plugin in the agent's directory with project scope:
claude plugin marketplace add ioc-project/cognition-protocols cd agents/<agent id> && claude plugin install <protocol>@cognition-protocols --scope projectEach agent gets both the initiator and the receiver skill. Their activation conditions are precise, so the initiator skill only activates on the agent that starts the protocol and the receiver skill on the agents that receive its messages.
-
Define the instruction file. The harness reads the agent's role from the instruction file of its project directory:
Harness Instruction file Claude Code CLAUDE.mdCodex, opencode AGENTS.mdOthers AGENTS.md, or the file the harness documents for project instructionsFor a specialist, the file is its role: what it cares about, and what it will and will not accept. A specialist without a position has nothing to contribute to a decision. For the initiator, the file only sets working rules, such as where to write its files and to report the protocol's final output verbatim.
3. Create the AgentBridge profiles¶
AgentBridge launches an agent from a profile: the program to run, how to pass it a prompt, and
the id of the agent. Every agent needs its own profile, named after its id, and registered with
--tool <agent id>. AgentBridge bundles one profile per harness. Yours is the bundled profile of
your harness with its id changed:
mkdir -p profiles
curl -fsSL https://raw.githubusercontent.com/agntcy/shadi/main/crates/agentbridge/profiles/<harness>.json \
| sed 's/"id": "<harness>"/"id": "<agent id>"/' > profiles/<agent id>.json
The bundled profiles are in the
AgentBridge repository.
Edit the execute arguments if the agent needs different flags, for example to run without
asking for approvals, since nobody is there to answer. Point AGENTBRIDGE_PROFILES_DIR at the
profiles directory.
4. Generate the certificates¶
The SLIM node and every agent authenticate each other with mutual TLS. AgentBridge refuses to
connect without it, even on the loopback address. The agntcy/shadi repository has a script
that generates a local certificate authority, a server certificate for the node and a client
certificate for your own terminal:
curl -fsSL https://raw.githubusercontent.com/agntcy/shadi/main/tools/generate_slim_mtls_certs.sh \
-o generate_slim_mtls_certs.sh
bash generate_slim_mtls_certs.sh "$PWD/.tmp/shadi-slim-mtls"
The node itself needs no installation or configuration file: shadictl slim start-node runs a
native SLIM node.
5. Define the identities¶
AgentBridge authenticates members of the bus with DIDs. Each participant has one, derived deterministically from a fixed seed and the participant's name:
| Identity | Used for |
|---|---|
avatar |
You: the agentbridge delegate call from your terminal that starts the run |
driver |
The initiator's own outbound calls to the specialists (the bus allows one active session per identity, so it cannot reuse avatar or initiator) |
initiator and the specialists |
The registered agents |
Derive them one at a time with shadictl derive-agent-identity, and export what every agent and
your terminal need:
export SHADI_SLIM_AUTH=did
export SLIM_HUMAN_SEED=<a fixed seed>
export SLIM_MEMBER_DIDS=<the DIDs of all participants, comma-separated>
export SLIM_ENDPOINT=127.0.0.1:47560
export SHADI_TMP_DIR="$PWD/.tmp" # where AgentBridge looks for the certificates
export SLIM_TLS_CERT="$PWD/.tmp/shadi-slim-mtls/client-avatar.crt"
export SLIM_TLS_KEY="$PWD/.tmp/shadi-slim-mtls/client-avatar.key"
shadictl derive-agent-identity --source seed --in <seed file> -n <participant> # prints its DID
On macOS, deriving an identity also stores its keys in the keychain, so derive them once, one at a time, and keep the list. An example can publish the identities of its team, which skips this.
6. Register the agents¶
Start the SLIM node, then register each agent from its own directory. An agent is registered
with agentbridge register, wrapped in shadictl, which sandboxes the harness:
shadictl slim start-node # once, in its own terminal
shadictl <sandbox options> -- agentbridge register \
--tool <agent id> --command "$PWD" --slim-endpoint "$SLIM_ENDPOINT"
Use one terminal per process so that each agent's traffic is visible, and export the credentials
of its harness first: the sandbox cannot read your keychain login. Wait until every agent prints
ready — listening on ....
The sandbox options say what the agent can touch:
| Option | Grants |
|---|---|
--allow <dir> |
Read and write access: the agent's own directory, .tmp and the temp directories |
--read <dir> |
Read access: the profiles directory, and where the harness keeps its configuration and skills |
--net-block --net-allow <host> |
No network, except the bus endpoint and the harness's model API |
Why the agents run sandboxed
With AgentBridge, agents are reached over the network: any member of the bus can send a
prompt to an agent, and that prompt is acted on by a coding harness that can run commands
and read and write files on your machine. An agent is therefore only as safe as the least
trusted party that can message it. Each agent is launched under shadictl, which sandboxes
the harness and restricts what it can do locally and what it can connect to:
- Filesystem: the agent can write only to its own directory (plus the harness's own configuration and temp directories) and read only the files it needs.
- Network: outbound connections are blocked except for an explicit allow-list: the bus endpoint and the model API of the harness.
Bus membership is restricted in the same spirit: only the DIDs listed in SLIM_MEMBER_DIDS
are admitted, and a protocol message can only trigger what the agent's own sandbox allows.
7. Prompt the initiator¶
Give the initiator its prompt inline: a registered agent cannot read files outside its own
directory. The prompt is a template with the task, the protocol to use, and how to reach the
specialists. The roles are not in it: each specialist already has its own, in its directory.
Replace what is in angle brackets, and save it as prompt.md.
You coordinate a team of specialists (agent ids: <SPECIALIST IDS, COMMA-SEPARATED>). You cannot
read files outside this directory; everything you need is below. Put every file you write in
./run/.
TASK FOR THE TEAM: "<TASK>"
Load the <PROTOCOL>-initiator skill and follow it to the end. Reach each specialist with
'agentbridge delegate "<message>" --to <agent id> --agent-id driver --endpoint 127.0.0.1:47560'.
Never write a specialist's reply yourself. Report the skill's final output verbatim.
Then hand it to the initiator with delegate, as avatar, from another terminal:
agentbridge delegate "$(cat prompt.md)" \
--to initiator --agent-id avatar --endpoint "$SLIM_ENDPOINT"
The initiator runs the skill's script itself. Every message the script asks for is a real
agentbridge delegate call to a live specialist, so a run takes minutes rather than seconds. The
protocol's own call budget, where it declares one, is printed when the initiator starts the run.
The initiator's state file in ./run/ holds the authoritative record of the run, in the
format defined by the protocol.
8. Look at the examples¶
The examples are complete implementations with the real commands, role files and prompts. Use them as inspiration for adapting the steps to your own use case:
- Coding Agent Team: three Claude Code specialists that must decide how to build a notification service.