@prom.codes/context-mcp 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +28 -21
  2. package/dist/bin.js +64 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,28 +2,33 @@
2
2
 
3
3
  prom.codes Context — local-first codebase indexing & retrieval as an MCP server (stdio).
4
4
 
5
- ## Quick start
6
-
7
- ```jsonc
8
- // Claude Desktop / Cursor MCP config
9
- {
10
- "mcpServers": {
11
- "prometheus": {
12
- "command": "npx",
13
- "args": ["-y", "@prom.codes/context-mcp@latest"],
14
- "env": {
15
- "PROMETHEUS_API_KEY": "prom_live_…",
16
- "PROMETHEUS_WORKSPACE_ROOT": "/absolute/path/to/your/repo"
17
- }
18
- }
19
- }
20
- }
5
+ ## Quick start (Claude Code)
6
+
7
+ ```bash
8
+ claude mcp add context --env PROMETHEUS_API_KEY=prom_live_… -- npx -y @prom.codes/context-mcp@latest
21
9
  ```
22
10
 
23
- With a `PROMETHEUS_API_KEY` the server runs in managed mode: it indexes
24
- your workspace into a local SQLite database (`~/.prometheus/<hash>.db`)
25
- and embeds via the prom.codes API. Your code never leaves your machine
26
- only embedding text transits to the API.
11
+ `claude mcp add` defaults to local scope (just you); add `--scope project` to
12
+ write a committable `.mcp.json`, or `--scope user` for all your projects. Other
13
+ MCP hosts (Cursor, VS Code) use the same command/args in their own config.
14
+
15
+ ## Configuration
16
+
17
+ - **`PROMETHEUS_API_KEY`** (required for semantic search) — a real key minted at
18
+ [app.prom.codes/app/api-keys](https://app.prom.codes), shape
19
+ `prom_live_<tag>_<secret>`. Embeddings route through the managed prom.codes
20
+ proxy — you never bring your own provider key. Without a valid key, code
21
+ search **degrades gracefully** to lexical (keyword) + symbol-graph retrieval
22
+ (no embeddings needed) and every structural tool still works.
23
+ - **Workspace root is auto-detected** — no need to set `PROMETHEUS_WORKSPACE_ROOT`.
24
+ Claude Code passes the open project via `CLAUDE_PROJECT_DIR`; Cursor/VS Code via
25
+ the MCP `roots` capability. Set it only to point at a different folder.
26
+ - The index is a local SQLite DB at `~/.prometheus/<hash>.db` (one per project).
27
+ Your code never leaves your machine — only embedding *text* transits to the proxy.
28
+
29
+ Tools: `search_code`, `get_symbol`, `find_references`, `find_callers`,
30
+ `find_callees`, `expand_context`, `get_file`, `list_changed_since`,
31
+ `list_workspaces`, `framework_overview`.
27
32
 
28
33
  ## Native modules
29
34
 
@@ -32,6 +37,8 @@ Prebuilt binaries are fetched automatically on the mainstream platforms
32
37
  (macOS x64/arm64, Linux x64, Windows x64) — no compiler needed. On other
33
38
  platforms (e.g. Linux/Windows arm64) or a Node ABI without a prebuild, install
34
39
  C/C++ build tools so the native modules can compile (Windows: VS Build Tools).
40
+ If `npx` skips the native build under a hardened npm (`ignore-scripts=true`),
41
+ install globally once and point Claude Code at the built binary — see the docs.
35
42
  Requires Node ≥ 20.10.
36
43
 
37
- Docs: https://prom.codes/docs
44
+ Docs: https://prom.codes/docs/mcp/claude-code
package/dist/bin.js CHANGED
@@ -8438,6 +8438,16 @@ function getStableDbPath(workspaceRoot) {
8438
8438
  const hash = createHash3("sha256").update(abs).digest("hex").slice(0, 16);
8439
8439
  return join4(homedir2(), ".prometheus", `${hash}.db`);
8440
8440
  }
8441
+ function isAutoIndexableRoot(workspaceRoot) {
8442
+ const abs = resolve4(workspaceRoot);
8443
+ if (abs === "")
8444
+ return false;
8445
+ if (abs === resolve4(homedir2()))
8446
+ return false;
8447
+ if (dirname2(abs) === abs)
8448
+ return false;
8449
+ return true;
8450
+ }
8441
8451
  var StorageConfigError = class extends Error {
8442
8452
  constructor(reason) {
8443
8453
  super(`Storage configuration error: ${reason}`);
@@ -8526,6 +8536,7 @@ async function composeFromEnv(opts) {
8526
8536
  const rerankTopN = intEnv(env, "PROMETHEUS_RERANK_TOP_N", 100);
8527
8537
  const { id: queryRewriterId, provider: queryRewriter } = discoverQueryRewriter(env, opts.fetch);
8528
8538
  const managed = apiKeyPresent && storageBackend === "sqlite";
8539
+ const autoIndexable = isAutoIndexableRoot(workspaceRoot);
8529
8540
  let closed = false;
8530
8541
  return {
8531
8542
  storage,
@@ -8538,6 +8549,7 @@ async function composeFromEnv(opts) {
8538
8549
  providerId,
8539
8550
  storageBackend,
8540
8551
  managed,
8552
+ autoIndexable,
8541
8553
  dbPath,
8542
8554
  reranker,
8543
8555
  rerankId,
@@ -8912,7 +8924,7 @@ var changedSinceInput = {
8912
8924
  };
8913
8925
  var emptyInput = {};
8914
8926
  function registerTools(server, deps) {
8915
- const { storage, retriever, workspaceRoot, workspaceId, workspaceName, regionMode, providerId, storageBackend, reranker, rerankTopN, queryRewriter } = deps;
8927
+ const { storage, embedder, retriever, workspaceRoot, workspaceId, workspaceName, regionMode, providerId, storageBackend, managed, autoIndexable, dbPath, reranker, rerankTopN, queryRewriter } = deps;
8916
8928
  server.registerTool("search_code", {
8917
8929
  title: "Hybrid code search",
8918
8930
  description: (
@@ -8946,7 +8958,7 @@ ${hyp}`;
8946
8958
  if (vectorError !== null)
8947
8959
  return;
8948
8960
  vectorError = err instanceof Error ? err.message : String(err);
8949
- console.error(`[context-mcp] search_code: vector (semantic) search unavailable \u2014 falling back to lexical + symbol-graph. Likely a missing/invalid embedding API key; set PROMETHEUS_API_KEY (a real minted prom_live_\u2026 key) or a provider key (e.g. VOYAGE_API_KEY) to enable semantic ranking. Cause: ${vectorError}`);
8961
+ console.error(`[context-mcp] search_code: vector (semantic) search unavailable \u2014 falling back to lexical + symbol-graph. Likely a missing/invalid embedding API key; set PROMETHEUS_API_KEY to a real minted prom_live_<tag>_<secret> key (mint at app.prom.codes/app/api-keys) to enable semantic ranking. Cause: ${vectorError}`);
8950
8962
  }
8951
8963
  });
8952
8964
  let ordered = pool;
@@ -8981,7 +8993,7 @@ ${hyp}`;
8981
8993
  };
8982
8994
  if (vectorError !== null) {
8983
8995
  payload.degraded = "lexical+graph-only";
8984
- payload.note = "Semantic (vector) search was unavailable \u2014 results are lexical (keyword) + symbol-graph only, which can rank less precisely on concept queries. Set a valid embedding key (PROMETHEUS_API_KEY = a real minted prom_live_\u2026 key, or e.g. VOYAGE_API_KEY) to enable semantic ranking.";
8996
+ payload.note = "Semantic (vector) search was unavailable \u2014 results are lexical (keyword) + symbol-graph only, which can rank less precisely on concept queries. Set PROMETHEUS_API_KEY to a real minted prom_live_<tag>_<secret> key (app.prom.codes/app/api-keys) to enable semantic ranking.";
8985
8997
  payload.vectorError = vectorError;
8986
8998
  }
8987
8999
  return textResult(payload);
@@ -9140,6 +9152,50 @@ ${hyp}`;
9140
9152
  languages
9141
9153
  });
9142
9154
  });
9155
+ server.registerTool("index_status", {
9156
+ title: "Index status / health check",
9157
+ description: "Health check for this workspace's code index. Reports the resolved workspace root, the on-disk index path, whether auto-indexing is enabled AND allowed for this root (it is refused for the home directory / filesystem root), how much is indexed (files / symbols / references + per-language counts), the embedding provider, and \u2014 best-effort, zero-cost \u2014 whether embeddings are reachable with the configured key. CALL THIS FIRST when `search_code` returns nothing, when you're unsure whether the right folder is indexed, or to confirm the API key works.",
9158
+ inputSchema: emptyInput
9159
+ }, async () => {
9160
+ const [stats, languages] = await Promise.all([
9161
+ storage.stats(),
9162
+ languageDistribution(storage)
9163
+ ]);
9164
+ const indexed = stats.fileCount > 0;
9165
+ let embeddingsReachable = null;
9166
+ let embeddingsError = null;
9167
+ const resolveIdentity = embedder.resolveIdentity;
9168
+ if (typeof resolveIdentity === "function") {
9169
+ try {
9170
+ await resolveIdentity.call(embedder);
9171
+ embeddingsReachable = true;
9172
+ } catch (err) {
9173
+ embeddingsReachable = false;
9174
+ embeddingsError = err instanceof Error ? err.message : String(err);
9175
+ }
9176
+ }
9177
+ const autoIndexReason = !managed ? "disabled \u2014 no PROMETHEUS_API_KEY (keyword + symbol-graph only)" : autoIndexable ? "enabled \u2014 indexing this workspace" : "SKIPPED \u2014 workspace is your home directory or a filesystem root; open a project folder or set PROMETHEUS_WORKSPACE_ROOT, then restart";
9178
+ const summary = indexed ? `Indexed ${stats.fileCount} files / ${stats.symbolCount} symbols at ${workspaceRoot}.` : managed && !autoIndexable ? `Empty index: auto-indexing was refused because the workspace resolved to ${workspaceRoot} (home/root). Open your project folder and restart.` : managed ? `Empty index: indexing may still be running, or this folder has no supported source files. Workspace: ${workspaceRoot}.` : `Empty index: no API key, so nothing was embedded/indexed. Semantic search is off; lexical + structural tools still work. Workspace: ${workspaceRoot}.`;
9179
+ return textResult({
9180
+ installed: true,
9181
+ workspace: { id: workspaceId, name: workspaceName, root: workspaceRoot },
9182
+ storage: { backend: storageBackend, dbPath, regionMode },
9183
+ autoIndex: { managed, allowedForThisRoot: autoIndexable, reason: autoIndexReason },
9184
+ index: {
9185
+ indexed,
9186
+ files: stats.fileCount,
9187
+ symbols: stats.symbolCount,
9188
+ references: stats.referenceCount,
9189
+ languages
9190
+ },
9191
+ embeddings: {
9192
+ provider: providerId,
9193
+ reachable: embeddingsReachable,
9194
+ ...embeddingsError !== null ? { error: embeddingsError } : {}
9195
+ },
9196
+ summary
9197
+ });
9198
+ });
9143
9199
  }
9144
9200
 
9145
9201
  // dist/server.js
@@ -9225,8 +9281,12 @@ async function main() {
9225
9281
  process.stderr.write(`prometheus-context-mcp: storage=${composed.storageBackend} provider=${composed.providerId} region-mode=${composed.regionMode} managed=${composed.managed} workspace=${composed.workspaceRoot} (via ${via})${composed.dbPath !== null ? ` db=${composed.dbPath}` : ""}
9226
9282
  `);
9227
9283
  registerTools(server, composed);
9228
- if (composed.managed)
9284
+ if (composed.managed && composed.autoIndexable) {
9229
9285
  managedIndexer = startManagedIndexing(composed);
9286
+ } else if (composed.managed && !composed.autoIndexable) {
9287
+ process.stderr.write(`prometheus-context-mcp: workspace resolved to ${composed.workspaceRoot} (your home directory or a filesystem root) \u2014 NOT auto-indexing it. Open a project folder (Claude Code passes it via CLAUDE_PROJECT_DIR) or set PROMETHEUS_WORKSPACE_ROOT to your repo, then restart. Call index_status for details.
9288
+ `);
9289
+ }
9230
9290
  };
9231
9291
  if (eagerVia !== null) {
9232
9292
  await boot(void 0, eagerVia);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prom.codes/context-mcp",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "prom.codes Context — local-first codebase indexing & retrieval as an MCP server.",
5
5
  "type": "module",
6
6
  "bin": {