Add your description here
Project description
crow-cli
crow-cli is an Agent Client Protocol (ACP) native agent implementation that serves as the core execution engine for the Crow agent framework.
Installation
# Ensure you're in the correct project directory
git clone https://github.com/crow-cli/crow-cli.git
uv venv
# Install dependencies using uv
uv --project /path/to/crow/crow-cli sync
Or run directly
uvx crow-cli --help
if you like having it available globally, you can install it using pip
uv tool install crow-cli --python 3.14
Quick Start
uvx crow-cli init
Run Programmatically
import asyncio
from crow_acp.agent import AcpAgent, agent_run
async def main():
await agent_run()
if __name__ == "__main__":
asyncio.run(main())
Configuration
Features
1. ACP Protocol Native
- Implements all ACP agent endpoints (
initialize,new_session,load_session,prompt,cancel) - Full streaming support for token-by-token responses
- Session persistence to SQLite database
2. MCP Tool Integration
- Automatically discovers tools from connected MCP servers
- Supports both MCP and ACP-native tool execution
- Tool execution with progress updates
3. Streaming ReAct Loop
- Real-time streaming of thinking tokens (for reasoning models)
- Content token streaming
- Tool call progress updates (pending → in_progress → completed/failed)
4. Cancellation Support
- Immediate task cancellation via async events
- Persists partial state on cancellation
- Safe resource cleanup on cancel
5. ACP Terminal Support
When the ACP client supports terminals (clientCapabilities.terminal: true):
- Uses ACP-native terminals instead of MCP terminal calls
- Better terminal display in the client
- Live output streaming
- Proper terminal lifecycle management
Built-in Tools
The agent automatically discovers and registers tools from connected MCP servers:
crow-mcp_terminal- Execute shell commands in the workspacecrow-mcp_write- Write content to filescrow-mcp_read- Read files with line numberscrow-mcp_edit- Fuzzy string replacement in filescrow-mcp_web_search- Search the web using a search enginecrow-mcp_web_fetch- Fetch URL content as markdown
Session Management
Creating a New Session
# When connecting via ACP, a new session is created automatically
# with the working directory and MCP servers provided by the client
Loading an Existing Session
# Sessions persist to the database and can be loaded by ID
# The load_session endpoint handles this automatically
Session Data Storage
Sessions are stored in SQLite with three main tables:
- Prompt - System prompt templates (Jinja2)
- Session - Session metadata (config, tools, model, cwd)
- Event - Conversation turns (messages, tool calls, results)
Usage with ACP Clients
crow-cli is designed to work with any ACP-compatible client:
// In Zed
{
"agent_servers": {
"crow-cli": {
"type": "custom",
"command": "uvx",
"args": ["crow-cli", "acp"],
},
...
}
ACP Client Capabilities
The agent automatically detects and uses client capabilities:
| Capability | When Enabled | Behavior |
|---|---|---|
terminal |
Client supports ACP terminals | Uses ACP-native terminals |
fs.write_text_file |
Client supports file writing | Uses ACP file write |
fs.read_text_file |
Client supports file reading | Uses ACP file read |
Project Structure
crow-cli/
├── src/crow_cli/
│ ├── __init__.py
│ ├── agent/
│ │ ├── __init__.py
│ │ ├── compact.py # Conversation compaction
│ │ ├── configure.py # Agent configuration
│ │ ├── context.py # Context providers (directory tree, file fetching)
│ │ ├── db.py # SQLAlchemy database models
│ │ ├── llm.py # LLM client configuration
│ │ ├── logger.py # Logging utilities
│ │ ├── main.py # Agent entry point
│ │ ├── mcp_client.py # MCP client creation + tool extraction
│ │ ├── prompt.py # Prompt building
│ │ ├── react.py # ReAct loop implementation
│ │ ├── session.py # Session management + persistence
│ │ ├── skills.py # Skills handling
│ │ ├── tools.py # Tool definitions
│ │ └── prompts/ # Jinja2 system prompt templates
│ │ ├── system_prompt.jinja2
│ │ ├── self_documentation.jinja2
│ │ ├── skill_knowledge_info.jinja2
│ │ └── system_message_suffix.jinja2
│ ├── cli/
│ │ ├── __init__.py
│ │ ├── init_cmd.py # `crow init` command
│ │ └── main.py # CLI entry point
│ └── client/
│ ├── __init__.py
│ └── main.py # Programmatic client
├── config/
│ ├── compose.yaml # Docker compose for services
│ ├── config.yaml # Default configuration
│ ├── .env.example # Environment variables template
│ ├── searxng/
│ │ └── settings.yml # SearXNG search config
│ └── prompts/ # Override prompts (user customization)
│ ├── system_prompt.jinja2
│ ├── self_documentation.jinja2
│ ├── skill_knowledge_info.jinja2
│ └── system_message_suffix.jinja2
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_agent_init.py
│ └── unit/
│ └── test_session.py
├── examples/
│ ├── mc_escher_loop.py
│ └── quick_test.py
├── pyproject.toml
├── README.md
├── TODO.md
└── run_tests.sh
Development
Running Tests
# From the project root
uv run --project /home/thomas/src/nid pytest crow-cli/tests/
Building
# Build the package
uv build --project /home/thomas/src/nid/crow-cli
# Install locally
pip install --force-reinstall ./crow-cli/dist/*.whl
ReAct Loop Logic
┌─────────────────────────────────────────────────────────────────────────┐
│ REACT LOOP (Turn N) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────┐
│ cancel_event.is_set()? │
└───────────────────────────────┘
│ │
YES NO
│ │
▼ ▼
┌──────────┐ ┌────────────────────────┐
│ RETURN │ │ send_request(LLM) │
└──────────┘ └────────────────────────┘
│
▼
┌──────────────────────────────┐
│ process_response() stream │
│ ┌────────────────────────┐ │
│ │ Yield: thinking/token │ │
│ │ Yield: content/token │ │
│ │ Yield: tool_args/token │ │
│ └────────────────────────┘ │
│ │ │
│ ▼ │
│ Collect in │
│ state_accumulator │
└──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ Cancelled during stream? │
└──────────────────────────────┘
┌────────┴────────┐
YES NO
│ │
▼ ▼
┌──────────────┐ ┌────────────────────────┐
│ Add partial │ │ Yield: final │
│ response │ │ (thinking, content, │
│ + results │ │ tool_call_inputs) │
│ Raise │ └────────────────────────┘
│ CancelledErr │ │
└──────────────┘ ▼
│ ┌────────────────────────┐
│ │ Log pre-tool usage │
▼ └────────────────────────┘
┌──────────┐ │
│ RETURN │ ┌────────────────────────┐
└──────────┘ │ tokens > threshold? │
│ └────────────────────────┘
┌──────────────────────────────┐ │ │
│ Turn Loop: for turn in │ YES NO
│ range(max_turns): │ │ │
└──────────────────────────────┘ ▼ ▼
│ ┌──────────────┐ ┌──────────┐
▼ │ COMPACT │ │ SKIP │
┌──────────────────────────┐ │ session() │ │ COMPACT│
│ process_response DONE │ └──────────────┘ └──────────┘
│ Extract: thinking │ │ │
│ content │ └────────┬───────┘
│ tool_call_inputs │ │
│ usage │ ▼
└──────────────────────────┘ ┌────────────────────────┐
│ │ Has tools to call? │
▼ └────────────────────────┘
┌──────────────────────────┐ │
│ Cancelled after stream? │ ┌────┴────┐
└──────────────────────────┘ YES NO
│ │ │
YES ▼ ▼
│ ┌──────────────┐ ┌──────────────┐
▼ │ EXECUTE │ │ NO TOOLS │
┌──────────────┐ │ TOOLS │ │ (final msg) │
│ Add partial │ └──────────────┘ └──────────────┘
│ response │ │ │
│ + tool │ │ │
│ results │ ▼ ▼
│ RETURN │ ┌──────────────┐ ┌──────────────┐
└──────────────┘ │ Add tools │ │ Add assistant│
│ to results │ │ response │
└──────────────┘ └──────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────┐
│ Cancelled after tool execution? │
└──────────────────────────────────────────────────┘
│
┌────────┴────────┐
YES NO
│ │
▼ ▼
┌──────────────┐ ┌────────────────────────┐
│ Add partial │ │ Add assistant response │
│ response + │ │ + tool results │
│ tool results │ └────────────────────────┘
│ RETURN │ │
└──────────────┘ │
│
▼
┌────────────────────────┐
│ Turn N complete │
│ ───────────────────── │
│ Loop back to turn N+1 │
│ (or max_turns reached)│
└────────────────────────┘
Troubleshooting
Connection Issues
If the agent can't connect to MCP servers:
- Verify MCP server config in
~/.crow/mcp.json - Check that the MCP server path is correct
- Ensure the server is executable
Session Loading Failures
If sessions fail to load:
- Check database exists:
ls ~/.crow/crow.db - Verify database permissions:
chmod 644 ~/.crow/crow.db - Check session ID exists in database
Terminal Not Working
If ACP terminals aren't working:
- Check client capabilities:
clientCapabilities.terminalshould betrue - Verify MCP terminal fallback is configured
- Check terminal command is valid in the workspace directory
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crow_cli-0.1.4.tar.gz.
File metadata
- Download URL: crow_cli-0.1.4.tar.gz
- Upload date:
- Size: 124.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5396cf713728ebbe2c66ce1b3fba66ca37aadf01f70907d32a2cf16a7a9744b8
|
|
| MD5 |
af466bcd77c617beda96afabe49414ae
|
|
| BLAKE2b-256 |
d30b148aed8965dd4c73050d6bcb7a7b83ffa6de7503a5ff07c7981844245962
|
File details
Details for the file crow_cli-0.1.4-py3-none-any.whl.
File metadata
- Download URL: crow_cli-0.1.4-py3-none-any.whl
- Upload date:
- Size: 46.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1c39e3f316f8cec67bb044d619840b749eb5d9d5ab1c496b5c62f692c2e88ab
|
|
| MD5 |
2842bec411090f695ec8a17013d4122b
|
|
| BLAKE2b-256 |
ba2a9de0958be17b82e0831dc7db1ba42d7f6863aefb3231cde9673468142fc2
|