@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.
- package/README.md +28 -21
- package/dist/bin.js +64 -4
- 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
|
-
```
|
|
8
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
|
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
|
|
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);
|