{"id":50834250,"url":"https://github.com/adanb13/cirdan","last_synced_at":"2026-06-17T05:00:31.693Z","repository":{"id":364134327,"uuid":"1265770289","full_name":"adanb13/cirdan","owner":"adanb13","description":"AI infrastructure cartographer and operations daemon — Graphify for live infrastructure. Fingerprints, graphs, and watches Docker/Kubernetes/AWS/IaC for AI agents via CLI + MCP.","archived":false,"fork":false,"pushed_at":"2026-06-16T02:06:12.000Z","size":353,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T04:25:29.588Z","etag":null,"topics":["agent-skills","ai-agents","aiops","claude-code","codex","cursor","devops","docker","gemini-cli","incident-response","infrastructure","knowledge-graph","kubernetes","mcp","mcp-server","observability","sre","terraform"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/cirdanops/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adanb13.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-11T04:16:34.000Z","updated_at":"2026-06-15T07:06:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adanb13/cirdan","commit_stats":null,"previous_names":["adanb13/cirdan"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/adanb13/cirdan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adanb13%2Fcirdan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adanb13%2Fcirdan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adanb13%2Fcirdan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adanb13%2Fcirdan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adanb13","download_url":"https://codeload.github.com/adanb13/cirdan/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adanb13%2Fcirdan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34434496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skills","ai-agents","aiops","claude-code","codex","cursor","devops","docker","gemini-cli","incident-response","infrastructure","knowledge-graph","kubernetes","mcp","mcp-server","observability","sre","terraform"],"created_at":"2026-06-14T02:10:22.158Z","updated_at":"2026-06-17T05:00:31.668Z","avatar_url":"https://github.com/adanb13.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- mcp-name: io.github.adanb13/cirdan --\u003e\n\n# Cirdan\n\n[![PyPI](https://img.shields.io/pypi/v/cirdanops)](https://pypi.org/project/cirdanops/)\n[![npm](https://img.shields.io/npm/v/%40cirdanops%2Fcli?logo=npm)](https://www.npmjs.com/package/@cirdanops/cli)\n[![npm installs](https://img.shields.io/npm/dt/%40cirdanops%2Fcli?logo=npm\u0026label=npm%20installs)](https://www.npmjs.com/package/@cirdanops/cli)\n[![Python](https://img.shields.io/pypi/pyversions/cirdanops)](https://pypi.org/project/cirdanops/)\n[![Downloads](https://static.pepy.tech/badge/cirdanops)](https://pepy.tech/projects/cirdanops)\n[![CI](https://github.com/adanb13/cirdan/actions/workflows/ci.yml/badge.svg)](https://github.com/adanb13/cirdan/actions/workflows/ci.yml)\n[![License](https://img.shields.io/github/license/adanb13/cirdan)](LICENSE)\n[![Stars](https://img.shields.io/github/stars/adanb13/cirdan?style=social)](https://github.com/adanb13/cirdan/stargazers)\n\n**Cirdan is a standalone AI infrastructure cartographer and operations daemon — Graphify for live infrastructure.**\n\nIt installs into AI agents like a skill, but instead of graphing only code, it fingerprints and graphs the live infrastructure the agent can access: Docker, Kubernetes, cloud accounts, IaC, databases, telemetry. It watches that graph continuously, detects incidents, and gives agents (and humans) a structured way to understand and operate the system.\n\n```\nCirdan fingerprints the system.\nCirdan graphs the system.\nCirdan watches the system.\nCirdan lets the agent operate inside the system using the access the agent already has.\nCirdan generates views only when the human asks to see something.\n```\n\n## Quickstart\n\n```bash\nuv tool install \"cirdanops[all]\"   # or npm / brew / curl — see Install below\ncirdan setup                       # one command: hook your agents, register MCP,\n                                   # arm the responder, build the first map, start the daemon\n```\n\n`cirdan setup` walks you through the whole loop and only proposes what's missing, so\nit's safe to re-run. Two useful flags:\n\n- `cirdan setup --all`     — run every step without prompting (good for scripts / CI)\n- `cirdan setup --system`  — set up machine-level awareness in `~/.cirdan` instead of a repo\n\nThat's it — Cirdan is now mapping, watching, and agent-ready. Read on for everything else.\n\n## Install\n\n**From PyPI (recommended):**\n\n```bash\nuv tool install \"cirdanops[all]\"\n# or\npipx install \"cirdanops[all]\"\npip install \"cirdanops[all]\"\n```\n\n**Without Python — npm / Homebrew / curl:**\n\n```bash\nnpx -y @cirdanops/cli serve-mcp        # run the MCP server, zero install\nnpm install -g @cirdanops/cli          # or put the `cirdan` command on your PATH\nbrew install adanb13/tap/cirdan        # macOS / Linux (Homebrew)\ncurl -LsSf https://raw.githubusercontent.com/adanb13/cirdan/main/packaging/install.sh | sh\n# Windows: irm https://raw.githubusercontent.com/adanb13/cirdan/main/packaging/install.ps1 | iex\n```\n\nThese ship a self-contained binary — no Python 3.11+ required. Supported: macOS (arm64), Linux x64/arm64 (glibc), Windows x64. On Intel Macs, Alpine/musl, or other platforms, use the PyPI install above.\n\n**Then set it up in one command** (see [Quickstart](#quickstart)):\n\n```bash\ncirdan setup --system     # map + watch your whole machine, agent-ready\n# or, inside a repo:\ncirdan install --project\n```\n\nBoth walk you through the full loop: hook your AI agents, arm the incident responder, build the first map, and start the always-on daemon.\n\nTargeted installs: `cirdanops[mcp]`, `cirdanops[api]`, `cirdanops[terraform]`, or combinations like `cirdanops[terraform,mcp]`. The Docker/Kubernetes/AWS/systemd adapters need no extras — they use the CLIs already on your PATH.\n\n**Prerequisites by platform** (Python 3.11+ and `uv` or `pipx`):\n\n```bash\n# macOS\nbrew install python@3.12 uv\n\n# Windows\nwinget install astral-sh.uv\n\n# Ubuntu / Debian\nsudo apt install python3.12 python3-pip pipx\n# or get uv:\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n**Docker (no Python needed):**\n\n```bash\n# run the always-on daemon against your host's Docker, watching the current directory\ndocker run -d \\\n  -v \"$PWD\":/workspace:ro \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -p 127.0.0.1:8090:8090 \\\n  ghcr.io/adanb13/cirdan\n```\n\n(or `docker compose up` with the provided [docker-compose.yml](docker-compose.yml))\n\n**From source:**\n\n```bash\npip install \"cirdanops[all] @ git+https://github.com/adanb13/cirdan.git\"\n```\n\nTwo commands are installed:\n\n| Command | What it is |\n|---|---|\n| `cirdan` | Human/agent CLI |\n| `cirdand` | Long-running Always ON daemon |\n\n## Upgrading\n\nNothing happens automatically — PyPI is pull-only, so an installed version keeps working as-is until you upgrade. New installs always get the latest release. Upgrading is one command, matching however you installed:\n\n| Installed via | Upgrade command |\n|---|---|\n| `uv tool install` | `uv tool upgrade cirdanops` |\n| `pipx install` | `pipx upgrade cirdanops` |\n| `pip install` | `pip install -U cirdanops` |\n| npm (`-g`) | `npm install -g @cirdanops/cli@latest` (or just `npx @cirdanops/cli@latest …`) |\n| Homebrew | `brew upgrade cirdan` |\n| curl installer | re-run the install script (it fetches the latest) |\n| Docker | `docker pull ghcr.io/adanb13/cirdan:latest` (then restart the container) |\n\nTwo operational notes: existing `cirdan-out/` artifacts and the SQLite graph are compatible across releases so far (a schema-version key + migration will land before 1.0). And the CLI prints a single dim line on stderr when a newer release exists (checked at most once a day, interactive terminals only) — silence it with `CIRDAN_NO_UPDATE_CHECK=1`.\n\n## First map\n\n```bash\ncirdan map .\n```\n\nThis fingerprints the environment (repo files **and** live runtimes the session can reach), builds the graph, and writes:\n\n```\ncirdan-out/\n├── infra.html          # interactive infrastructure map\n├── INFRA_REPORT.md     # plain-English report\n├── infra.graph.json    # machine-readable graph for agents\n├── fingerprint.json    # evidence-backed environment classification\n├── access.json         # what this session can currently reach\n├── services.json\n├── dependencies.json\n├── runtime-state.json\n├── incidents/          # active.json + history.jsonl\n├── views/generated/    # on-demand Agentic UI views\n└── audit.jsonl         # everything Cirdan observed, generated, executed, verified\n```\n\n## The access model\n\n**Cirdan inherits the agent's execution context.** It is not a permission manager; it is a mirror. If the session can read the repo, run shell, reach `/var/run/docker.sock`, use `kubectl`, or call AWS — Cirdan can use the same context, and nothing more. Run `cirdan access .` to see the live capability report.\n\n## Commands\n\n```bash\ncirdan map .                        # full pipeline: fingerprint → graph → artifacts\ncirdan fingerprint .                # what is this system? (with confidence + evidence)\ncirdan access .                     # capability mirror for the current session\ncirdan query \"what is running right now?\"\ncirdan query \"what depends on postgres?\"\ncirdan query \"what broke in the last hour?\"\ncirdan query \"what can the agent do here?\"\ncirdan show \"state\"                 # workload state table\ncirdan show \"show me the infrastructure map\"\ncirdan show \"show checkout-api as a dependency graph\"\ncirdan show \"show last night's incidents as a timeline\"\ncirdan incidents                    # detection pass + list\ncirdan explain \u003cincident-id|node\u003e   # evidence-backed explanation\ncirdan actions list \u003cnode\u003e          # what can be done with current access\ncirdan actions run \u003caction-id\u003e --yes\ncirdan verify \u003cact-record-id\u003e       # did the system actually recover?\ncirdan watch .                      # foreground event stream\ncirdan serve-mcp                    # MCP server over stdio\ncirdan setup                        # set up all of Cirdan: agents + MCP + responder + map + daemon\ncirdan setup --all                  # same, non-interactive (every step, no prompts)\ncirdan setup --system               # set up machine-level scope in ~/.cirdan\ncirdan install --project            # alias for the project-scope guided setup\n```\n\n## Always ON\n\n```bash\ncirdand serve                        # watch, refresh, detect, export — forever\ncirdand serve --mcp                  # + MCP (stdio)\ncirdand serve --http --mcp --host 0.0.0.0 --port 8090   # shared team server\n```\n\nThe daemon runs supervised loops: access refresh, fingerprint refresh, graph refresh, Docker/Kubernetes event watching, telemetry ingestion, incident detection, verification, and artifact export. A crashing loop logs and restarts; it never takes the daemon down.\n\nOne instance per scope: a second `cirdand serve` (or `cirdan watch`) against the same scope is refused with the running pid. `cirdan status` / `cirdan stop` (also available on `cirdand`) inspect and shut it down.\n\n## Watch the whole machine\n\nProjects aren't the only scope. The live adapters (Docker, Kubernetes, AWS, systemd) see everything the session can reach regardless of directory — so Cirdan has a **system scope** that watches all of it autonomously, independent of any repo:\n\n```bash\ncirdan setup --system        # guided: map everything + start the machine-level daemon\ncirdan map --system          # fingerprint + graph everything this session can reach\ncirdan query \"what broke?\" --system\ncirdan status --system       # the system daemon\n```\n\nSystem scope lives in `~/.cirdan/` (graph, incidents, briefs, daemon, optional `cirdan.yaml` for responder/webhook settings) and skips repo scanning — declared-vs-live drift stays a per-project concern, while the system daemon watches the live world: every container, cluster, cloud account, and failing unit. Project daemons and the system daemon run independently.\n\nOnce `~/.cirdan/` exists, the flag is mostly optional: a command run outside any cirdan project (no `cirdan.yaml`, `cirdan-out/`, or registered `.mcp.json`) falls back to the system scope automatically — with a one-line stderr notice — instead of scattering `cirdan-out/` directories or failing in unwritable locations. Inside a project, project scope always wins.\n\n`cirdan setup --system` also hooks your agents at the user level (instruction files whose examples carry `--system`) and registers Cirdan as a **user-scope MCP server** for the agent CLIs that support it — Claude Code and Codex through their own `mcp add`, VS Code through `code --add-mcp`, and Cursor, Gemini, Windsurf, opencode, and Goose through their global config — so the MCP tools are available in every project without per-repo setup.\n\n## Agent integration\n\n```bash\ncirdan install --project             # full guided setup (recommended, see below)\ncirdan setup                         # re-run the guided setup anytime, step by step\ncirdan install --platform claude     # .claude/skills/cirdan/SKILL.md + CLAUDE.md + .mcp.json\ncirdan install --platform codex      # AGENTS.md + .codex/cirdan.md\ncirdan install --platform cursor     # .cursor/rules/cirdan.mdc + .cursor/mcp.json\ncirdan install --platform gemini     # GEMINI.md\ncirdan install --platform vscode     # .github/copilot-instructions.md + .vscode/mcp.json\ncirdan install --platform windsurf   # .windsurf/rules/cirdan.md  (MCP: global config)\ncirdan install --platform roo        # .roo/rules/cirdan.md + .roo/mcp.json\ncirdan install --platform cline      # .clinerules/cirdan.md  (MCP: editor UI)\ncirdan install --platform opencode   # AGENTS.md + opencode.json\ncirdan install --platform goose      # .goosehints  (MCP: global config)\ncirdan install --platform generic    # .agents/skills/cirdan/SKILL.md + AGENTS.md\n```\n\n`cirdan install --project` is a guided setup that leaves Cirdan in full use, not just documented:\n\n1. **detects the agents on your machine** (claude/codex/cursor/gemini/vscode/windsurf/opencode/goose config or CLIs) and writes instruction files for exactly those (plus generic `AGENTS.md`)\n2. **registers the MCP server** in `.mcp.json`\n3. **arms the incident responder** so daemon alerts route to your agent\n4. **runs the first map** (graph + artifacts in `cirdan-out/`)\n5. **starts the always-on daemon** (detached; `cirdand status` / `cirdand stop`)\n\nSteps 3–5 are prompted (default yes) or driven by flags for scripts: `--responder/--no-responder`, `--map/--no-map`, `--daemon/--no-daemon`, `--all-platforms`. Re-run any of it later with `cirdan setup`, which shows each step's current state and only proposes what's missing.\n\nInstalls are idempotent and never touch content outside Cirdan's own marker block. MCP tools include `describe_system`, `describe_node`, `query_infra_graph`, `get_node`, `get_neighbors`, `shortest_path`, `get_recent_errors`, `get_logs`, `get_state`, `list_incidents`, `explain_incident`, `list_available_actions`, `execute_action`, `verify_action`, `generate_view`, and more. The node-scoped tools accept `node_id` as an alias for `node_ref`.\n\n**New in 0.9.0:** one-call answers for more ops questions — `describe_node` returns a node's **restart/impact** (blast radius *and* the prerequisites that must be healthy first) in a single call; `query_infra_graph` gains a **restart/impact** intent and an **external-providers** intent (third-party SaaS vendors vs managed cloud infra, each with their callers); dependency/dependent answers now state their **complete, authoritative set** so agents don't re-query; subject resolution prefers exact matches over fuzzy substrings; and **cross-lane reconciliation** links the same resource across Compose/Terraform/Kubernetes with evidence-backed `SAME_AS` edges.\n\n**Supported agents.** First-class auto-registration (native instruction file + MCP where the agent supports a writable config) covers Claude Code, Codex, Cursor, Gemini, VS Code (+ GitHub Copilot), Windsurf, Roo Code, Cline, opencode, and Goose. Any other agent works through the generic `AGENTS.md` + `.agents/skills/cirdan/SKILL.md`. Auto-detection finds claude/codex/cursor/gemini/vscode/windsurf/opencode/goose; pass `--platform roo` or `--platform cline` explicitly (they're VS Code extensions with no CLI to detect, and Cline keeps MCP config in editor storage, so add that one through its UI).\n\nFor any MCP client not listed, register Cirdan by hand — no Python required:\n\n```jsonc\n// npx form — zero install\n{ \"command\": \"npx\", \"args\": [\"-y\", \"@cirdanops/cli\", \"serve-mcp\"] }\n// or, if `cirdan` is already on PATH (pip / npm -g / brew / curl install):\n{ \"command\": \"cirdan\", \"args\": [\"serve-mcp\"] }\n```\n\n## The graph\n\nEvery node and edge carries **evidence** and a **confidence label** (`EXTRACTED`, `INFERRED`, `AMBIGUOUS`, `UNKNOWN`):\n\n```json\n{\n  \"source\": \"service:checkout-api\",\n  \"target\": \"database:postgres-prod\",\n  \"relation\": \"CONNECTS_TO\",\n  \"confidence\": \"INFERRED\",\n  \"evidence\": [\"DATABASE_URL references postgres://postgres-prod… in k8s/checkout.yaml\"]\n}\n```\n\nCirdan maintains a **static graph** (what the repo says should exist: Compose, Kubernetes YAML, Terraform/OpenTofu, Helm, CI, SQL, nginx, systemd units) and a **live graph** (what actually exists: Docker Engine, Kubernetes API, AWS, systemd, Prometheus), merges them, and reports drift — declared-but-not-running, running-but-undeclared, degraded capacity, unhealthy state.\n\n## Agents don't just read the graph — they build it\n\nLike Graphify's hybrid model (deterministic tree-sitter lane for code, LLM lane for docs/semantics), Cirdan's graph has two lanes. Adapters extract what's parseable — that's the always-on, token-free lane, labeled `EXTRACTED`. Agents contribute what isn't: relationships described in READMEs and runbooks, implied by code, or known to operators. Contributions require evidence quotes, are capped at `INFERRED`/`AMBIGUOUS` (an agent can never overwrite a deterministic claim), and carry the contributing agent's name.\n\n```bash\ncirdan enrich                # hand your agent a brief of what the scanners left\n                             # unconnected (isolated nodes, unlinked IaC, docs to read)\ncirdan enrich --dry-run      # just see the brief\ncirdan graph add-edge payment-worker orders DEPENDS_ON \\\n  --evidence \"ARCHITECTURE.md: 'the worker drains the orders queue nightly'\"\n```\n\nMCP-connected agents get the same surface as tools: `upsert_node`, `upsert_edge`, `annotate_node`, `get_enrichment_targets`. Contributions appear in `INFRA_REPORT.md` under \"Agent-contributed knowledge\" and as dashed edges in `infra.html`.\n\n## Incident responder: the agent loop\n\nDetection is automatic; response can be too. When a high/critical incident opens, the daemon writes an **incident brief** (`cirdan-out/incidents/briefs/\u003cid\u003e.md` — evidence, blast radius, available actions, instructions) and, if a responder command is configured, **invokes your agent against it**:\n\n```yaml\n# cirdan.yaml — normally wired by `cirdan install --project`, which detects\n# claude/codex/gemini/aider on PATH and asks you once\nresponder:\n  command: 'claude -p \"Respond to the Cirdan incident brief at {brief_file}\"'\n  webhook_url: https://hooks.slack.com/services/…   # optional notify on open/resolve\n```\n\nThe agent investigates and fixes through Cirdan's own tools (`cirdan actions run … --yes`), every action attaches to the incident and is verified, the incident auto-resolves when the condition stays clear, and the whole exchange lands in `audit.jsonl`. Invocations are cooldown-limited per incident condition. Test your setup with `cirdan respond \u003cincident-id\u003e --dry-run`.\n\n## Actions and verification\n\nCirdan detects which operations are *technically possible* with the session's access (`docker restart`, `kubectl rollout restart`, `systemctl restart`, …), exposes them as graph-attached capabilities, executes only through the session's own tools, records pre/post state in the audit trail, and verifies the outcome (workload ready, health checks passing, error clusters quiet). There is no separate credential store and no privilege escalation.\n\n## HTTP API\n\nWith the `[api]` extra, `cirdand serve --http` exposes `/health`, `/fingerprint`, `/graph`, `/graph/query`, `/services`, `/incidents`, `/actions`, `/views/generate`, `/audit`, and a minimal OTLP/HTTP JSON receiver at `/v1/logs`. Add `--mcp` to mount the MCP server at `/mcp`.\n\n## Configuration\n\nZero config works. `cirdan.yaml` refines it — see [`cirdan.yaml.example`](cirdan.yaml.example).\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadanb13%2Fcirdan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadanb13%2Fcirdan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadanb13%2Fcirdan/lists"}