Skip to content

Subprocess Bridges

Subprocess bridges let AI Butler drive external command-line tools — ffmpeg, imagemagick, Aider, Continue CLI, or any shell script — as if they were native tools. Use bridges when the tool has no MCP server and no A2A endpoint, and you want the agent to be able to call it directly.

For persistent tool servers, prefer MCP. For full-agent delegation, prefer A2A.

Bridges live in config.yaml under configurations.bridges.bridges (keyed by name):

configurations:
bridges:
bridges:
ffmpeg-convert:
command: "ffmpeg"
args: ["-i", "{{input}}", "{{output}}", "-y"]
timeout: 60s
capabilities:
- shell.execute
aider:
command: "aider"
args: ["--no-auto-commits", "--yes", "--message", "{{message}}"]
timeout: 600s
capabilities:
- shell.execute
- file.write

After restart, the agent sees bridges.ffmpeg-convert and bridges.aider in its tool registry and can call them through the normal tool-use pipeline.

FieldMeaning
commandExecutable path or name on $PATH
argsArguments list. Supports {{name}} templates for parameters the agent fills in.
timeoutMax runtime before the process is killed (Go duration format: 60s, 5m, etc.)
capabilitiesCapabilities the bridge needs. The agent must have these granted to call it.

{{name}} placeholders in args are filled from the tool-call arguments the agent passes. The agent is told what placeholders exist via the bridge description, so it can fill them in correctly.

Bridges inherit the same sandbox as shell.exec — see configurations.sandbox for workspace-only and allow-list modes. A bridge cannot do anything shell.exec can’t do; it just has a nicer name and a fixed template.

Three reasons to wrap a shell command as a bridge:

  1. Discoverability — the agent sees a named tool with a description instead of having to know about the CLI
  2. Capability gating — you can restrict shell.exec to certain commands and still allow bridges
  3. Template safety — bridge args are built from structured parameters, not string concatenation, so the agent can’t smuggle arbitrary flags
configurations:
bridges:
bridges:
image-resize:
command: "convert"
args: ["{{input}}", "-resize", "{{size}}", "{{output}}"]
timeout: 30s
capabilities:
- shell.execute

Now the agent can say “resize this image to 800x600” and it’ll call bridges.image-resize with input, size, and output parameters.

  • A2A Protocol — agent-level delegation over HTTP
  • MCP Server — persistent tool servers over stdio or HTTP
  • Plugins — in-process WASM extensions, no subprocess overhead