AgentStack
MCP verified MIT Self-run

Litos Mcp

mcp-stubbies-litos-mcp · by stubbies

MCP server that indexes repo symbols locally (SQLite/FTS5) so coding agents search structure first and read only the lines they need.

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add mcp-stubbies-litos-mcp

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Litos Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Litos MCP

> Search · read by ID · callers · map · check · CLI — local structural navigation for coding agents

[](https://github.com/stubbies/litos-mcp/releases) [](https://github.com/stubbies/litos-mcp/releases) [](https://github.com/stubbies/litos-mcp/actions/workflows/ci.yml)

A local MCP server and CLI that gives coding agents structural sight over your repo—without the grep > read whole file > grep again loop.

Litos indexes definitions into a SQLite cache (.lcn_cache.db) at the project root: symbols, scopes, line ranges, and call sites. Agents search by keyword, read exact symbols by stable ID, trace callers, sketch a directory, and check syntax after edits—all from compact JSON hits instead of scrolling grep output or loading entire files.

It ships as a single Go binary (MCP over stdio + matching CLI subcommands). Everything stays on your machine: no cloud API, no embeddings, no telemetry.

What is this?

Litos is a local code navigation layer for AI coding agents—not semantic search, not an LSP. It pre-indexes your repo and exposes tools to:

  • Discover — FTS keyword search, exact name lookup, file outlines, directory maps
  • Fetchread_symbol by stable symbol_id (byte-precise with optional tree-sitter)
  • Tracefind_callers for name-based call-site lookup
  • Validatecheck_file for post-edit syntax (tree-sitter build)

Optional Universal Ctags broadens language coverage; build with -tags treesitter for precise boundaries and syntax check on Go, TS/JS, and Python.

Why use it?

  • Fewer tokens — Search returns paths and line numbers, not matching lines or entire files. Reads are capped (500 lines / 512KB per call).
  • Faster discovery — FTS5 keyword search over symbols beats scrolling large grep dumps for “where is X implemented?”
  • Stays fresh — On serve, the index hydrates at startup, watches the repo for saves (fsnotify), and rechecks staleness before search. Normal edits do not require manual reindex.
  • Private and offline — Local cache only; respects .gitignore and common skip dirs (node_modules, .git, build outputs).
  • Optional depth — Install Universal Ctags for broad multi-language symbol extraction, or use the built-in regex indexer for Go, TS/JS, and Python. Build with -tags treesitter (requires CGO) for byte-precise symbol boundaries on those same extensions.

How it works

  1. litos-mcp init (or auto-init on first serve) crawls indexable source files, extracts symbols, and writes .lcn_cache.db with an FTS5 search index.
  2. litos-mcp serve starts the MCP server, hydrates any drift since last run, and watches the filesystem for changes while you work.
  3. The agent discovers symbols via keyword search, exact name lookup, a single-file outline, or a directory map (definitions + outgoing calls under a prefix).
  4. The agent fetches source with read_symbol using the stable symbol_id from search, outline, or map hits (read_file_lines remains a fallback).
  5. The agent traces callers with find_callers by exact callee name (or symbol_id) to see who invokes a symbol, then reads caller bodies via enclosing_symbol_id.
  6. The agent validates edits with check_file (tree-sitter build) to catch syntax errors before continuing.

Example search hit (no source body—just structure):

[{
  "symbol_id": "src/billing/billing.go#function#ProcessPayment#56",
  "file_path": "src/billing/billing.go",
  "symbol": "ProcessPayment",
  "kind": "function",
  "start_line": 56,
  "end_line": 69,
  "scope": "BillingService",
  "matched_in": "symbol"
}]

Each hit includes a symbol_id (file_path#kind#name#start_line) that stays stable while start_line, kind, and name are unchanged. Symbol names must not contain #. Edits that move the definition or change only end_line may leave a stale ID or line range — re-search or re-outline after substantive edits.

After large tree changes (git pull, branch switch), call reindex_index or run litos-mcp init again. Check sync state anytime via the litos://index/status MCP resource.

Call-site index: Caller lookup adds a call_sites table indexed at sync time. If you upgrade from an older cache, run litos-mcp clean --reindex — existing caches are not migrated automatically (same as byte-boundary columns).

What it is not

  • Not semantic / embedding search — Keyword and structural FTS over symbol metadata, not “find code similar to this paragraph.”
  • Not a grep replacement — Use grep when you need literal matches in comments, strings, configs, or exact regex patterns litos does not index.
  • Not a hosted service — You install the binary and wire it into Cursor, Claude Code, or another MCP host.

Install

Install from release (recommended)

  1. Download the archive for your OS/arch from GitHub Releases.
  2. Extract and place litos-mcp on your PATH.
  3. Verify: litos-mcp version — expect boundary: tree-sitter (go, ts, py) and a semver version (e.g. litos-mcp 1.0.0).

Release binaries include tree-sitter (precise reads, syntax check). Tags use a v prefix (v1.0.0); the injected version omits it (1.0.0).

Install with go install (pure Go)

For a slim build without CGO or tree-sitter:

go install github.com/stubbies/litos-mcp/cmd/litos-mcp@latest

This path does not include -tags treesitter; you get line-range reads and regex callers unless you build from source with CGO (see below).

Build from source

git clone https://github.com/stubbies/litos-mcp.git
cd litos-mcp
go build -o bin/litos-mcp ./cmd/litos-mcp

Optional: install Universal Ctags for richer symbol extraction across many languages. Without it, litos-mcp falls back to built-in regex heuristics for Go, TypeScript/JavaScript, and Python only (.go, .ts, .tsx, .js, .jsx, .mjs, .cjs, .py, .pyw). Run litos-mcp version to see which indexer your install will use (indexer: ctags available … vs regex fallback), whether byte-precise boundaries are active (boundary: tree-sitter (go, ts, py) vs boundary: line-range only), and how call sites are extracted (callers: tree-sitter vs callers: regex).

Byte-precise boundaries (optional)

By default, read_symbol returns a line-range slice derived from the primary indexer (ctags or regex). For exact definition spans on Go, TS/JS, and Python, build with tree-sitter:

CGO_ENABLED=1 go build -tags treesitter -o bin/litos-mcp ./cmd/litos-mcp

Tree-sitter refines symbol start_byte / end_byte at index time; read_symbol prefers those bytes when present. This requires CGO and a C toolchain. After upgrading to a build with byte columns, run litos-mcp clean --reindex — existing caches are not migrated automatically.

Language support

| Mode | Indexed extensions | |------|-------------------| | Regex fallback (no ctags) | .go, .ts, .tsx, .js, .jsx, .mjs, .cjs, .py, .pyw | | Universal Ctags | All crawl-eligible source extensions (Go, TS/JS, Python, Rust, Java/Kotlin, C/C++, C#, Ruby, PHP, Swift, Scala, Vue, Svelte, shell, SQL, Protobuf, and more) |

Crawl discovers many file types, but the regex indexer only extracts symbols from the extensions in the first row. With ctags installed, the full crawl set is indexed.

Regex indexer scope: On the regex fallback path, the indexer sets each symbol's scope from the immediately preceding // comment line (cleared after the next symbol match). This is a heuristic, not full ctags scope resolution — ctags and tree-sitter builds may differ. Doc comments above definitions improve FTS hits on the regex path; the eval locate task depends on scope-indexed doc text when running without ctags.

Quick start

  1. Index your repo (creates .lcn_cache.db beside the repo root):

``bash cd /path/to/your/project litos-mcp init ``

Example output:

`` files=842 symbols=3912 indexer=regex elapsed_ms=1204 db_bytes=524288 ``

  1. Wire into your MCP host

#### Cursor

Copy .cursor/mcp.json (or merge into your existing MCP config):

``json { "mcpServers": { "litos-mcp": { "command": "/path/to/litos-mcp", "args": ["serve"], "cwd": "${workspaceFolder}" } } } ``

cwd must be the workspace root so the server resolves the same repo root as init.

#### Claude Code

Create .mcp.json in the project you want indexed (your app repo, not necessarily litos-mcp itself). Claude Code ignores cwd in MCP config; litos uses CLAUDE_PROJECT_DIR automatically.

``json { "mcpServers": { "litos-mcp": { "type": "stdio", "command": "litos-mcp", "args": ["serve"] } } } ``

Use litos-mcp on your PATH, or substitute an absolute path (e.g. $(go env GOPATH)/bin/litos-mcp or ./bin/litos-mcp).

Alternative CLI:

``bash claude mcp add --scope project litos-mcp -- litos-mcp serve ``

Restart Claude Code after config changes. Verify with /mcp or claude mcp list. First-time project-scoped servers may require approval in the UI.

  1. Use the MCP tools in agent sessions:
  • search_code_skeleton — find symbols by keyword (default FTS) or by name (name_match: exact or contains); returns JSON hits with symbol_id, line ranges, and matched_in; optional match_mode: and or or (FTS only)
  • outline_file — list all indexed symbols in one file with symbol_id, kind, scope, and line ranges
  • read_symbol — read a bounded, line-numbered slice by symbol_id (preferred fetch path)
  • read_file_lines — read a bounded slice by file path and line range (fallback when you lack a symbol_id)
  • find_callers — find indexed call sites for a callee by exact name (case-sensitive) or symbol_id; returns file, line, column, and enclosing symbol metadata with enclosing_symbol_id for reading the caller
  • map_directory — directory architecture sketch: indexed definitions and outgoing calls under a repo-relative prefix (e.g. src/handlers), without reading file bodies; use when exploring a subsystem before drilling into symbols
  • check_file — post-edit syntax check for Go, TS/JS, and Python via tree-sitter; returns { "ok": true/false, "errors": [...] }; requires a -tags treesitter build
  • reindex_index — full index rebuild after large changes (e.g. git pull); normal saves sync automatically
  • litos://index/status (MCP resource) — JSON sync status: file/symbol/call_sites counts, indexer, boundary_indexer (treesitter or none), callers_indexer (treesitter or regex), reconcile_needed
  • code_discovery_workflow (MCP prompt) — onboarding text for agents: map > discover > read > find callers > check edits > iterate

litos-mcp serve auto-runs init when the cache is missing, then hydrates the index on startup (stat pass + boot crawl) and keeps it fresh with a filesystem watcher for debounced per-file updates. Search calls run a lightweight staleness check before FTS.

Commands

| Command | Description | |---------|-------------| | litos-mcp init [--root PATH] | Build or refresh .lcn_cache.db | | litos-mcp clean [--root PATH] [--reindex] | Delete index cache (and optionally rebuild) | | litos-mcp serve | MCP stdio server + boot hydration + fsnotify sync | | litos-mcp version | Print binary, Go, indexer, boundary mode, callers mode, FTS5 status, and CLI subcommands | | litos-mcp search QUERY [--limit N] [--json] | Keyword or name search (same engine as search_code_skeleton) | | litos-mcp outline FILE [--json] | List symbols in one file | | litos-mcp read-symbol ID [--json] | Read symbol slice by symbol_id (raw text without --json) | | litos-mcp find-callers NAME [--dir D] [--limit N] [--json] | Caller lookup by exact name | | litos-mcp map-dir DIR [--json] | Directory map: definitions + outgoing calls | | litos-mcp check FILE [--json] | Syntax check (tree-sitter build only) |

Query subcommands accept [--root PATH] to override repo discovery. Use --json for machine-readable stdout; status messages go to stderr.

| Situation | Command | |-----------|---------| | Normal edits | automatic fsnotify sync | | After git pull | reindex_index or init | | Schema upgrade / corrupt cache / fresh start | clean --reindex |

Agent workflow

  1. Subsystem sketchmap_directory(dir="src/handlers") to see indexed definitions and outgoing calls in a package before reading bodies.
  2. Keyword discoverysearch_code_skeleton(query="payment middleware") for structural FTS hits (~10 results by default).
  3. Known symbol namesearch_code_skeleton(query="ProcessPayment", name_match="exact") for a case-sensitive name match (use name_match="contains" for substring).
  4. Known fileoutline_file(file_path="src/billing/billing.go") to list symbols and pick a symbol_id.
  5. Fetchread_symbol(symbol_id=...) using the ID from search, outline, or map hits (preferred). Use read_file_lines only when you lack a symbol_id.
  6. Find callersfind_callers(name=...) or find_callers(symbol_id=...) to see who invokes a symbol; use enclosing_symbol_id from each hit to read_symbol on the caller and walk up the chain.
  7. Validate editscheck_file(file_path=...) after editing Go, TS/JS, or Python source; fix syntax errors when ok is false (tree-sitter build required).
  8. CLI debugginglitos-mcp search "jwt verification" --json, litos-mcp map-dir src/handlers --json, etc. mirror MCP tools from the terminal.
  9. Prefer litos tools over grep or reading entire files when litos-mcp is available.

The MCP server exposes a code_discovery_workflow prompt with the same guidance. In Cursor, invoke it from the MCP prompts picker or reference it when onboarding agents to the repo.

find_callers limitations

Call-site indexing is name-based only: billing.ProcessPayment(...) is indexed as callee ProcessPayment. There is no import-path, receiver, or type resolution.

  • Exact name only — case-sensitive match on the callee identifier at the call site
  • Homonyms — symbols with the same name in different packages may all appear in results; narrow with the optional dir prefix filter
  • Regex fallback — without -tags treesitter, per-line regex may match false positives (e.g. function declarations that look like calls)
  • No macro/generated code — only parsed/indexed source files are covered

If find_callers returns no hits, the indexed callee name may differ from what you expect — try search_code_skeleton first to confirm the symbol name.

map_directory limitations

Directory maps are composed at query time from the symbols and call_sites tables — no separate index.

  • Outgoing calls only — shows calls made from files under the directory prefix, not incoming references to symbols defined there
  • Name-based calls — same name-only callee names as find_callers (no import or type resolution)
  • Limits — default 50 definitions and 50 outgoing call entries; raise with def_limit / call_limit when needed

check_file limitations

Syntax checking requires a -tags treesitter build (CGO). Without it, the tool returns a clear error: syntax check requires tree-sitter build.

  • Supported extensions — Go, TS/JS, and Python (same set as tree-sitter indexing)
  • Parse errors only — reports tree-sitter ERROR nodes, not type-checker or linter diagnostics
  • Post-edit guard — call after saving edits; does not replace go test, tsc, or your CI linter

#

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.