{"id":48421645,"url":"https://github.com/saturate/husk","last_synced_at":"2026-06-30T14:00:18.202Z","repository":{"id":340855782,"uuid":"1165451044","full_name":"Saturate/HUSK","owner":"Saturate","description":"Observability meets context engineering for AI agents. Monitor, extract knowledge, track secrets, surface context. OTel-native.","archived":false,"fork":false,"pushed_at":"2026-06-30T13:08:46.000Z","size":2864,"stargazers_count":0,"open_issues_count":16,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T14:00:16.432Z","etag":null,"topics":["agent-observability","ai","ai-agents","claude-code","context-engineering","mcp","memory","ollama","opentelemetry","otel","qdrant","secret-scanning","self-hosted","tracing"],"latest_commit_sha":null,"homepage":"https://husk.akj.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Saturate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["Saturate"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2026-02-24T07:15:34.000Z","updated_at":"2026-06-30T13:08:50.000Z","dependencies_parsed_at":"2026-02-27T02:04:01.664Z","dependency_job_id":"14bf5313-e51e-45b5-b4a3-b8fde0945f9e","html_url":"https://github.com/Saturate/HUSK","commit_stats":null,"previous_names":["saturate/yams","saturate/husk"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/Saturate/HUSK","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saturate%2FHUSK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saturate%2FHUSK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saturate%2FHUSK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saturate%2FHUSK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Saturate","download_url":"https://codeload.github.com/Saturate/HUSK/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saturate%2FHUSK/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34969682,"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-30T02:00:05.919Z","response_time":92,"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-observability","ai","ai-agents","claude-code","context-engineering","mcp","memory","ollama","opentelemetry","otel","qdrant","secret-scanning","self-hosted","tracing"],"created_at":"2026-04-06T08:32:56.942Z","updated_at":"2026-06-30T14:00:18.195Z","avatar_url":"https://github.com/Saturate.png","language":"TypeScript","funding_links":["https://github.com/sponsors/Saturate"],"categories":[],"sub_categories":[],"readme":"# HUSK\n\nOTel-native observability and context engineering for AI coding agents.\n\nCollects traces from Claude Code (and other agents), stores them as OTel spans, runs trufflehog against the trace data to find leaked secrets, breaks down cost and token usage per model, and compresses sessions into knowledge that gets injected into future sessions via MCP. You can look up what happened in any session through the web UI. The agent can query its own history whenever it needs to.\n\n## How it works\n\n```mermaid\ngraph LR\n    A[Coding Agent] --\u003e|OTel traces| B[HUSK]\n    A --\u003e|Hooks| B\n    A \u003c--\u003e|MCP tools| B\n    B --\u003e C[Traces \u0026 Spans]\n    C --\u003e D[Knowledge Pipeline]\n    D --\u003e E[Session Summaries]\n    E --\u003e|Context injection| A\n    C --\u003e F[Secret Scanner]\n    C --\u003e G[Usage Analytics]\n```\n\nHUSK receives telemetry, stores it as OTel-shaped traces and spans, then runs three pipelines: knowledge derivation (compress sessions into searchable memories), secret scanning (flag leaked credentials via trufflehog), and usage analytics (cost, tokens, model comparison).\n\n```mermaid\ngraph TB\n    subgraph Ingestion\n        OTel[OTLP Receiver]\n        Hooks[Hook Endpoints]\n        API[Custom API]\n    end\n    subgraph Storage\n        SQLite[(SQLite)]\n        Postgres[(PostgreSQL)]\n    end\n    subgraph Intelligence\n        Knowledge[Knowledge Pipeline]\n        Secrets[Secret Scanner]\n        Stats[Usage Analytics]\n        Context[Context Engine]\n    end\n    subgraph Interfaces\n        UI[Web Dashboard]\n        MCP[MCP Tools]\n        Export[OTLP Export]\n    end\n    OTel --\u003e SQLite\n    Hooks --\u003e SQLite\n    API --\u003e SQLite\n    OTel --\u003e Postgres\n    SQLite --\u003e Knowledge\n    SQLite --\u003e Secrets\n    SQLite --\u003e Stats\n    Knowledge --\u003e Context\n    Context --\u003e MCP\n    SQLite --\u003e UI\n    SQLite --\u003e MCP\n    SQLite --\u003e Export\n```\n\n## Quick start\n\n```bash\ngit clone https://github.com/Saturate/HUSK.git\ncd HUSK \u0026\u0026 bun install\n\n# Fully local, no Docker, no external services:\nHUSK_EMBEDDINGS=transformers HUSK_STORAGE=sqlite-vec bun run server/src/index.ts\n```\n\nOpen `http://localhost:3000/setup` to create your admin account.\n\n### Connect Claude Code\n\nHUSK accepts Claude Code's native OTel telemetry. Add to your Claude Code `settings.json`:\n\n```json\n{\n  \"env\": {\n    \"CLAUDE_CODE_ENABLE_TELEMETRY\": \"1\",\n    \"OTEL_EXPORTER_OTLP_ENDPOINT\": \"http://localhost:3000\",\n    \"OTEL_EXPORTER_OTLP_PROTOCOL\": \"http/protobuf\"\n  }\n}\n```\n\nOr route through Grafana Alloy for fan-out to multiple backends (HUSK + Grafana + Datadog + whatever speaks OTLP).\n\nFor MCP tools (search memories, query traces, compress sessions), add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"husk\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:3000/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer husk_your-key\" }\n    }\n  }\n}\n```\n\n## What you get\n\n**Dashboard** with cost cards, daily spend chart, project breakdown, model comparison.\n\n**Session tracing** with filterable trace list and a span detail viewer showing every turn, tool call, and subagent in a session.\n\n**Model analytics** comparing token output per turn, cost per turn, and cache hit rates across model families. (Opus 4.8 outputs 3x more tokens per turn than 4.6. The data makes this visible.)\n\n**Secret scanning** powered by trufflehog. Scans trace data for leaked credentials that were exposed to the model provider through tool calls. Found real verified Storyblok and AbuseIPDB key leaks in historical sessions.\n\n**Knowledge derivation** from telemetry. Sessions get compressed into structured summaries (what was asked, what was done, what was learned, what's next) and stored as searchable memories.\n\n**MCP tools** the agent can use mid-session: `cost_summary`, `tool_stats`, `get_trace_summary`, `get_trace_spans`, `compress_trace`, `scan_secrets`, `project_insights`.\n\n## Architecture\n\nEverything is pluggable via a provider pattern:\n\n| Layer | Options |\n|---|---|\n| **Telemetry storage** | SQLite (default), PostgreSQL |\n| **Telemetry source** | OTLP receiver, custom API, legacy hooks |\n| **Embeddings** | Ollama, Transformers.js (local), OpenAI, Voyage, llama.cpp |\n| **Vector store** | Qdrant, SQLite-vec (local) |\n| **Compression** | Anthropic, OpenRouter, Ollama |\n| **Graph** | SQLite, Neo4j |\n| **OTLP export** | Optional dual-write to any OTLP backend |\n\nThree deployment modes:\n\n**Standalone** (local SQLite, zero config) - install, run, point Claude Code at it.\n\n**Fan-out target** (behind Alloy) - HUSK is one OTLP destination alongside Grafana, Datadog, whatever.\n\n**Grafana-backed** (future) - HUSK reads traces from Tempo, owns only the knowledge layer.\n\n## Configuration\n\nEnvironment variables or `husk.toml`. Env vars take priority.\n\n| Variable | Default | What it does |\n|---|---|---|\n| `HUSK_TELEMETRY` | `sqlite` | Telemetry backend (`sqlite`, `postgres`, `otlp`) |\n| `HUSK_TELEMETRY_URL` | - | PostgreSQL connection string |\n| `HUSK_OTLP_AUTH` | `true` | Set `false` for local-only OTLP without auth |\n| `HUSK_STORAGE` | `qdrant` | Vector backend (`qdrant`, `sqlite-vec`) |\n| `HUSK_EMBEDDINGS` | `ollama` | Embedding backend (`ollama`, `transformers`, `openai`, `voyage`) |\n| `HUSK_COMPRESSION_MODE` | `client` | `client` (agent compresses) or `server` (auto) |\n| `HUSK_PORT` | `3000` | Server port |\n\n## Development\n\n```bash\nbun install\ncd server \u0026\u0026 bun run dev     # hot reload\ncd server \u0026\u0026 bun test        # 312 tests\ncd server \u0026\u0026 bun run check   # lint + format\ncd server \u0026\u0026 bun run build:ui  # rebuild frontend\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaturate%2Fhusk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaturate%2Fhusk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaturate%2Fhusk/lists"}