aamp-cli-bridge
v0.1.3
Published
Bridge direct CLI agents into the AAMP email network with profile-driven command invocation
Readme
aamp-cli-bridge
Profile-driven bridge for direct CLI agents that do not speak ACP.
aamp-cli-bridge turns command-line agents into AAMP mailbox participants. It receives task.dispatch mail, renders the task into a CLI prompt, runs the configured command, streams incremental output when the CLI provides it, and sends the final task.result or task.help_needed back to the same AAMP thread.
Use it for agents whose public surface is a command such as claude, codex, coco, gemini, codem, or a private in-house CLI.
Install
npm install aamp-cli-bridgeFrom this repo:
cd packages/cli-bridge
npm install
npm run buildRecommended Flow
The normal flow is:
npx aamp-cli-bridge profile-maker
npx aamp-cli-bridge init
npx aamp-cli-bridge startprofile-maker creates or updates a user profile for a custom CLI agent. Built-in profiles do not need this step.
init is repeatable. It scans built-in profiles, user-created profiles, profiles already present in the config file, and already configured agents. The prompt is a multi-select list: use arrow keys to move, Space to select, and Enter to confirm. Agents that were configured previously stay selected by default, so you can rerun init to add a new agent without losing existing ones.
When configuring senderPolicies, init first asks whether to reuse an existing policy when one is already available for that agent. New agents can also reuse the senderPolicies from another configured agent before entering a new policy by hand.
start loads the config, provisions or reuses each agent mailbox, listens for task.dispatch, and forwards work into the matching CLI command.
Storage
Default paths:
- Config:
~/.aamp/cli-bridge/config.json - Agent credentials:
~/.aamp/cli-bridge/credentials/<agent>.json - User profiles:
~/.aamp/cli-bridge/profiles/<profile>.json
init writes the main config and credentials. profile-maker writes user profile JSON files. You can also pass a config path to commands that support it:
npx aamp-cli-bridge start --config ./production.cli-bridge.json
npx aamp-cli-bridge list --config ./production.cli-bridge.jsonProfile Model
A CLI profile describes how to invoke an agent and how to interpret its output.
Profiles can come from four places:
- Built-in profiles shipped by the bridge:
claude,codex,coco,gemini, andcodem - User profiles in
~/.aamp/cli-bridge/profiles/*.json - Shared top-level
profilesin the bridge config - Inline
cliProfileobjects on a specific agent config
When an agent uses a string profile reference, resolution order is:
profiles.<name>in the loaded config~/.aamp/cli-bridge/profiles/<name>.json- built-in profile
<name>
When an agent uses an inline cliProfile object, that object is used directly for that agent.
Profile Format
{
"name": "codem",
"description": "Codem SSE mode.",
"command": "codem",
"args": ["-p", "{{prompt}}", "--sse", "--yolo"],
"stdin": null,
"env": {
"MY_AGENT_MODE": "aamp"
},
"cwd": "/path/to/workspace",
"shell": false,
"timeoutMs": 1800000,
"successExitCodes": [0],
"stream": {
"format": "sse",
"enabled": true
},
"output": {
"includeStderr": false,
"stripAnsi": true,
"trim": true
}
}Fields:
name: optional profile name; file names and config keys also name profilesdescription: optional human-readable description shown by profile listing and initcommand: executable to runargs: argument list; each string supports template variablesstdin: optional stdin template; use this when the CLI reads the prompt from stdinenv: extra environment variables for the child processcwd: working directory for the child processshell: run through a shell when truetimeoutMs: process timeout; defaults to the bridge runtime default when omittedsuccessExitCodes: accepted exit codes; defaults to[0]stream: optional parser declaration for streaming CLIsoutput: plain-output cleanup rules
Supported template variables:
{{prompt}}: rendered AAMP task prompt{{agentName}}: current bridge agent name{{sessionKey}}: stable AAMP session key for the thread, when available{{env.NAME}}: environment variableNAME
Examples
Prompt in arguments:
{
"name": "my-agent",
"command": "my-agent",
"args": ["run", "--prompt", "{{prompt}}"],
"timeoutMs": 1800000,
"output": {
"stripAnsi": true,
"trim": true
}
}Prompt over stdin:
{
"name": "stdin-agent",
"command": "stdin-agent",
"args": ["run"],
"stdin": "{{prompt}}"
}SSE stream:
{
"name": "codem",
"command": "codem",
"args": ["-p", "{{prompt}}", "--sse", "--yolo"],
"stream": {
"format": "sse"
},
"timeoutMs": 1800000
}NDJSON stream:
{
"name": "custom-ndjson-agent",
"command": "custom-agent",
"args": ["run", "--json"],
"stdin": "{{prompt}}",
"stream": {
"format": "ndjson"
}
}Stream Parsing
stream.format supports:
sse: Server-Sent Events withevent:anddata:linesndjson: one JSON object per line
The parser accepts common event shapes used by CLI agents:
text,delta,text.delta: forwarded to AAMP astext.deltatool_start,tool_result,tool: forwarded as stream progress or status eventsusage: forwarded as a progress eventresult: used as final text when presentdone: closes the stream state for the current task
Text deltas are streamed to AAMP and concatenated into the final task.result. This lets a mailbox UI show live output while still preserving a complete final answer in the thread.
Bridge Config
Minimal config using a built-in profile:
{
"aampHost": "https://meshmail.ai",
"rejectUnauthorized": false,
"agents": [
{
"name": "codex",
"cliProfile": "codex",
"slug": "codex-cli-bridge",
"credentialsFile": "~/.aamp/cli-bridge/credentials/codex.json"
}
]
}Inline custom profile:
{
"aampHost": "https://meshmail.ai",
"rejectUnauthorized": false,
"agents": [
{
"name": "my-agent",
"cliProfile": {
"command": "my-agent",
"args": ["run", "{{prompt}}"],
"timeoutMs": 1800000
},
"slug": "my-agent-cli-bridge"
}
]
}Shared top-level profile:
{
"aampHost": "https://meshmail.ai",
"profiles": {
"my-agent": {
"command": "my-agent",
"stdin": "{{prompt}}"
}
},
"agents": [
{
"name": "my-agent",
"cliProfile": "my-agent"
}
]
}senderPolicies is optional. When configured, the bridge only accepts dispatches from matching sender mailboxes and can enforce exact-match X-AAMP-Dispatch-Context values:
{
"senderPolicies": [
{
"sender": "[email protected]",
"dispatchContextRules": {
"project_key": ["project-a"],
"user_key": ["alice"]
}
}
]
}Runtime Contract
For each accepted task.dispatch, the bridge:
- builds a task prompt from AAMP headers, body, and attachments
- renders the configured profile templates
- starts the CLI process
- streams parsed events to AAMP when
streamis enabled - sends
task.resultwith the final concatenated output
The CLI agent can use these plain-output conventions:
- Start final output with
HELP:to sendtask.help_needed - End output with
FILE:/absolute/path/to/filelines to attach generated files totask.result
Commands
npx aamp-cli-bridge init
npx aamp-cli-bridge start [--config X]
npx aamp-cli-bridge list [--config X]
npx aamp-cli-bridge status
npx aamp-cli-bridge profile-list
npx aamp-cli-bridge profile-maker
npx aamp-cli-bridge directory-list --agent NAME [--include-self]
npx aamp-cli-bridge directory-search --agent NAME --query TEXT
npx aamp-cli-bridge directory-update --agent NAME --summary TEXT