Crow
by yusif-v
README.md
# Crow
A local, read-only assistant for your CrowdStrike Falcon tenant.
- **Scope:** strictly **read-only**. The API client is scoped so the tool physically cannot mutate your tenant (no contain, no RTR, no incident writes).
- **Front-ends:** a CLI (`cli.py`) and an MCP server (`server.py`) that both wrap the same shared logic in `core.py`, so they never diverge. The MCP server speaks the standard Model Context Protocol, so **any MCP-capable client** can use it — Claude Code, Cursor, Zed, any LLM harness or agent that supports MCP — not just one specific tool.
## What it can do (v0.2.0, read-only)
| Capability | CLI command | MCP tool |
|---|---|---|
| Ask a question in natural language | `crow ask "..."` | `crow_ask` |
| List detections | `crow detections` | `crow_list_detections` |
| Get a detection | `crow detection <id>` | `crow_get_detection` |
| List alerts | `crow alerts` | `crow_list_alerts` |
| Get an alert | `crow alert <id>` | `crow_get_alert` |
| List / search hosts | `crow hosts` | `crow_list_hosts` |
| Get a host | `crow host --hostname X` | `crow_get_host` |
| List incidents | `crow incidents` | `crow_list_incidents` |
| Get an incident | `crow incident <id>` | `crow_get_incident` |
| IOC lookup (Falcon X) | `crow ioc <value>` | `crow_lookup_ioc` |
> **Note:** detections and incidents are served from the unified **Alerts API**.
> CrowdStrike decommissioned the legacy `detects` endpoint and removed the
> `incidents` endpoint (March 2026); incidents are synthesized by grouping
> related detection alerts that share a control graph.
### AI assistant (`crow ask`)
`crow ask "..."` translates a natural-language question to the right read-only
function, runs it, and summarizes the result with a **local** Ollama model
(`LFM2.5-2.6B`, e.g. `ollama pull hf.co/LiquidAI/LFM2.5-2.6B-GGUF`) — no
third-party transit. It's available as the `crow_ask` MCP tool too, so any
MCP-capable agent can ask naturally. If Ollama is down or unconfigured it falls
back to the raw results with a notice.
See [docs/usage.md](docs/usage.md) for full command reference and examples.
## Repository layout
```
Crow/
├── core.py # shared read-only Falcon logic (falconpy calls)
├── cli.py # standalone CLI front-end
├── server.py # MCP server front-end (any MCP-capable client)
├── requirements.txt
├── .env.example # credential template (copy to .env, chmod 600)
├── .gitignore # excludes .env and .venv
├── README.md
└── docs/
├── usage.md # command reference + examples
├── credentials.md # how to create the read-only API client
└── architecture.md# how it works / safety model
```
## Quick start
```bash
git clone https://github.com/yusif-v/Crow.git
cd Crow
python3 -m venv .venv
./.venv/bin/python -m pip install hatchling wheel setuptools
./.venv/bin/python -m pip install --no-build-isolation "git+https://github.com/CrowdStrike/falconpy.git"
./.venv/bin/python -m pip install "mcp==1.9.4" "python-dotenv>=1.0.0"
cp .env.example .env # then edit .env with your credentials
chmod 600 .env
```
> **Install note:** on some networks PyPI returns an empty package list for `falconpy`
> (a package filter). Installing it from GitHub source (above) is the workaround.
> `mcp` and `python-dotenv` install normally from PyPI.
Create a **read-only** Falcon API client (see [docs/credentials.md](docs/credentials.md)), then:
```bash
./.venv/bin/crow detections --severity-min 4
```
## Wiring into an AI client (agent-agnostic)
`server.py` is a standard MCP server, so it works with **any MCP-capable client** —
Claude Code, Cursor, Zed, your own agent, or any LLM harness that supports the
Model Context Protocol. You are not locked into one tool or model.
### Example: Hermes Agent
Add to `~/.hermes/config.yaml`:
```yaml
mcp_servers:
crow:
command: "/Users/lizard/Development/Projects/Crow/.venv/bin/python"
args: ["/Users/lizard/Development/Projects/Crow/server.py"]
timeout: 120
connect_timeout: 60
```
Restart the agent. The `crow_*` tools then appear and you can ask naturally:
*"show me critical detections in the last 24 hours"*.
### Example: Claude Code
Claude Code auto-discovers an `.mcp.json` in the project root. Drop this in
`~/Development/Projects/Crow/.mcp.json` (or any project where you want Crow
available):
```json
{
"mcpServers": {
"crow": {
"command": "/Users/lizard/Development/Projects/Crow/.venv/bin/python",
"args": ["/Users/lizard/Development/Projects/Crow/server.py"]
}
}
}
```
Or register it globally from the terminal:
```bash
claude mcp add crow -- /Users/lizard/Development/Projects/Crow/.venv/bin/python \
/Users/lizard/Development/Projects/Crow/server.py
```
Then in Claude Code: `/mcp` to confirm it connected, and ask naturally.
### Example: Codex (OpenAI Codex CLI)
Codex reads MCP servers from `~/.codex/config.toml`:
```toml
[mcp_servers.crow]
command = "/Users/lizard/Development/Projects/Crow/.venv/bin/python"
args = ["/Users/lizard/Development/Projects/Crow/server.py"]
```
The `crow_*` tools are then available to Codex in any session.
### Other MCP clients
Any client that reads an MCP server config (stdio transport) can launch `server.py`
the same way — point its command at the venv Python and pass `server.py` as the
argument. The `crow_*` tools are then available to whatever model that client drives.
Prefer not to run an MCP client at all? Use the CLI (`cli.py`) directly — same
read-only logic, no agent required.
## Safety model
- **Read-only by construction.** The Falcon API client is granted only `*:read`
scopes. No write/contain/RTR scope exists, so the server cannot change state.
- **Credentials stay local.** Your Client ID / Secret live only in a chmod-600
`.env` on your machine. They are sent only to CrowdStrike's API. The MCP layer
redacts credential-shaped strings from error messages.
- **No third-party transit.** Queries go directly from your machine to CrowdStrike.
## Status
v0.2.0 — read-only visibility across detections, alerts, hosts, incidents,
and Falcon X IOC lookups, plus a **local AI assistant** (`crow ask` / `crow_ask`)
that maps natural-language questions to the read-only functions and summarizes
the results with Ollama. Detections and incidents are backed by the unified
Alerts API (CrowdStrike decommissioned the legacy `detects` and `incidents`
endpoints). List commands paginate automatically past the API page limit;
detections/alerts/hosts return rich analyst-friendly summaries (hosts, IPs,
users); duplicate hostnames are disambiguated; IOC lookups report missing scope
instead of failing cryptically. No caching, no mutating actions. Those are
deliberate follow-ups.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues