{"_id":"@dongnh311/claude-context-saver","_rev":"4-6ed36979ab782ff1ae974ea6438c8c30","name":"@dongnh311/claude-context-saver","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"@dongnh311/claude-context-saver","version":"0.1.0","keywords":["mcp","claude-code","anthropic","claude","token-optimization","log-compression","tree-sitter","ast","gradle","npm","jest","pytest","kotlin","typescript"],"author":{"name":"dongnh","email":"hoaidongit5@gmail.com"},"license":"MIT","_id":"@dongnh311/claude-context-saver@0.1.0","maintainers":[{"name":"dongnh311","email":"hoaidongit5@gmail.com"}],"homepage":"https://github.com/dongnh311/claude-context-saver#readme","bugs":{"url":"https://github.com/dongnh311/claude-context-saver/issues"},"bin":{"claude-context-saver":"dist/index.js"},"dist":{"shasum":"86a12a03e0066cf9742750672476243053fb1699","tarball":"https://registry.npmjs.org/@dongnh311/claude-context-saver/-/claude-context-saver-0.1.0.tgz","fileCount":43,"integrity":"sha512-1M/bkUrAjWbDAqS69HLcQJVgM7JEY8VlatGhmvDKeOtvPZL+zkHrlWXHlMcHn86yZFdlNrhaZ11QnsM806I1Qw==","signatures":[{"sig":"MEUCIF5kf6IqpadbKRuI3/c9vc2KmHVy6A31vuiUIXF/9m08AiEA62HMeaxQiOarFFsaGAWwcYKs5/URvxH3EXyMbF1jphI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120331},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"99c9291a601c8c26f25611edff62b0bf827819d0","scripts":{"dev":"tsc --watch","lint":"biome check src test","test":"vitest run","bench":"tsx scripts/benchmark.ts","build":"tsc","clean":"rm -rf dist","start":"node dist/index.js","format":"biome format --write src test","postbuild":"node -e \"import('node:fs').then(fs => { const p='dist/index.js'; const s=fs.readFileSync(p,'utf8'); if(!s.startsWith('#!')) fs.writeFileSync(p,'#!/usr/bin/env node\\n'+s); fs.chmodSync(p,0o755); })\"","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run clean && npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"dongnh311","email":"hoaidongit5@gmail.com"},"repository":{"url":"git+https://github.com/dongnh311/claude-context-saver.git","type":"git"},"_npmVersion":"10.9.7","description":"MCP server that cuts Claude Code token usage. Two capabilities: log compression (build/test/install output) and smart file reading (AST-backed symbol-level source access). Context-efficient tooling for Pro-tier users.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","vitest":"^2.1.5","typescript":"^5.6.3","@types/node":"^22.9.0","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/claude-context-saver_0.1.0_1776844742359_0.5971767159269643","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dongnh311/claude-context-saver","version":"0.1.1","keywords":["mcp","claude-code","anthropic","claude","token-optimization","log-compression","tree-sitter","ast","gradle","npm","jest","pytest","kotlin","typescript"],"author":{"name":"dongnh","email":"hoaidongit5@gmail.com"},"license":"MIT","_id":"@dongnh311/claude-context-saver@0.1.1","maintainers":[{"name":"dongnh311","email":"hoaidongit5@gmail.com"}],"homepage":"https://github.com/dongnh311/claude-context-saver#readme","bugs":{"url":"https://github.com/dongnh311/claude-context-saver/issues"},"bin":{"claude-context-saver":"dist/index.js"},"dist":{"shasum":"04db89c7c5dbe7f6c96625d4b2cc5185f85fa510","tarball":"https://registry.npmjs.org/@dongnh311/claude-context-saver/-/claude-context-saver-0.1.1.tgz","fileCount":43,"integrity":"sha512-nPgy+A/zNtz4WtBJQwx1D/jcgjX9upoDdk/ZKVv7mYjy+ssg93cRrCeEXnxrpQa1QtuNJq2PvqDcFknZaXJupw==","signatures":[{"sig":"MEQCIA+lJrpZErfYxRZczabGsEQcWgnKnkBpyAEe+UoZ2ZhaAiAh2CZNc1ZcR2nfwRpibBk1dx6aFxCTsqCiTRzqM2747Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120346},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"9573182e94272da8689556aae02ff05e612030a8","scripts":{"dev":"tsc --watch","lint":"biome check src test","test":"vitest run","bench":"tsx scripts/benchmark.ts","build":"tsc","clean":"rm -rf dist","start":"node dist/index.js","format":"biome format --write src test","postbuild":"node -e \"import('node:fs').then(fs => { const p='dist/index.js'; const s=fs.readFileSync(p,'utf8'); if(!s.startsWith('#!')) fs.writeFileSync(p,'#!/usr/bin/env node\\n'+s); fs.chmodSync(p,0o755); })\"","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run clean && npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"dongnh311","email":"hoaidongit5@gmail.com"},"repository":{"url":"git+https://github.com/dongnh311/claude-context-saver.git","type":"git"},"_npmVersion":"10.9.7","description":"MCP server that cuts Claude Code token usage. Two capabilities: log compression (build/test/install output) and smart file reading (AST-backed symbol-level source access). Context-efficient tooling for Pro-tier users.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","vitest":"^2.1.5","typescript":"^5.6.3","@types/node":"^22.9.0","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/claude-context-saver_0.1.1_1776844813078_0.8105562542040512","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@dongnh311/claude-context-saver","version":"0.2.0","keywords":["mcp","claude-code","anthropic","claude","token-optimization","log-compression","tree-sitter","ast","gradle","npm","jest","pytest","kotlin","typescript"],"author":{"name":"dongnh","email":"hoaidongit5@gmail.com"},"license":"MIT","_id":"@dongnh311/claude-context-saver@0.2.0","maintainers":[{"name":"dongnh311","email":"hoaidongit5@gmail.com"}],"homepage":"https://github.com/dongnh311/claude-context-saver#readme","bugs":{"url":"https://github.com/dongnh311/claude-context-saver/issues"},"bin":{"claude-context-saver":"dist/index.js"},"dist":{"shasum":"80c79e9f6123115e86bdda66a0d1cc00390740e6","tarball":"https://registry.npmjs.org/@dongnh311/claude-context-saver/-/claude-context-saver-0.2.0.tgz","fileCount":72,"integrity":"sha512-wXZx751JqLMrNnUuELPoHEf01FwAgZYTe0Glwgxrkw5OLSAgWpm55FUzuQMO6Jvw/6eIaiouG84ztX8HI6AWlw==","signatures":[{"sig":"MEYCIQDIT7xudmjaaa9Lj/4l+345AeroLvzMEzhiSqfMG/XKiAIhAOQX6Qo/kIgyZpNFevNxGG2cy2AHhuUhgmA+stYfFSZx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9204688},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"a238f2a6e28587639d6c64a9073f3c8b2f147394","scripts":{"dev":"tsc --watch","lint":"biome check src test","test":"vitest run","bench":"tsx scripts/benchmark.ts","build":"tsc","clean":"rm -rf dist","start":"node dist/index.js","format":"biome format --write src test","postbuild":"node scripts/postbuild.mjs","typecheck":"tsc --noEmit","bench:file":"tsx scripts/bench-file-side.ts","test:watch":"vitest","prepublishOnly":"npm run clean && npm run typecheck && npm run build && npm test"},"_npmUser":{"name":"dongnh311","email":"hoaidongit5@gmail.com"},"repository":{"url":"git+https://github.com/dongnh311/claude-context-saver.git","type":"git"},"_npmVersion":"10.9.7","description":"MCP server that cuts Claude Code token usage. Two capabilities: log compression (build/test/install output) and smart file reading (AST-backed symbol-level source access). Context-efficient tooling for Pro-tier users.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"web-tree-sitter":"^0.22.6","@modelcontextprotocol/sdk":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","vitest":"^2.1.5","typescript":"^5.6.3","@types/node":"^22.9.0","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/claude-context-saver_0.2.0_1776846253649_0.8464106601630832","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@dongnh311/claude-context-saver","version":"0.2.1","description":"MCP server that cuts Claude Code token usage. Two capabilities: log compression (build/test/install output) and smart file reading (AST-backed symbol-level source access). Context-efficient tooling for Pro-tier users.","keywords":["mcp","claude-code","anthropic","claude","token-optimization","log-compression","tree-sitter","ast","gradle","npm","jest","pytest","kotlin","typescript"],"license":"MIT","author":{"name":"dongnh","email":"hoaidongit5@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/dongnh311/claude-context-saver.git"},"bugs":{"url":"https://github.com/dongnh311/claude-context-saver/issues"},"homepage":"https://github.com/dongnh311/claude-context-saver#readme","type":"module","main":"dist/index.js","bin":{"claude-context-saver":"dist/index.js"},"scripts":{"build":"tsc","postbuild":"node scripts/postbuild.mjs","dev":"tsc --watch","start":"node dist/index.js","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","lint":"biome check src test","format":"biome format --write src test","clean":"rm -rf dist","bench":"tsx scripts/benchmark.ts","bench:file":"tsx scripts/bench-file-side.ts","prepublishOnly":"npm run clean && npm run typecheck && npm run build && npm test"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.0","web-tree-sitter":"^0.22.6"},"devDependencies":{"@biomejs/biome":"^1.9.4","@types/node":"^22.9.0","tsx":"^4.19.2","typescript":"^5.6.3","vitest":"^2.1.5"},"engines":{"node":">=18"},"_id":"@dongnh311/claude-context-saver@0.2.1","gitHead":"28439b2b6b2cae525dc3865611c30f662135000b","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-Om0irYnzOocJVHnQr4m/l5H8PX8KGfV+lO8GNPvoZDGiUuka6bL52p8EIAUZRn46AcN64PT/BrwZrzpvzLBG3w==","shasum":"59f353fa2068db6f4fb1da45d202f21cf748986a","tarball":"https://registry.npmjs.org/@dongnh311/claude-context-saver/-/claude-context-saver-0.2.1.tgz","fileCount":74,"unpackedSize":9204409,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDntaI0vXKwBL8IebbUiP+mJu4RHd2Gny1T8KU+epbsPAIgJmyroTNtSPexiGXxfkruzZXTMPiAswMAT5MPj57FPNw="}]},"_npmUser":{"name":"dongnh311","email":"hoaidongit5@gmail.com"},"directories":{},"maintainers":[{"name":"dongnh311","email":"hoaidongit5@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/claude-context-saver_0.2.1_1776846680246_0.8325860612313698"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-22T07:59:02.260Z","modified":"2026-04-22T08:31:20.641Z","0.1.0":"2026-04-22T07:59:02.491Z","0.1.1":"2026-04-22T08:00:13.356Z","0.2.0":"2026-04-22T08:24:13.840Z","0.2.1":"2026-04-22T08:31:20.527Z"},"bugs":{"url":"https://github.com/dongnh311/claude-context-saver/issues"},"author":{"name":"dongnh","email":"hoaidongit5@gmail.com"},"license":"MIT","homepage":"https://github.com/dongnh311/claude-context-saver#readme","keywords":["mcp","claude-code","anthropic","claude","token-optimization","log-compression","tree-sitter","ast","gradle","npm","jest","pytest","kotlin","typescript"],"repository":{"type":"git","url":"git+https://github.com/dongnh311/claude-context-saver.git"},"description":"MCP server that cuts Claude Code token usage. Two capabilities: log compression (build/test/install output) and smart file reading (AST-backed symbol-level source access). Context-efficient tooling for Pro-tier users.","maintainers":[{"name":"dongnh311","email":"hoaidongit5@gmail.com"}],"readme":"# @dongnh311/claude-context-saver\n\n[![npm](https://img.shields.io/npm/v/@dongnh311/claude-context-saver.svg)](https://www.npmjs.com/package/@dongnh311/claude-context-saver)\n[![CI](https://github.com/dongnh311/claude-context-saver/actions/workflows/ci.yml/badge.svg)](https://github.com/dongnh311/claude-context-saver/actions/workflows/ci.yml)\n[![license](https://img.shields.io/npm/l/@dongnh311/claude-context-saver.svg)](./LICENSE)\n\n> MCP server that cuts Claude Code token usage through two cooperating capabilities:\n> **(1) log compression** for build/test/install output, **(2) smart file reading** for source code at the symbol level. Same philosophy: don't let raw, unfiltered content flood Claude's context — let Claude pull exactly what it needs.\n\n> **Note:** this package was originally published as `claude-log-compressor` (log side only). It has been renamed to `@dongnh311/claude-context-saver` now that file-side capabilities are landing. The old name is deprecated; please update your config (see Quick start).\n\n## Quick start\n\n**1.** Add to your Claude Code MCP config at `~/.claude/mcp.json` (or project `.claude/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"context-saver\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@dongnh311/claude-context-saver@latest\"]\n    }\n  }\n}\n```\n\nOr via CLI:\n\n```bash\nclaude mcp add context-saver -s user -- npx -y @dongnh311/claude-context-saver@latest\n```\n\n**2.** Restart Claude Code. Tools `smart_run`, `smart_build`, `smart_test`, `read_log_section` show up now. File-side tools (`smart_read`, `list_symbols`, `read_symbol`, `find_references_in_file`, `read_lines`) ship in `v0.2.0`.\n\n**3.** (Recommended) Nudge Claude in your project's `CLAUDE.md`:\n\n```markdown\n## Token-efficient tooling (claude-context-saver)\n- Build/test: use `smart_build` / `smart_test` instead of bash gradle/npm/jest/pytest.\n- File reading (from v0.2): prefer `smart_read` over `Read` for source files > 300 lines.\n```\n\n## Why\n\nTwo dominant sources of wasted tokens in a Claude Code session:\n\n- **Noisy command output.** `gradle build`, `npm install`, `pytest` can emit 5k–20k tokens per invocation, 90% of which is progress bars, deprecation warnings, and framework noise.\n- **Whole-file reads for narrow questions.** Claude reads a 2,000-line `MainActivity.kt` to fix one function; 90% of what goes into context is irrelevant.\n\nBoth compound quickly: the Pro 5-hour limit hits before the real work is done, prompt-cache hit rate drops, and the model's attention gets diluted.\n\n## How it works\n\nClaude calls the MCP tool instead of `bash`/`Read`. The server runs the command (or parses the file), keeps the heavy output on disk, and returns only a compact summary plus an id Claude can use to retrieve detail on demand.\n\n```\n[Claude] ──► smart_build(\"./gradlew assembleDebug\")\n              │\n              ▼\n         [context-saver]\n              │\n              ├─► run command → 12k tokens raw\n              │      │\n              │      ▼\n              │   classify → \"gradle\"\n              │      │\n              │      ▼\n              │   gradle compressor (errors, deduped warnings, failing task)\n              │      │\n              │      ▼\n              │   cache full log → ~/.cache/claude-context-saver/logs/grd_abc12345.log (7d TTL)\n              │\n              └─► return 0.8k token summary + log_id=\"grd_abc12345\"\n[Claude] ◄──\n```\n\nSame pattern for `smart_read`: parse file → return outline first, focused symbols on demand, cache AST for the session.\n\n## Tools — log side\n\n| Tool | Input (highlights) | What it does |\n|---|---|---|\n| `smart_run` | `command`, `cwd?`, `timeout_seconds?`, `max_output_tokens?` | Runs any shell command, auto-classifies output, returns compressed summary + `log_id`. |\n| `smart_build` | `tool?` (`gradle`/`npm`/`cargo`/`make`/`auto`), `args?`, `cwd?` | Auto-detects build tool from `cwd` (gradlew, package.json, Cargo.toml, Makefile). |\n| `smart_test` | `framework?` (`jest`/`pytest`/`junit`/`go`/`auto`), `pattern?`, `cwd?` | Auto-detects test framework (go.mod, pytest config, package.json, gradlew). |\n| `read_log_section` | `log_id`, `grep?`, `lines_around?`, `start_line?`/`end_line?`, `max_tokens?` | Slice a cached full log. Escape hatch when compressed view isn't enough. |\n\n## Tools — file side\n\n| Tool | Input | What it does |\n|---|---|---|\n| `smart_read` | `path`, `focus?`, `mode?` (`outline`/`full`/`auto`), `max_tokens?` | Smart replacement for Read. Returns outline first, focused symbols on demand. |\n| `list_symbols` | `path`, `kinds?`, `depth?` | Full symbol tree without bodies. |\n| `read_symbol` | `path`, `names[]` (dotted: `Class.method`), `include_surrounding?` | Return bodies of named symbols. |\n| `find_references_in_file` | `path`, `identifier`, `context_lines?` | AST-aware \"where is X used inside this file\" with `inside_symbol` annotation. |\n| `read_lines` | `path`, `start_line`, `end_line` | Line-range fallback when symbol approach doesn't fit. |\n\nLanguages supported for file side: Kotlin, Java, TypeScript/TSX, JavaScript/JSX, Python, Go, Rust. Swift deferred to a future release.\n\n## Benchmark — real Android project\n\nMeasured live on `./gradlew …` against a real Android Compose + C++/NDK project (MasterCamera, 2 Gradle modules):\n\n| Command | Raw tokens | Compressed | Reduction |\n|---|---:|---:|---:|\n| `clean :app:assembleDebug` | 2,090 | 82 | **96.1%** |\n| `clean :app:assembleRelease` (R8) | 2,720 | 82 | **97.0%** |\n| `:app:installDebug` → emulator | 955 | 3 | **99.7%** |\n| `:app:testDebugUnitTest` | 780 | 82 | **89.5%** |\n| `:app:compileDebugKotlin` (2 injected errors) | 667 | 114 | **82.9%** ⟵ both errors with `file:line:col` preserved |\n\nAverage ≈ **93%** reduction, 100% of errors and warnings kept.\n\n## Benchmark — real source files (file side)\n\nMeasured on actual Kotlin source from the same MasterCamera project:\n\n| File | Lines | Full | smart_read outline | smart_read focus | Reduction (outline) |\n|---|---:|---:|---:|---:|---:|\n| `CameraControl.kt` | 1,040 | 7,949 | 839 | 1,261 (focus=`startRecord`) | **89.4%** |\n| `Camera2Control.kt` | 951 | 8,721 | 878 | 893 (focus=`captureImage`) | **89.9%** |\n\nBoth files cleared the SPEC §2 target (\"≤20% of full-file tokens for a ≥1000-line Kotlin file\"). Focused mode still beats 80% reduction because the outline gets bundled with the body.\n\n## Benchmark — synthetic fixtures (log side)\n\n| Fixture | Kind | Original | Compressed | Reduction |\n|---|---|---:|---:|---:|\n| gradle-success.log | gradle | 1,005 | 64 | **93.6%** |\n| gradle-failure.log | gradle | 1,708 | 173 | **89.9%** |\n| jest-passing.log | jest | 242 | 34 | **86.0%** |\n| jest-failing.log | jest | 578 | 363 | 37.2% |\n| junit-failing.log | junit | 827 | 151 | **81.7%** |\n| npm-install-success.log | npm | 648 | 218 | 66.4% |\n| npm-install-fail.log | npm | 337 | 279 | 17.2% (info-dense) |\n| pytest-passing.log | pytest | 224 | 20 | **91.1%** |\n| pytest-failing.log | pytest | 583 | 333 | 42.9% |\n\nRun locally: `npm run bench`.\n\n## What each log compressor keeps / drops\n\n### Gradle\n- **Keep:** BUILD status + duration, every Kotlin/javac error with `file:line:col`, deduped warnings with occurrence counts (`[×3]`), failing task name, \"What went wrong\" block.\n- **Drop:** `> Task :xxx UP-TO-DATE/NO-SOURCE`, `Download …` URLs, Daemon startup chatter.\n\n### npm / yarn / pnpm\n- **Keep:** `npm ERR!` blocks with error code, `added X packages`, deduped deprecations (per package, top 10), audit summary.\n- **Drop:** duplicate deprecation lines, download progress, boilerplate audit text.\n\n### Jest / Vitest\n- **Keep:** `Test Suites:` / `Tests:` / `Time:` summary, every `● Test › name` failure block with assertion diff.\n- **Drop:** `PASS src/…` names (collapsed to count), duplicated \"Summary of failing tests\" block.\n\n### Pytest\n- **Keep:** platform header, `ERRORS:` + `FAILURES:` blocks verbatim, short summary info, final result line.\n- **Drop:** progress dot lines (`tests/foo.py ...... [10%]`), rootdir/plugin chatter.\n\n### JUnit (Gradle/Maven test output)\n- **Keep:** each `FAILED` test with FQCN + assertion + app stack frames, total count.\n- **Drop:** `PASSED` names (count only), framework frames (`org.junit.*`, `java.base/jdk.internal.*`, `kotlinx.coroutines.internal.*`, `android.os.*`, reflection).\n\n### Generic (fallback)\n- **Keep:** every line matching `/error|fail|exception|fatal|panic/i`.\n- **Transform:** consecutive identical lines deduped, middle-truncated when over budget.\n\n## FAQ\n\n**What if the compressor drops something I need?**\nEvery response includes `log_id`. Call `read_log_section` with a `grep` pattern or `start_line`/`end_line`. Full log is on disk for 7 days.\n\n**Does it work on Windows?**\nWSL only in v0.1/v0.2. Native Windows is Phase 3.\n\n**Does it send anything to a server?**\nNo. Commands run locally, logs live on your disk, nothing phones home.\n\n**Will Claude actually use `smart_*` instead of bash?**\nWith the CLAUDE.md snippet in Quick start, yes. Tool descriptions also explicitly say \"ALWAYS prefer this\". In practice adherence is high.\n\n**Why a scoped package name (`@dongnh311/…`)?**\nThe plain `claude-context-saver` unscoped name was already taken by an unrelated package. Scoped keeps the descriptive name.\n\n## Development\n\n```bash\nnpm install\nnpm run typecheck\nnpm test           # vitest\nnpm run bench      # compressor benchmark table\nnpm run build      # tsc → dist/index.js (+ shebang + chmod)\nnpm run dev        # tsc --watch\nnpx @modelcontextprotocol/inspector node dist/index.js   # manual tool exercise\n```\n\nLayout, conventions, milestones: see [`CLAUDE.md`](./CLAUDE.md).\nUnified implementation spec: [`SPEC.md`](./SPEC.md). Archived log-only spec: [`SPEC-v0.1.md`](./SPEC-v0.1.md). High-level pitch: [`spec-overview.md`](./spec-overview.md).\n\n## Links\n\n- **npm:** [`@dongnh311/claude-context-saver`](https://www.npmjs.com/package/@dongnh311/claude-context-saver)\n- **GitHub:** [dongnh311/claude-context-saver](https://github.com/dongnh311/claude-context-saver)\n- **Issues / feedback:** [GitHub Issues](https://github.com/dongnh311/claude-context-saver/issues)\n\n## License\n\nMIT\n","readmeFilename":"README.md"}