npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

locus-mcp

v0.2.0

Published

Locus MCP - AI-driven semantic code search client

Readme

Locus MCP

Forked from the upstream locus-mcp project. This build adds a hosted mode: clients talk to the self-hosted Locus service instead of connecting directly to Windsurf. The service injects the real Windsurf authentication server-side, so end users never need a local Windsurf installation or API key.

Hosted Mode (Locus)

Set these two environment variables to enable hosted mode:

| Variable | Example | Purpose | | --- | --- | --- | | LOCUS_BASE_URL | https://ace.panrun.me/relay | Base URL of the Locus service. When set, requests go to ${LOCUS_BASE_URL}/exa.api_server_pb.ApiServerService/... and ${LOCUS_BASE_URL}/exa.auth_pb.AuthService/... instead of Windsurf. | | LOCUS_TOKEN | ace_xxxxxxxx | Your Locus key. Sent as Authorization: Bearer ${LOCUS_TOKEN} on every request. |

Example MCP config (hosted mode, via npm):

{
  "mcpServers": {
    "locus": {
      "command": "npx",
      "args": ["-y", "locus-mcp"],
      "env": {
        "LOCUS_BASE_URL": "https://ace.panrun.me/relay",
        "LOCUS_TOKEN": "your-locus-api-key"
      }
    }
  }
}

In hosted mode the client does not read your local Windsurf install or WINDSURF_API_KEY; a placeholder key is encoded into the protobuf body and the service replaces it with the real Windsurf credentials. Local command execution (rg / readfile / tree / ls / glob) is unchanged.

Legacy / direct mode: if LOCUS_BASE_URL is not set, the client behaves exactly like upstream and connects directly to Windsurf (see the original docs below).


Any MCP-compatible client (Claude Code, Claude Desktop, Cursor, etc.) can use this to search codebases with natural language queries. All tools are bundled via npm — no system-level dependencies needed (ripgrep via @vscode/ripgrep, tree via tree-node-cli). Works on macOS, Windows, and Linux.

How It Works

You: "where is the authentication logic?"
         │
         ▼
┌─────────────────────────┐
│  Locus MCP              │
│  (local MCP server)     │
│                         │
│  1. Maps project → /codebase
│  2. Sends query to Windsurf Devstral API
│  3. AI generates rg/readfile/tree commands
│  4. Executes commands locally (built-in rg)
│  5. Returns results to AI
│  6. Repeats for N rounds
│  7. Returns file paths + line ranges
│     + suggested search keywords
└─────────────────────────┘
         │
         ▼
Found 3 relevant files.
  [1/3] /project/src/auth/handler.py (L10-60)
  [2/3] /project/src/middleware/jwt.py (L1-40)
  [3/3] /project/src/models/user.py (L20-80)

Suggested search keywords:
  authenticate, jwt.*verify, session.*token

Prerequisites

  • Node.js >= 18

No need to install ripgrep — it's bundled via @vscode/ripgrep.

Installation

Option 1: npm (Recommended)

npm install locus-mcp
# or run directly
npx -y locus-mcp

Option 2: From Source

git clone https://github.com/zj0808/locus-mcp.git
cd locus-mcp
npm install

Setup (Hosted Mode, Recommended)

Get a key from the Locus console, then add to your editor's MCP config (Claude Code ~/.claude.json, Claude Desktop claude_desktop_config.json, Cursor mcp.json, etc.):

{
  "mcpServers": {
    "locus": {
      "command": "npx",
      "args": ["-y", "locus-mcp"],
      "env": {
        "LOCUS_BASE_URL": "https://ace.panrun.me/relay",
        "LOCUS_TOKEN": "your-locus-api-key"
      }
    }
  }
}

Setup (Legacy Direct Mode)

Without LOCUS_BASE_URL, the client connects directly to Windsurf and needs a Windsurf account (free tier works). The server auto-extracts the API key from your local Windsurf installation; you can also use the extract_windsurf_key MCP tool after setup, or set WINDSURF_API_KEY manually.

{
  "mcpServers": {
    "locus": {
      "command": "npx",
      "args": ["-y", "locus-mcp"],
      "env": {
        "WINDSURF_API_KEY": "sk-ws-01-xxxxx"
      }
    }
  }
}

If WINDSURF_API_KEY is omitted, the server auto-discovers it from your local Windsurf installation.

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | WINDSURF_API_KEY | (auto-discover) | Windsurf API key | | LOCUS_MAX_TURNS | 3 | Search rounds per query (more = deeper but slower) | | LOCUS_MAX_COMMANDS | 8 | Max parallel commands per round | | LOCUS_TIMEOUT_MS | 30000 | Connect-Timeout-Ms for streaming requests | | LOCUS_GRAPH_HINTS | auto | Local JS/TS symbol graph hints: auto (index exists, or auto-build on JS/TS projects), true, false | | LOCUS_GRAPH_AUTO_BUILD | true | When graph is enabled, auto-sync/build index if missing or stale | | LOCUS_ROUTE | auto | Query routing: auto classifies intent (symbol/semantic/exact/impact/complex), coordinates the built-in Graph and Hybrid indexes, and adapts max_turns. off disables routing. See docs/route-policy.md | | LOCUS_LOCAL_FIRST | auto | Skip remote verification only when built-in retrieval confidence is high; on is more aggressive and off always verifies remotely | | LOCUS_SPEED_PROFILE | balanced | quality, balanced, or fast; controls local-first confidence thresholds | | LOCUS_DEFAULT_EXCLUDES | (empty) | Extra comma-separated exclude patterns merged into defaults | | LOCUS_REPO_MAP_CACHE_MS | 45000 | Cache repo tree map TTL in ms (0 disables) | | LOCUS_HIDE_EXTRACT_WINDSURF_KEY_TOOL | false | Hide extract_windsurf_key from MCP tools when set to 1, true, yes, or on | | LOCUS_RESULT_MAX_LINES | 50 | Max lines per command output (truncation) | | LOCUS_LINE_MAX_CHARS | 250 | Max characters per output line (truncation) | | WS_MODEL | MODEL_SWE_1_6_FAST | Windsurf model name | | WS_APP_VER | 1.48.2 | Windsurf app version (protocol metadata) | | WS_LS_VER | 1.9544.35 | Windsurf language server version (protocol metadata) |

Available Models

The model can be changed by setting WS_MODEL (see environment variables above).

Available Models

Default: MODEL_SWE_1_6_FAST — fastest speed, richest grep keywords, finest location granularity.

MCP Tools

locus_mcp_search

AI-driven semantic code search with tunable parameters.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | query | string | Yes | — | Natural language search query | | project_path | string | No | cwd | Absolute path to project root | | tree_depth | integer | No | 3 | Directory tree depth for repo map (1-6). Higher = more context but larger payload. Auto falls back to lower depth if tree exceeds 250KB. Use 1-2 for huge monorepos (>5000 files), 3 for most projects, 4-6 for small projects. | | max_turns | integer | No | 3 | Search rounds (1-5). More = deeper search but slower. Use 1-2 for simple lookups, 3 for most queries, 4-5 for complex analysis. | | max_results | integer | No | 10 | Upper bound for files to return (1-30). Locus dynamically selects the useful TopK instead of padding weak results. |

Returns:

  1. Relevant files with line ranges
  2. Suggested search keywords (rg patterns used during AI search)
  3. Diagnostic metadata ([config] line showing actual tree_depth used, tree size, and whether fallback occurred)

Example output:

Found 3 relevant files.

  [1/3] /project/src/auth/handler.py (L10-60, L120-180)
  [2/3] /project/src/middleware/jwt.py (L1-40)
  [3/3] /project/src/models/user.py (L20-80)

grep keywords: authenticate, jwt.*verify, session.*token

[config] tree_depth=3, tree_size=12.5KB, max_turns=3

Error output includes status-specific hints:

Error: Request failed: HTTP 403

[hint] 403 Forbidden: Authentication failed. The API key may be expired or revoked.
Try re-extracting with extract_windsurf_key, or set a fresh WINDSURF_API_KEY env var.
If you are running inside WSL, run `devin login` inside WSL so `~/.local/share/devin/credentials.toml` exists.
Error: Request failed: HTTP 413

[diagnostic] tree_depth_used=3, tree_size=280.0KB (auto fell back from requested depth)
[hint] If the error is payload-related, try a lower tree_depth value.

extract_windsurf_key

Extract Windsurf API Key from local installation. No parameters.

Set LOCUS_HIDE_EXTRACT_WINDSURF_KEY_TOOL=1 at MCP server startup to hide this tool from tools/list. This does not disable internal API-key auto-discovery for locus_mcp_search.

locus_index_status

Reports the native Graph and Hybrid index state for a project or package root:

  • freshness, version, file count, chunk count, and structured-chunk count
  • loaded .gitignore, .cursorignore, .locusignore, .ignore, and .dockerignore sources
  • watcher state, scan fallback, and incremental changed/reused/deleted counts

Set refresh=true to synchronize both indexes before returning status.

Project Structure

locus-mcp/
├── package.json
├── src/
│   ├── server.mjs        # MCP server entry point
│   ├── core.mjs          # Auth, message building, streaming, search loop
│   ├── executor.mjs      # Tool executor: rg, readfile, tree, ls, glob
│   ├── extract-key.mjs   # Windsurf API Key extraction (SQLite)
│   └── protobuf.mjs      # Protobuf encoder/decoder + Connect-RPC frames
├── README.md
└── LICENSE

How the Search Works

  1. Project directory is mapped to virtual /codebase path
  2. Directory tree generated at requested depth (default L=3), with automatic fallback to lower depth if tree exceeds 250KB
  3. Optional local JS/TS graph hints seed candidate files/symbols (verify with tools)
  4. Query + directory tree (+ hints) sent to Windsurf's Devstral model via Connect-RPC/Protobuf
  5. Devstral generates tool commands (ripgrep, file reads, tree, ls, glob)
  6. Commands executed locally in parallel (up to LOCUS_MAX_COMMANDS per round)
  7. Results sent back to Devstral for the next round
  8. After max_turns rounds, Devstral returns file paths + line ranges
  9. All rg patterns used during search are collected as suggested keywords
  10. Diagnostic metadata and monorepo [scope] hints appended for the calling AI

Search workflow (JetBrains-adapted)

For agent callers, follow one broad semantic bootstrap → local read → one path_filter narrowed retry. Do not re-broaden at monorepo root. Full comparison of JetBrains Context vs Locus: docs/jetbrains-context-comparison.md. Workflow: docs/search-workflow.md.

New tool param: path_filter — relative path under project_path (same idea as JetBrains pathFilter) for the narrowed retry.

Precision Tips (monorepo + graph)

# Build / refresh local JS/TS symbol index for a package or whole repo
npm run graph:index -- --project ./packages/api
# or from installed package
npx locus-mcp  # graph is used automatically when .locus-mcp/graph exists or LOCUS_GRAPH_AUTO_BUILD=true
  • Narrow project_path: prefer packages/foo / apps/web over monorepo root.
  • Graph: LOCUS_GRAPH_HINTS=auto (default) + LOCUS_GRAPH_AUTO_BUILD=true keeps the index fresh on JS/TS projects.
  • Turns: simple lookup max_turns=1-2; cross-package tracing 3-5.

Technical Details

  • Protocol: Connect-RPC over HTTP/1.1, Protobuf encoding, gzip compression
  • Model: Devstral (MODEL_SWE_1_6_FAST, configurable)
  • Local tools: rg (bundled via @vscode/ripgrep), readfile (Node.js fs), tree (tree-node-cli), ls (Node.js fs), glob (Node.js fs)
  • Auth: API Key → JWT (auto-fetched per session)
  • Runtime: Node.js >= 18 (ESM)

Dependencies

| Package | Purpose | |---------|---------| | @modelcontextprotocol/sdk | MCP server framework | | @vscode/ripgrep | Bundled ripgrep binary (cross-platform) | | tree-node-cli | Cross-platform directory tree (replaces system tree) | | better-sqlite3 | Read Windsurf's local SQLite DB | | zod | Schema validation (MCP SDK requirement) |

License

MIT

Retrieval performance (monorepo)

Optimizations in this fork for better + faster search:

  1. Route auto-turns — symbol/semantic queries use fewer remote turns when the built-in indexes are confident
  2. Local radar adapt — Graph and native Hybrid confidence further clamps max_turns
  3. Parallel prep — JWT, Graph, Hybrid, and repo-map preparation overlap
  4. Caches — repo maps are cached and the native Hybrid index is incrementally persisted under .locus-mcp/index
  5. Lean excludes.locus-mcp, .codegraph, binaries/logs skipped from tree
  6. Local-first - LOCUS_LOCAL_FIRST=auto skips remote Devstral when local radars are high-confidence
  7. Prebuild graphnpm run graph:index -- --project <root>

The native Hybrid index is bundled with Locus and requires no external MCP server, CLI or model download. See docs/native-hybrid-retrieval.md.

Result quality now includes implementation-owner ranking, query-aware file roles, dynamic TopK selection, an approximately 20 percent related-result quota, Graph evidence chains, structural chunks, project ignore rules, and watch-driven incremental refresh with a scan fallback.

Run retrieval policy coverage and the quality dashboard with:

npm run smoke:retrieval
npm run benchmark:retrieval
# optional machine-readable report
node scripts/benchmark-retrieval-quality.mjs --json=./retrieval-quality.json

Biggest accuracy lever remains: narrow project_path / path_filter (see docs/search-workflow.md).