{
  "markdown": "<div align=\"center\">\n\n<img src=\"assets/logo-128.png\" width=\"112\" alt=\"Throughline logo\" />\n\n# Throughline\n\n**Give Claude complete understanding of your software project.**\n\n[![License](https://img.shields.io/badge/license-MIT-3b82f6?style=flat-square)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A520.11-38bdf8?style=flat-square)](package.json)\n[![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Windows-94a3b8?style=flat-square)](#install)\n[![MCP](https://img.shields.io/badge/MCP-desktop%20extension-1e3a8a?style=flat-square)](https://modelcontextprotocol.io)\n[![CI](https://github.com/devznsh/throughline/actions/workflows/ci.yml/badge.svg)](https://github.com/devznsh/throughline/actions/workflows/ci.yml)\n\n</div>\n\n---\n\nPoint it at a repository on your machine. It reads every file, extracts symbols\nwith tree-sitter, resolves imports into a call graph, ingests git history, and\nexposes the whole thing to Claude as precise retrieval tools.\n\nThen you can ask the questions you actually have — *\"where is rate limiting\nhandled?\"*, *\"what breaks if I change this?\"* — and get **real file paths and\nline numbers** instead of plausible-sounding guesses.\n\nEverything runs locally. This extension makes no network requests of any kind.\n\n## What it looks like\n\n> **You:** where does indexing decide a file has changed?\n\n```\n3 matches for \"where does indexing decide a file has changed\"\n\n### src/core/services/index-repository.ts:171-186\nmethod IndexingService.index — src/core/services/index-repository.ts:171-186\nwhy: text match; 15 inbound references; 6 matches in this file\n\n      const hash = contentHash(buffer);\n      const previous = known.get(scanned.relPath);\n      ...\n      if (mode === 'incremental' && previous === hash) {\n        unchanged.push(scanned.relPath);\n        continue;\n      }\n```\n\nThat `why:` line is the point. Results are ranked by how structurally central\nthey are — inbound references, export status, architectural role — not by how\nmany times a word appears. A file that *mentions* caching loses to the one that\n*implements* it.\n\n## What you can ask\n\n| You ask | What happens |\n| --- | --- |\n| *\"Where is payment handled?\"* | Expands the concept into the mechanisms code actually uses — `stripe`, `charge`, `invoice`, `checkout` — then ranks by structural importance |\n| *\"What calls `validateToken`?\"* | Every call site, with heuristic matches **labelled as such** so you know what to double-check before a rename |\n| *\"What happens when a request hits `/login`?\"* | Traces the call path from route handler to core logic, rendered as a sequence diagram |\n| *\"Get me oriented in this repo\"* | Stack, entry points, layer structure, hotspots, existing docs — every claim cited |\n| *\"Is anything dead here?\"* | Unreferenced non-exported symbols, with an explicit warning about what static analysis cannot see |\n| *\"Draft an onboarding guide\"* | Assembles one from the index; a **separate** tool writes it, and only with your explicit approval |\n\nEighteen tools in total — see **[docs/TOOLS.md](docs/TOOLS.md)**.\n\n## Supported languages\n\n**Full symbol extraction** — TypeScript · TSX · JavaScript · JSX · Python · Go ·\nJava · Kotlin · C# · Rust · C · C++ · YAML · JSON\n\n**Text-searchable only** — SQL · Markdown · Dockerfile · Terraform\n*(grammars not yet vendored; files are indexed and searchable, but no symbols\nare extracted)*\n\nAnything else is still catalogued and searchable as text.\n\n## Install\n\n**From a release** — download `throughline.mcpb`, then in Claude\nDesktop go to **Settings → Extensions → Advanced settings → Install Extension**.\nYou'll be asked which directories the connector may read.\n\n**From source** — see **[docs/INSTALL.md](docs/INSTALL.md)**:\n\n```bash\nnpm install\nnpm run grammars     # vendor tree-sitter WASM grammars\nnpm run build\nnpm run smoke -- .   # watch it index itself\n```\n\nRequires Claude Desktop on macOS or Windows. Node ships with Claude Desktop, so\nthere's nothing else to install.\n\n## First run\n\n1. *\"List my workspaces\"* — confirms the directory was granted.\n2. *\"Index this project\"* — a 5,000-file repository takes 20–60 seconds.\n3. Ask anything. Later, *\"refresh the index\"* picks up your edits in about a second.\n\n## Example prompts\n\n- *\"Index this repo, then explain how authentication works. Cite files.\"*\n- *\"I want to rename `getUserById`. Show me every caller and flag the risky ones.\"*\n- *\"What are the entry points in this service?\"*\n- *\"Draw me the dependency graph for `src/billing`.\"*\n- *\"Which files change most often **and** are the most complex?\"*\n- *\"Draft an architecture overview — don't write it to disk yet.\"*\n\n## How it works\n\nA two-pass pipeline. Pass 1 parses every file with tree-sitter in parallel, with\nno shared state. Pass 2 has the global view and resolves names into a symbol\ntable, import graph and call graph.\n\nSearch fuses a BM25 lexical ranker with a symbol-name ranker using **reciprocal\nrank fusion**, then re-ranks by graph centrality. RRF uses rank *position* only,\nso rankers with incomparable score scales compose without calibration — and the\ngraph re-rank is what makes a conceptual query find the implementation rather\nthan the twelve files that merely mention it.\n\nThe design rationale, including eleven decisions and what each traded away, is\nin **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)**.\n\n---\n\n## Privacy Policy\n\n**Effective date:** 2026-01-01 · **Last updated:** 2026-01-01\n\nThroughline is a local desktop extension. It runs entirely on your\ncomputer as a child process of Claude Desktop.\n\n### What the connector accesses\n\n- **Files inside the directories you explicitly grant** during installation.\n  Nothing outside those directories is read. Symlinks resolving outside a granted\n  directory are refused.\n- **Git metadata** in those directories: commit subjects, author names and\n  emails, timestamps, and which files each commit touched. Commit message bodies\n  are not stored.\n- **Nothing else.** No environment variables beyond its own configuration, no\n  browser data, no files elsewhere on your system, no other applications.\n\n### What the connector stores, and where\n\nAn index is written to `.throughline/index.db` **inside each project\ndirectory you granted**. It contains file paths, symbol names and signatures,\ndocumentation comments, import relationships, call edges, git metadata, and\nexcerpts of your source code used for search.\n\nThe index never leaves your machine. Deleting the `.throughline` directory\ndeletes it completely. Uninstalling the extension leaves it in place; remove the\ndirectory yourself if you want it gone.\n\n### What the connector transmits\n\n**The extension makes no network requests of any kind.** No telemetry, no\nanalytics, no crash reporting, no update check, no remote API. This is\nstructural rather than a promise: it opens no sockets, and git operations read\nthe local object database directly rather than contacting a remote.\n\nThe boundary is worth stating plainly. When Claude calls a tool, the tool's\n**response** — code snippets, file paths, symbol names from your project — is\nreturned to Claude and therefore processed by Anthropic under\n[Anthropic's Privacy Policy](https://www.anthropic.com/legal/privacy), exactly as\nif you had pasted that code into a conversation yourself. The connector controls\nwhat leaves your machine only insofar as it controls what it returns; it returns\nscoped, bounded excerpts rather than whole repositories, and redacts secrets\nfirst. If you don't want a directory's contents reaching Claude, don't grant that\ndirectory.\n\n### Secret redaction\n\nBefore any content is stored or returned, it is scanned for credential patterns —\nAPI keys, tokens, private keys, connection strings, passwords in assignments —\nand matches are replaced with `[REDACTED:kind]`. Redaction happens at write time,\nso secrets are never persisted in the index either.\n\nThis is a safety net, not a guarantee. Pattern matching cannot catch every\nsecret. Don't grant access to directories containing credentials you wouldn't\nwant in a conversation, and use `security.denyGlobs` to exclude sensitive paths.\n\n### Writing to your files\n\nRead-only by default. The single tool that can write — `write_documentation` —\nrequires **both** that you enable writes in settings **and** that you confirm the\nspecific write after seeing a preview of the exact content. It writes only inside\ngranted directories, only to a path you name.\n\n### Data sharing, retention, and contact\n\nNo data is shared with anyone. There is no server, no account, no third party.\nRetention is entirely under your control: the index lives in your project\ndirectory and is deleted when you delete it. This is a developer tool not\ndirected at children and collects no personal information from anyone.\n\nQuestions or concerns:\n[open an issue](https://github.com/devznsh/throughline/issues).\n\nThe full policy, including the exact redaction patterns and the data model, is in\n**[docs/PRIVACY.md](docs/PRIVACY.md)**.\n\n---\n\n## Security\n\n- Read-only by default; writes are double-gated and preview-first.\n- **No shell execution, ever.** Git is read in-process rather than by invoking `git`.\n- Path containment is enforced against resolved *real* paths, so symlinks cannot\n  escape a granted directory.\n- `stdout` carries only JSON-RPC; all diagnostics go to `stderr`.\n- A config file inside a repository **cannot widen** the connector's access —\n  granted directories come from the install dialog and nothing else can add to them.\n\nThreat model: **[docs/SECURITY.md](docs/SECURITY.md)**.\n\n## Configuration\n\nOptional. Drop a `connector.config.json` in your project root to tune excludes,\nlimits and search behaviour — see\n[connector.config.example.json](connector.config.example.json) and\n**[docs/CONFIGURATION.md](docs/CONFIGURATION.md)**.\n\n## Limitations\n\nWorth knowing before you rely on it:\n\n- **References resolve by name, not by types.** No type checker is involved. Edges\n  are labelled `exact` or `heuristic`; heuristic ones can be wrong.\n- **Dynamic dispatch is invisible.** Reflection, dependency injection,\n  string-keyed routing and event buses produce no edges. \"Dead code\" findings are\n  candidates, not verdicts.\n- **Blame is approximate.** Line attribution is reconstructed by walking history\n  and doesn't track code movement the way `git blame -M` does.\n- **Four languages parse as text only** — SQL, Markdown, Dockerfile, Terraform.\n- **Large repositories are bounded, not unbounded.** The default file limit is\n  50,000; hitting it produces a warning, not a silent truncation.\n\n## Contributing\n\n**[docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)**. Adding a language is usually a\ngrammar, a `.scm` query file and a registry row — the pipeline shouldn't need to\nchange.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n<div align=\"center\">\n<sub>Built for the <a href=\"https://modelcontextprotocol.io\">Model Context Protocol</a>.</sub>\n</div>\n",
  "bytes": 10909,
  "sha": "21fab7204125a075cffb8749168d7e5b034ca1ddc0ced399ffbefa1ff0e3b4d9",
  "repo_slug": "devznsh/throughline",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_devznsh_throughline_eb5eb936/readme"
}