{"id":51516710,"url":"https://github.com/timoncool/satori","last_synced_at":"2026-07-08T12:30:24.255Z","repository":{"id":369921828,"uuid":"1292246063","full_name":"timoncool/satori","owner":"timoncool","description":"Self-learning loop for Claude Code — corrections and failures become skills, behind a human gate. MCP + hooks, Windows-native, zero background LLM calls.","archived":false,"fork":false,"pushed_at":"2026-07-07T13:54:51.000Z","size":158,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-07T14:03:34.683Z","etag":null,"topics":["ai-agents","anthropic","claude","claude-code","continuous-learning","mcp","mcp-server","self-improving","skills"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/timoncool.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":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://github.com/timoncool/ACE-Step-Studio/blob/master/DONATE.md","https://dalink.to/nerual_dreming","https://boosty.to/neuro_art"]}},"created_at":"2026-07-07T11:40:46.000Z","updated_at":"2026-07-07T13:56:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/timoncool/satori","commit_stats":null,"previous_names":["timoncool/satori"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/timoncool/satori","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoncool%2Fsatori","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoncool%2Fsatori/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoncool%2Fsatori/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoncool%2Fsatori/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timoncool","download_url":"https://codeload.github.com/timoncool/satori/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timoncool%2Fsatori/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35265380,"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-07-08T02:00:06.796Z","response_time":61,"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":["ai-agents","anthropic","claude","claude-code","continuous-learning","mcp","mcp-server","self-improving","skills"],"created_at":"2026-07-08T12:30:23.439Z","updated_at":"2026-07-08T12:30:24.248Z","avatar_url":"https://github.com/timoncool.png","language":"Python","funding_links":["https://github.com/timoncool/ACE-Step-Studio/blob/master/DONATE.md","https://dalink.to/nerual_dreming","https://boosty.to/neuro_art"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# satori\n\n**A self-learning loop for Claude Code — the model learns skills from its own sessions. Fully automatic, fully visible, fully reversible.**\n\n[![Status](https://img.shields.io/badge/status-beta-orange?style=flat-square)](#-beta-disclaimer)\n[![License](https://img.shields.io/github/license/timoncool/satori?style=flat-square)](LICENSE)\n[![Stars](https://img.shields.io/github/stars/timoncool/satori?style=flat-square)](https://github.com/timoncool/satori/stargazers)\n[![Last Commit](https://img.shields.io/github/last-commit/timoncool/satori?style=flat-square)](https://github.com/timoncool/satori/commits)\n\n**[English](README.md)** · **[Русский](README_RU.md)**\n\n![satori](docs/screenshots/hero.png)\n\n\u003c/div\u003e\n\n\u003e ### ⚠️ Beta disclaimer\n\u003e This is **beta software** I build for myself and share with the community as-is. It parses your session transcripts, stores lesson data locally and — **by default, automatically** — activates skills that will instruct your future Claude sessions. Every activation is announced in chat (⛩) and reversible in one call (`retire_skill`), but do read `server.py` and watch what your agent learns. It works on my setup; I can't guarantee yours and **take no responsibility** for the skills your agent teaches itself. Want to pre-approve everything instead? `SATORI_AUTO_APPROVE=0`.\n\nsatori is an MCP server + hooks that give Claude Code a closed self-learning loop: user corrections and tool failures become lesson candidates, lessons become skill drafts, drafts become active skills — automatically, visibly, reversibly. Windows-native, works in Claude Desktop, zero bash wrappers.\n\nTwo principles you won't find together elsewhere: **the server does only deterministic mechanics** (parsing, counters, storage, validation) — the thinking is done by the calling model right in the session, no background LLM calls, no extra bills; and **fully automatic, fully visible, fully reversible** — validated drafts activate on their own, every loop event is announced in chat with a ⛩ marker, and `retire_skill` undoes any activation in one call (prefer a manual approval gate instead? `SATORI_AUTO_APPROVE=0`).\n\n## Features\n\n- **4-stage loop** — capture → decide → distill → curate; `reflect()` is called several times per session\n- **User correction = signal #1** — surfaces as a candidate after a single occurrence (Devin's mechanic); tool failures wait for recurrence\n- **Patch-not-append** — a recurring signal bumps `seen_count` instead of piling up rows\n- **SKIP gate, forever** — \"not skill-worthy\" verdicts are remembered; rejected noise never comes back\n- **Fully automatic** — a validated draft activates immediately (backup of anything it overwrites, `retire_skill` = one-call undo); `SATORI_AUTO_APPROVE=0` switches to a manual staging gate\n- **The trigger is sacred** — `description: Use when ...` is mandatory: recall works when a note says *when* to recall it, not what it does\n- **pinned_project** — a lesson is global or pinned to one project; approve routes it to the right skills folder\n- **Draft validation** — frontmatter, size, secrets (also redacted at rest), prompt-injection markers (EN+RU)\n- **FTS5 search over past sessions** — \"when did I fix exactly this error\" finds the actual transcript\n- **Curator** — usage telemetry; unused drafts go stale in 30 days, archived in 90\n- **Smart nudge hooks** — silent by default; they speak only on a correction (instantly) or accumulated work; a declined nudge stays declined\n- **Visible audit trail** — every loop event surfaces in chat as a ⛩ marker line: what fired, why, what was staged or skipped\n- **dream/wake integration** — the [dream-skill](https://github.com/timoncool/dream-skill) consolidation pass harvests satori's staging and promotes/retires drafts through its validator gate\n\n## Quick Start\n\n**Easiest — let Claude install it.** Paste this message into Claude Code:\n\n```text\nInstall the satori self-learning loop from https://github.com/timoncool/satori:\n1) clone the repo to a permanent location (not a temp dir — the MCP runs from it);\n2) create a venv inside it and install the single dependency: fastmcp;\n3) register the MCP in my .mcp.json (project or global) as \"satori\" with\n   command = absolute path to the venv python and args = [absolute path to server.py];\n4) recommended: add the three nudge hooks (UserPromptSubmit / Stop / SessionEnd,\n   all calling hooks/nudge.py with the venv python — exact JSON is in the README\n   \"Quick Start\" step 3) into ~/.claude/settings.json, PRESERVING my existing hooks;\n5) smoke-test: import server in the venv and show me what got configured;\nthen remind me to restart Claude Code / Desktop so the MCP and hooks load.\n```\n\nThat's it — Claude clones, wires configs, verifies and reports. Manual way:\n\n1. **Clone \u0026 install the one dependency**\n   ```bash\n   git clone https://github.com/timoncool/satori.git\n   cd satori \u0026\u0026 python -m venv .venv \u0026\u0026 .venv\\Scripts\\pip install fastmcp\n   ```\n\n2. **Register the MCP** — in your project's `.mcp.json` (or global config):\n   ```jsonc\n   \"satori\": {\n     \"command\": \"\u003cpath\u003e\\\\satori\\\\.venv\\\\Scripts\\\\python.exe\",\n     \"args\": [\"\u003cpath\u003e\\\\satori\\\\server.py\"]\n   }\n   ```\n\n3. **(Optional) nudge hooks** — three hooks onto one script in `~/.claude/settings.json`:\n   ```jsonc\n   \"UserPromptSubmit\": [{\"matcher\": \"\", \"hooks\": [{\"type\": \"command\", \"command\": \"\u003cvenv-python\u003e \u003cpath\u003e/hooks/nudge.py prompt-submit\", \"timeout\": 10}]}],\n   \"Stop\":             [{\"matcher\": \"\", \"hooks\": [{\"type\": \"command\", \"command\": \"\u003cvenv-python\u003e \u003cpath\u003e/hooks/nudge.py stop\", \"timeout\": 10}]}],\n   \"SessionEnd\":       [{\"matcher\": \"\", \"hooks\": [{\"type\": \"command\", \"command\": \"\u003cvenv-python\u003e \u003cpath\u003e/hooks/nudge.py session-end\", \"timeout\": 60}]}]\n   ```\n   Restart Claude Code / Desktop.\n\n## How it works\n\n```\nsession transcript\n      │  (hook/tool call — parsing costs 0 tokens)\n      ▼\n① capture   reflect() reads what's new since the stored offset: corrections,\n            failures, fix-after-fail, complex segments (≥12 calls + ≥2 edits)\n      ▼\n② decide    the model judges candidates (corrections after 1×, the rest after 2×):\n            noise → skip_lesson (forever), worthy → a draft\n      ▼\n③ distill   submit_draft → validated, provenance-stamped, staged AND auto-activated\n            into ~/.claude/skills/ (or the pinned project). ⛩ announced in chat;\n            retire_skill = one-call undo. Manual gate: SATORI_AUTO_APPROVE=0\n      ▼\n④ curate    usage telemetry, stale at 30d, archive at 90d\n```\n\n**Hooks** (all optional, all silent by default): `UserPromptSubmit` — on a correction injects one line \"fix it, then reflect\" (series-deduplicated); on ≥25 accumulated tool calls — same, and repeats only after the next full threshold; `Stop` — same threshold at turn end; `SessionEnd` — silent capture directly in Python, no model involved at all. When a nudge does fire, the model opens its reply with a visible `⛩ satori: ...` marker and reports what was recorded — you always see the loop working.\n\n**Anti-pollution by construction:** the loop never writes into Claude's memory (only its own SQLite + staging); context injections are one line and only when warranted; an ignored nudge doesn't nag.\n\n## Tools\n\n| Tool | What it does |\n|------|-------------|\n| `reflect(transcript_path?)` | stages 1+2+4: signals since offset, aggregation, candidates + similar existing skills, curator tick |\n| `skip_lesson(key, reason)` | permanent SKIP |\n| `submit_draft(name, markdown, lesson_key?, patches?, pinned_project?)` | draft into staging with full validation |\n| `retire_skill(name)` | one-call undo: live skill + staging copy → archive, pre-activation backup restored |\n| `approve_draft(name, dest_dir?)` | manual-mode gate (`SATORI_AUTO_APPROVE=0`): staging → active skills |\n| `session_search(query, limit?)` | FTS5 over all past transcripts |\n| `loop_status()` | loop telemetry |\n\n## Configuration (env)\n\n| Variable | Default | Meaning |\n|---|---|---|\n| `SATORI_AUTO_APPROVE` | 1 | fully automatic activation; 0 = manual staging gate |\n| `SN_PROMOTE_AT` | 2 | recurrences before a candidate (except corrections) |\n| `SN_CORRECTION_PROMOTE_AT` | 1 | user corrections surface immediately |\n| `SN_SEGMENT_TOOL_CALLS` / `SN_SEGMENT_FILE_EDITS` | 12 / 2 | \"complex segment\" threshold |\n| `SN_STALE_DAYS` / `SN_ARCHIVE_DAYS` | 30 / 90 | draft aging |\n| `SN_NUDGE_MIN_CALLS` | 25 | accumulated work before a nudge |\n| `SN_NUDGE_COOLDOWN_MIN` / `SN_CORR_COOLDOWN_MIN` | 10 / 3 | nudge cooldowns |\n| `SN_STOP_NUDGE` | 1 | Stop-hook nudge (0 = off) |\n\n## Works best with dream-skill\n\n[**dream-skill**](https://github.com/timoncool/dream-skill) is this project's sibling — memory consolidation for Claude Code (dream = read-only pass, wake = gated apply, full rollback). satori handles **procedural memory** (skills), dream/wake handles **factual memory** (notes, rules, index) — and they meet in the middle:\n\n- satori runs fully automatic *inside* sessions; dream is the periodic *auditor*: its **Skill harvest** phase reads satori's staging + usage telemetry and proposes `retire_skill` for stale/duplicate self-taught skills (and `promote_skill` if you run satori in manual mode)\n- dream's validator re-checks every self-taught skill against a hard checklist: `Use when` trigger, no injection markers, no duplicates\n- wake applies the audit, logs everything, and its `rollback` restores skills too\n\nEach works standalone; together the cycle is complete: сон → пробуждение → прозрение (dream → wake → satori).\n\n## Standing on shoulders\n\nAn honest list of sources: [Hermes Agent](https://github.com/NousResearch/hermes-agent) (Nous) — the 4-stage cycle, FTS5, periodic self-reflection; [claude-self-improving-skills](https://github.com/UniM0cha/claude-self-improving-skills) — complexity thresholds, patch-over-create, curator, telemetry, \"declined stays declined\"; [claude-evolve](https://github.com/taipm/claude-evolve) — objective signals, patch-not-append; [claude-harness-hermes](https://github.com/jjackkun/claude-harness-hermes) — permanent SKIP, redaction at rest; Devin (Cognition) — corrections at threshold 1, the trigger as a sacred field, pinned scoping, injection scanning; [dream-skill](https://github.com/timoncool/dream-skill) (ours) — the staging gate.\n\n## Other Projects by [@timoncool](https://github.com/timoncool)\n\n| Project | Description |\n|---------|-------------|\n| [dream-skill](https://github.com/timoncool/dream-skill) | Memory consolidation for Claude Code — dream/wake with a gate |\n| [trail-spec](https://github.com/timoncool/trail-spec) | TRAIL — cross-MCP content tracking protocol |\n| [telegram-api-mcp](https://github.com/timoncool/telegram-api-mcp) | Full Telegram Bot API as MCP server |\n| [civitai-mcp-ultimate](https://github.com/timoncool/civitai-mcp-ultimate) | Civitai API as MCP server |\n| [GitLife](https://github.com/timoncool/gitlife) | Your life in weeks — interactive calendar |\n\n## Authors\n\n- **Nerual Dreming** — [Telegram](https://t.me/nerual_dreming) | [neuro-cartel.com](https://neuro-cartel.com) | [ArtGeneration.me](https://artgeneration.me)\n\n## Support the Author\n\nI build open-source software and do AI research. Most of what I create is free and available to everyone. Your donations help me keep creating without worrying about where the next meal comes from =)\n\n**[All donation methods](https://github.com/timoncool/ACE-Step-Studio/blob/master/DONATE.md)** | **[dalink.to/nerual_dreming](https://dalink.to/nerual_dreming)** | **[boosty.to/neuro_art](https://boosty.to/neuro_art)**\n\n- **BTC:** `1E7dHL22RpyhJGVpcvKdbyZgksSYkYeEBC`\n- **ETH (ERC20):** `0xb5db65adf478983186d4897ba92fe2c25c594a0c`\n- **USDT (TRC20):** `TQST9Lp2TjK6FiVkn4fwfGUee7NmkxEE7C`\n\n## Star History\n\n\u003ca href=\"https://github.com/timoncool/satori/stargazers\"\u003e\n \u003cpicture\u003e\n   \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/stars-dark.svg\" /\u003e\n   \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"docs/stars-light.svg\" /\u003e\n   \u003cimg alt=\"Star History Chart\" src=\"docs/stars-light.svg\" /\u003e\n \u003c/picture\u003e\n\u003c/a\u003e\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimoncool%2Fsatori","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimoncool%2Fsatori","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimoncool%2Fsatori/lists"}