> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI Backend Protocol

> Plug an external CLI (Claude Code, future: Codex, Gemini) in as a first-class Agent backend

CLI Backends let you run an agent's turn through an external CLI tool (like Claude Code) instead of a Python LLM client, while keeping the same `Agent`/`Task` API.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "CLI Backend Flow"
        A[📋 Agent Input] --> B[🧠 Resolver]
        B --> C[🔌 Backend]
        C --> D[💻 CLI Process]
        D --> E[✅ Result]
    end
    
    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef resolver fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef backend fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    
    class A input
    class B resolver
    class C,D backend
    class E result
```

## Quick Start

<Steps>
  <Step title="Simplest: CLI flag">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai "Refactor utils.py" --cli-backend claude-code
    ```
  </Step>

  <Step title="Declarative: YAML">
    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    framework: praisonai
    topic: coding
    roles:
      coder:
        role: Code refactorer
        goal: Refactor Python modules
        backstory: Senior engineer
        cli_backend: claude-code   # string form
        tasks:
          refactor:
            description: Refactor utils.py
            expected_output: Refactored code
    ```
  </Step>

  <Step title="YAML with overrides">
    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    roles:
      coder:
        role: Code refactorer
        goal: Refactor Python modules
        backstory: Senior engineer
        cli_backend:
          id: claude-code
          overrides:
            timeout_ms: 60000
        tasks:
          refactor:
            description: Refactor utils.py
            expected_output: Refactored code
    ```
  </Step>

  <Step title="Discover what's registered">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai backends list
    # claude-code
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI as CLI/YAML
    participant Resolver as resolve_cli_backend
    participant Factory as Backend Factory
    participant Backend as ClaudeCodeBackend
    participant Process as claude CLI
    participant Agent

    User->>CLI: Request with --cli-backend
    CLI->>Resolver: resolve_cli_backend(id, overrides)
    Resolver->>Factory: Create backend instance
    Factory->>Backend: ClaudeCodeBackend()
    Agent->>Backend: execute(prompt)
    Backend->>Process: subprocess call
    Process-->>Backend: JSONL response
    Backend-->>Agent: CliBackendResult
    Agent-->>User: Final response
```

| Step | Component | Purpose                                           |
| ---- | --------- | ------------------------------------------------- |
| 1    | User/CLI  | Specifies backend via flag or YAML                |
| 2    | Resolver  | Factory pattern for backend creation              |
| 3    | Backend   | Protocol implementation (e.g., ClaudeCodeBackend) |
| 4    | Process   | External CLI subprocess execution                 |
| 5    | Result    | Parsed response returned to Agent                 |

***

## Configuration Surfaces

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{How do I want to configure a CLI backend?}
    Q -->|Quickest, ad-hoc command| A[--cli-backend on the CLI]
    Q -->|Versioned, per-role config| B[cli_backend in YAML - string form]
    Q -->|Need to tweak timeouts/args| C[cli_backend in YAML - dict with overrides]
    Q -->|Building a custom backend| D[register_cli_backend in Python]
    
    classDef question fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef option fill:#189AB4,stroke:#7C90A0,color:#fff
    
    class Q question
    class A,B,C,D option
```

***

## The `cli_backend` YAML Field

| Shape                     | Example                                                          | Behavior                                                           |
| ------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------ |
| Omitted                   | *(field absent)*                                                 | No backend used; Agent uses normal LLM client. No warning logged.  |
| String                    | `cli_backend: claude-code`                                       | Resolves via `resolve_cli_backend("claude-code")`                  |
| Dict                      | `cli_backend: {id: claude-code, overrides: {timeout_ms: 60000}}` | Resolves via `resolve_cli_backend("claude-code", overrides={...})` |
| Dict missing `id`         | `cli_backend: {overrides: {...}}`                                | Returns `None` + logged warning. **Does not raise.**               |
| Unknown id                | `cli_backend: nope`                                              | Returns `None` + logged warning. **Does not raise.**               |
| Invalid type (e.g. `123`) | `cli_backend: 123`                                               | Returns `None` + logged warning. **Does not raise.**               |

***

## Built-in Backend: `claude-code`

The `claude-code` backend executes commands via the Claude Code CLI with these default settings:

| Option               | Type             | Default                                                                                                                                                                                                                                                                                                                                                                                                | Description                                       |
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- |
| `command`            | `str`            | `"claude"`                                                                                                                                                                                                                                                                                                                                                                                             | CLI command (must be on PATH)                     |
| `args`               | `List[str]`      | `["-p", "--output-format", "stream-json", "--include-partial-messages", "--verbose", "--setting-sources", "user", "--permission-mode", "bypassPermissions"]`                                                                                                                                                                                                                                           | Default arguments passed to CLI                   |
| `resume_args`        | `List[str]`      | `["-p", "--output-format", "stream-json", "--resume", "{session_id}"]`                                                                                                                                                                                                                                                                                                                                 | Arguments for resuming sessions                   |
| `output`             | `str`            | `"jsonl"`                                                                                                                                                                                                                                                                                                                                                                                              | Output format expected from CLI                   |
| `input`              | `str`            | `"stdin"`                                                                                                                                                                                                                                                                                                                                                                                              | How to pass prompts to CLI                        |
| `live_session`       | `str`            | `"claude-stdio"`                                                                                                                                                                                                                                                                                                                                                                                       | Live session mode                                 |
| `model_arg`          | `str`            | `"--model"`                                                                                                                                                                                                                                                                                                                                                                                            | CLI argument for model selection                  |
| `model_aliases`      | `Dict[str, str]` | `{"opus": "claude-opus-4-5", "sonnet": "claude-sonnet-4-5", "haiku": "claude-haiku-3-5"}`                                                                                                                                                                                                                                                                                                              | Model name shortcuts                              |
| `session_arg`        | `str`            | `"--session-id"`                                                                                                                                                                                                                                                                                                                                                                                       | CLI argument for session ID                       |
| `session_mode`       | `str`            | `"always"`                                                                                                                                                                                                                                                                                                                                                                                             | When to use sessions                              |
| `session_id_fields`  | `List[str]`      | `["session_id"]`                                                                                                                                                                                                                                                                                                                                                                                       | Fields containing session ID                      |
| `system_prompt_arg`  | `str`            | `"--append-system-prompt"`                                                                                                                                                                                                                                                                                                                                                                             | CLI argument for system prompts                   |
| `system_prompt_when` | `str`            | `"first"`                                                                                                                                                                                                                                                                                                                                                                                              | When to add system prompts                        |
| `image_arg`          | `str`            | `"--image"`                                                                                                                                                                                                                                                                                                                                                                                            | CLI argument for images                           |
| `clear_env`          | `List[str]`      | `["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_OAUTH_TOKEN", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "CLAUDE_CONFIG_DIR", "CLAUDE_CODE_OAUTH_TOKEN", "OTEL_EXPORTER_OTLP_ENDPOINT", "OTEL_EXPORTER_OTLP_HEADERS", "OTEL_RESOURCE_ATTRIBUTES", "GOOGLE_APPLICATION_CREDENTIALS", "AWS_PROFILE", "AWS_REGION", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]` | Environment variables sanitized before subprocess |
| `bundle_mcp`         | `bool`           | `True`                                                                                                                                                                                                                                                                                                                                                                                                 | Enable MCP bundling                               |
| `bundle_mcp_mode`    | `str`            | `"claude-config-file"`                                                                                                                                                                                                                                                                                                                                                                                 | MCP bundling mode                                 |
| `serialize`          | `bool`           | `True`                                                                                                                                                                                                                                                                                                                                                                                                 | Queue operations to avoid conflicts               |
| `timeout_ms`         | `int`            | `300000`                                                                                                                                                                                                                                                                                                                                                                                               | Subprocess timeout (5 minutes)                    |

***

## The `--cli-backend` CLI Flag

| Flag                                    | Type   | Behavior                                                                            |
| --------------------------------------- | ------ | ----------------------------------------------------------------------------------- |
| `--cli-backend BACKEND_ID`              | string | Choices populated dynamically from `list_cli_backends()`. Currently: `claude-code`. |
| `--cli-backend X --external-agent Y`    | —      | **Mutually exclusive** — argparse rejects with "not allowed with argument"          |
| Unknown id (e.g. `--cli-backend bogus`) | —      | Rejected by argparse with "invalid choice"                                          |

***

## The `backends` Subcommand

| Command                    | Behavior                                                                                 |
| -------------------------- | ---------------------------------------------------------------------------------------- |
| `praisonai backends list`  | Prints each registered backend id on its own line                                        |
| `praisonai backends`       | Same as `list` (list is the default)                                                     |
| `praisonai backends bogus` | Prints `[red]Unknown backends subcommand: bogus[/red]` and the list of valid subcommands |

***

## Custom Backends (Advanced)

Register your own CLI backend for custom tools:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.cli_backends import register_cli_backend
from praisonaiagents import CliBackendConfig

def my_backend_factory():
    from my_pkg import MyBackend
    return MyBackend(config=CliBackendConfig(command="my-cli"))

register_cli_backend("my-backend", my_backend_factory)
```

After registering, `praisonai backends list` shows it, `--cli-backend my-backend` accepts it, and `cli_backend: my-backend` works in YAML.

***

## CliBackendProtocol Reference

For backend authors implementing the protocol:

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "CliBackendProtocol"
        A[config: CliBackendConfig] 
        B[async execute(...)]
        C[async stream(...)]
    end
    
    classDef protocol fill:#8B0000,stroke:#7C90A0,color:#fff
    
    class A,B,C protocol
```

* `config: CliBackendConfig` — Configuration object
* `async def execute(prompt, *, session=None, images=None, system_prompt=None, **kwargs) -> CliBackendResult` — Single execution
* `async def stream(prompt, **kwargs) -> AsyncIterator[CliBackendDelta]` — Streaming execution

***

## Best Practices

<AccordionGroup>
  <Accordion title="Prefer YAML for production">
    Use the YAML `cli_backend:` field for versioned, declarative configuration. Use `--cli-backend` flag for quick one-off commands and testing.
  </Accordion>

  <Accordion title="Set timeout overrides for slow CLIs">
    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    cli_backend:
      id: claude-code
      overrides:
        timeout_ms: 60000  # 1 minute instead of 5
    ```

    Rather than monkey-patching, use the overrides system for custom timeouts.
  </Accordion>

  <Accordion title="Don't combine with --external-agent">
    The `--cli-backend` flag and `--external-agent` flag are mutually exclusive. Pick one approach:

    * CLI Backends (new): Pluggable, configurable, YAML-supported
    * External Agent (legacy): Class-based, limited configuration
  </Accordion>

  <Accordion title="Ensure claude CLI is on PATH">
    The `claude-code` backend requires the `claude` CLI to be installed and accessible. Install via the Claude Code SDK or ensure it's in your system PATH.
  </Accordion>
</AccordionGroup>

***

## How this differs from `--external-agent`

<Note>
  The legacy `--external-agent claude` and `ClaudeCodeIntegration` class still work and are unchanged (see [External CLI Integrations](/docs/features/external-cli-integrations)). The CLI Backend Protocol is the **new pluggable** path: backends are registered by id, configured declaratively, and surfaced as a YAML field and `--cli-backend` flag.
</Note>

***

## Related

<CardGroup cols={2}>
  <Card title="External CLI Integrations" icon="link" href="/docs/features/external-cli-integrations">
    Legacy class-based CLI integration approach
  </Card>

  <Card title="Agent Configuration" icon="gear" href="/docs/concepts/agents">
    Core Agent configuration and usage patterns
  </Card>
</CardGroup>
