@zokizuan/satori-mcp 4.11.0 → 4.11.1
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/LICENSE +1 -1
- package/README.md +26 -3
- package/dist/cli/install.js +76 -7
- package/dist/config.js +1 -1
- package/dist/core/handlers.js +3 -1
- package/package.json +2 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ Read-only MCP server for Satori. It gives coding agents six deterministic tools
|
|
|
7
7
|
Use the CLI installer for normal setup:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx -y @zokizuan/satori-cli@0.4.
|
|
11
|
-
npx -y @zokizuan/satori-cli@0.4.
|
|
10
|
+
npx -y @zokizuan/satori-cli@0.4.1 install --client all
|
|
11
|
+
npx -y @zokizuan/satori-cli@0.4.1 doctor
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
The CLI installer supports `codex`, `claude`, `opencode`, and `all`. It creates the runtime cache, writes the stable launcher, and writes client config for you. Avoid using `npx` as the resident MCP server command; first-run package resolution can exceed normal MCP startup timeouts.
|
|
@@ -16,9 +16,11 @@ The CLI installer supports `codex`, `claude`, `opencode`, and `all`. It creates
|
|
|
16
16
|
Advanced direct execution is available through the package bin:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npx -y @zokizuan/satori-mcp@4.11.
|
|
19
|
+
npx -y @zokizuan/satori-mcp@4.11.1 --help
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
Use direct package execution for inspection, smoke tests, or unsupported harnesses. For supported clients, prefer `satori-cli install` so startup does not depend on package-manager resolution.
|
|
23
|
+
|
|
22
24
|
## Agent Workflow
|
|
23
25
|
|
|
24
26
|
```text
|
|
@@ -42,6 +44,27 @@ Important defaults:
|
|
|
42
44
|
|
|
43
45
|
Configure an embedding provider and Milvus-compatible backend before indexing. Supported embedding providers are OpenAI, VoyageAI, Gemini, and Ollama. Changing provider, model, dimension, vector store, or schema requires a reindex because those values are part of the index fingerprint.
|
|
44
46
|
|
|
47
|
+
MCP startup, `tools/list`, and installer operations are lazy with respect to provider credentials. Missing provider values become `MISSING_PROVIDER_CONFIG` only when a provider-backed tool call needs them.
|
|
48
|
+
|
|
49
|
+
Installer-managed client config starts the resident launcher. Runtime provider settings come from the MCP client's environment and are exposed in native client config:
|
|
50
|
+
|
|
51
|
+
- Codex writes active `env_vars` forwarding plus an optional commented `[mcp_servers.satori.env]` template in `~/.codex/config.toml`.
|
|
52
|
+
- Claude Code writes `mcpServers.satori.env` in `~/.claude.json` with `${VAR:-}` pass-through values.
|
|
53
|
+
- OpenCode writes `mcp.satori.environment` in `~/.config/opencode/opencode.json` with `{env:VAR}` pass-through values.
|
|
54
|
+
|
|
55
|
+
Users who want literal values in a client config can replace the generated pass-through value for that client. In Codex, uncomment or add this table outside the installer-managed launcher block so reinstalls keep edits:
|
|
56
|
+
|
|
57
|
+
```toml
|
|
58
|
+
[mcp_servers.satori.env]
|
|
59
|
+
EMBEDDING_PROVIDER = "VoyageAI"
|
|
60
|
+
EMBEDDING_MODEL = "voyage-4-large"
|
|
61
|
+
EMBEDDING_OUTPUT_DIMENSION = "1024"
|
|
62
|
+
VOYAGEAI_API_KEY = "pa-..."
|
|
63
|
+
VOYAGEAI_RERANKER_MODEL = "rerank-2.5"
|
|
64
|
+
MILVUS_ADDRESS = "https://your-zilliz-endpoint"
|
|
65
|
+
MILVUS_TOKEN = "your-zilliz-token"
|
|
66
|
+
```
|
|
67
|
+
|
|
45
68
|
Cloud-quality setup:
|
|
46
69
|
|
|
47
70
|
```bash
|
package/dist/cli/install.js
CHANGED
|
@@ -7,12 +7,47 @@ import { applyEdits, modify, parse as parseJsonc } from "jsonc-parser";
|
|
|
7
7
|
import { CliError } from "./errors.js";
|
|
8
8
|
const MANAGED_BLOCK_START = "# >>> satori-cli managed satori start >>>";
|
|
9
9
|
const MANAGED_BLOCK_END = "# <<< satori-cli managed satori end <<<";
|
|
10
|
+
const CODEX_ENV_TEMPLATE_START = "# >>> satori-cli optional satori env template >>>";
|
|
11
|
+
const CODEX_ENV_TEMPLATE_END = "# <<< satori-cli optional satori env template <<<";
|
|
10
12
|
const INSTRUCTIONS_BLOCK_START = "<!-- satori-mcp:start -->";
|
|
11
13
|
const INSTRUCTIONS_BLOCK_END = "<!-- satori-mcp:end -->";
|
|
12
14
|
const OWNED_SKILL_DIRS = ["satori"];
|
|
13
15
|
const MANAGED_RUNTIME_DIR = "mcp-runtime";
|
|
14
16
|
const MANAGED_BIN_DIR = "bin";
|
|
15
17
|
const MANAGED_LAUNCHER_FILE = "satori-mcp.js";
|
|
18
|
+
const SATORI_RUNTIME_ENV_VARS = [
|
|
19
|
+
"EMBEDDING_PROVIDER",
|
|
20
|
+
"EMBEDDING_MODEL",
|
|
21
|
+
"EMBEDDING_OUTPUT_DIMENSION",
|
|
22
|
+
"OPENAI_API_KEY",
|
|
23
|
+
"OPENAI_BASE_URL",
|
|
24
|
+
"VOYAGEAI_API_KEY",
|
|
25
|
+
"VOYAGEAI_RERANKER_MODEL",
|
|
26
|
+
"GEMINI_API_KEY",
|
|
27
|
+
"GEMINI_BASE_URL",
|
|
28
|
+
"OLLAMA_HOST",
|
|
29
|
+
"OLLAMA_MODEL",
|
|
30
|
+
"MILVUS_ADDRESS",
|
|
31
|
+
"MILVUS_TOKEN",
|
|
32
|
+
"READ_FILE_MAX_LINES",
|
|
33
|
+
"MCP_ENABLE_WATCHER",
|
|
34
|
+
"MCP_WATCH_DEBOUNCE_MS",
|
|
35
|
+
];
|
|
36
|
+
const CODEX_ENV_TEMPLATE_LINES = [
|
|
37
|
+
CODEX_ENV_TEMPLATE_START,
|
|
38
|
+
"# Optional direct Codex env values. Uncomment/fill these if you prefer",
|
|
39
|
+
"# ~/.codex/config.toml to store Satori runtime settings directly.",
|
|
40
|
+
"# This template is outside the launcher block so reinstall keeps edits.",
|
|
41
|
+
"# [mcp_servers.satori.env]",
|
|
42
|
+
"# EMBEDDING_PROVIDER = \"VoyageAI\"",
|
|
43
|
+
"# EMBEDDING_MODEL = \"voyage-4-large\"",
|
|
44
|
+
"# EMBEDDING_OUTPUT_DIMENSION = \"1024\"",
|
|
45
|
+
"# VOYAGEAI_API_KEY = \"pa-...\"",
|
|
46
|
+
"# VOYAGEAI_RERANKER_MODEL = \"rerank-2.5\"",
|
|
47
|
+
"# MILVUS_ADDRESS = \"https://your-zilliz-endpoint\"",
|
|
48
|
+
"# MILVUS_TOKEN = \"your-zilliz-token\"",
|
|
49
|
+
CODEX_ENV_TEMPLATE_END,
|
|
50
|
+
];
|
|
16
51
|
const OPENCODE_INSTRUCTIONS = `# Satori MCP
|
|
17
52
|
|
|
18
53
|
This project uses Satori MCP for semantic code search, deterministic navigation, and index lifecycle management.
|
|
@@ -60,7 +95,7 @@ function resolveClientTargets(homeDir) {
|
|
|
60
95
|
},
|
|
61
96
|
{
|
|
62
97
|
client: "claude",
|
|
63
|
-
configPath: path.join(homeDir, ".claude
|
|
98
|
+
configPath: path.join(homeDir, ".claude.json"),
|
|
64
99
|
companion: {
|
|
65
100
|
kind: "skills",
|
|
66
101
|
path: path.join(homeDir, ".claude", "skills"),
|
|
@@ -107,6 +142,21 @@ function toTomlString(value) {
|
|
|
107
142
|
function buildTomlArray(values) {
|
|
108
143
|
return `[${values.map(toTomlString).join(", ")}]`;
|
|
109
144
|
}
|
|
145
|
+
function runtimeEnvMap(valueForName) {
|
|
146
|
+
return Object.fromEntries(SATORI_RUNTIME_ENV_VARS.map((name) => [name, valueForName(name)]));
|
|
147
|
+
}
|
|
148
|
+
function objectValue(value) {
|
|
149
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
function mergeRuntimeEnv(existing, defaults) {
|
|
155
|
+
return {
|
|
156
|
+
...defaults,
|
|
157
|
+
...(objectValue(existing) ?? {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
110
160
|
function packageNameFromSpecifier(packageSpecifier) {
|
|
111
161
|
if (packageSpecifier.startsWith("@")) {
|
|
112
162
|
const versionMarker = packageSpecifier.indexOf("@", 1);
|
|
@@ -262,10 +312,25 @@ function buildCodexManagedBlock(runtimeCommand) {
|
|
|
262
312
|
"[mcp_servers.satori]",
|
|
263
313
|
`command = ${toTomlString(runtimeCommand.command)}`,
|
|
264
314
|
`args = ${buildTomlArray(runtimeCommand.args)}`,
|
|
315
|
+
"# Satori reads provider/vector settings from environment at MCP startup.",
|
|
316
|
+
"# env_vars forwards these names from Codex's parent environment when set.",
|
|
317
|
+
`env_vars = ${buildTomlArray([...SATORI_RUNTIME_ENV_VARS])}`,
|
|
265
318
|
MANAGED_BLOCK_END,
|
|
266
319
|
"",
|
|
267
320
|
].join("\n");
|
|
268
321
|
}
|
|
322
|
+
function buildCodexEnvTemplateBlock() {
|
|
323
|
+
return `${CODEX_ENV_TEMPLATE_LINES.join("\n")}\n`;
|
|
324
|
+
}
|
|
325
|
+
function codexHasSatoriEnvTable(content) {
|
|
326
|
+
return /^\s*\[mcp_servers\.satori\.env\]\s*$/m.test(content);
|
|
327
|
+
}
|
|
328
|
+
function ensureCodexEnvTemplate(content) {
|
|
329
|
+
if (content.includes(CODEX_ENV_TEMPLATE_START) || codexHasSatoriEnvTable(content)) {
|
|
330
|
+
return content;
|
|
331
|
+
}
|
|
332
|
+
return `${normalizeTrailingNewline(content)}\n${buildCodexEnvTemplateBlock()}`;
|
|
333
|
+
}
|
|
269
334
|
function codexHasUnmanagedSatoriSection(content) {
|
|
270
335
|
if (!content.includes("[mcp_servers.satori]")) {
|
|
271
336
|
return false;
|
|
@@ -288,6 +353,7 @@ function prepareCodexInstall(filePath, runtimeCommand) {
|
|
|
288
353
|
else {
|
|
289
354
|
next = `${normalizeTrailingNewline(current)}\n${managedBlock}`;
|
|
290
355
|
}
|
|
356
|
+
next = ensureCodexEnvTemplate(next);
|
|
291
357
|
return {
|
|
292
358
|
changed: next !== current,
|
|
293
359
|
apply: () => {
|
|
@@ -341,10 +407,12 @@ function parseJsonObject(filePath) {
|
|
|
341
407
|
}
|
|
342
408
|
return parsed;
|
|
343
409
|
}
|
|
344
|
-
function buildClaudeServerConfig(runtimeCommand) {
|
|
410
|
+
function buildClaudeServerConfig(runtimeCommand, existing) {
|
|
345
411
|
return {
|
|
412
|
+
type: "stdio",
|
|
346
413
|
command: runtimeCommand.command,
|
|
347
414
|
args: runtimeCommand.args,
|
|
415
|
+
env: mergeRuntimeEnv(existing?.env, runtimeEnvMap((name) => `\${${name}:-}`)),
|
|
348
416
|
};
|
|
349
417
|
}
|
|
350
418
|
function isManagedLauncherPath(value) {
|
|
@@ -370,7 +438,8 @@ function isManagedClaudeEntry(value) {
|
|
|
370
438
|
function prepareClaudeInstall(filePath, runtimeCommand) {
|
|
371
439
|
const currentObject = parseJsonObject(filePath);
|
|
372
440
|
const currentSerialized = JSON.stringify(currentObject);
|
|
373
|
-
const
|
|
441
|
+
const existingSatori = objectValue(currentObject.mcpServers?.satori);
|
|
442
|
+
const desiredServer = buildClaudeServerConfig(runtimeCommand, existingSatori);
|
|
374
443
|
const mcpServersValue = currentObject.mcpServers;
|
|
375
444
|
let mcpServers;
|
|
376
445
|
if (mcpServersValue === undefined) {
|
|
@@ -382,8 +451,7 @@ function prepareClaudeInstall(filePath, runtimeCommand) {
|
|
|
382
451
|
else {
|
|
383
452
|
throw new CliError("E_USAGE", `Expected mcpServers to be an object in ${filePath}.`, 2);
|
|
384
453
|
}
|
|
385
|
-
|
|
386
|
-
if (existingSatori !== undefined && !isManagedClaudeEntry(existingSatori)) {
|
|
454
|
+
if (mcpServers.satori !== undefined && !isManagedClaudeEntry(mcpServers.satori)) {
|
|
387
455
|
throw new CliError("E_USAGE", `Refusing to overwrite unmanaged Satori config in ${filePath}. Remove mcpServers.satori manually or align it to the managed Satori form first.`, 2);
|
|
388
456
|
}
|
|
389
457
|
mcpServers.satori = {
|
|
@@ -443,11 +511,12 @@ function parseJsoncObject(filePath, content) {
|
|
|
443
511
|
}
|
|
444
512
|
return parsed;
|
|
445
513
|
}
|
|
446
|
-
function buildOpenCodeServerConfig(runtimeCommand) {
|
|
514
|
+
function buildOpenCodeServerConfig(runtimeCommand, existing) {
|
|
447
515
|
return {
|
|
448
516
|
enabled: true,
|
|
449
517
|
type: "local",
|
|
450
518
|
command: [runtimeCommand.command, ...runtimeCommand.args],
|
|
519
|
+
environment: mergeRuntimeEnv(existing?.environment, runtimeEnvMap((name) => `{env:${name}}`)),
|
|
451
520
|
};
|
|
452
521
|
}
|
|
453
522
|
function isManagedOpenCodeEntry(value) {
|
|
@@ -492,7 +561,7 @@ function prepareOpenCodeInstall(filePath, runtimeCommand) {
|
|
|
492
561
|
if (existingSatori !== undefined && !isManagedOpenCodeEntry(existingSatori)) {
|
|
493
562
|
throw new CliError("E_USAGE", `Refusing to overwrite unmanaged Satori config in ${filePath}. Remove mcp.satori manually or align it to the managed Satori form first.`, 2);
|
|
494
563
|
}
|
|
495
|
-
return mutateJsonc(filePath, current, ["mcp", "satori"], buildOpenCodeServerConfig(runtimeCommand));
|
|
564
|
+
return mutateJsonc(filePath, current, ["mcp", "satori"], buildOpenCodeServerConfig(runtimeCommand, objectValue(existingSatori)));
|
|
496
565
|
}
|
|
497
566
|
function prepareOpenCodeUninstall(filePath) {
|
|
498
567
|
const current = readTextIfExists(filePath);
|
package/dist/config.js
CHANGED
|
@@ -209,7 +209,7 @@ Environment Variables:
|
|
|
209
209
|
|
|
210
210
|
Examples:
|
|
211
211
|
# Install resident MCP config without package-manager startup on every client launch
|
|
212
|
-
npx -y @zokizuan/satori-cli@0.4.
|
|
212
|
+
npx -y @zokizuan/satori-cli@0.4.1 install --client all
|
|
213
213
|
|
|
214
214
|
# Start MCP server with OpenAI and explicit Milvus address
|
|
215
215
|
OPENAI_API_KEY=sk-xxx MILVUS_ADDRESS=localhost:19530 satori
|
package/dist/core/handlers.js
CHANGED
|
@@ -3541,6 +3541,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
3541
3541
|
rerankerFailurePhase = 'parse_results';
|
|
3542
3542
|
throw new Error('reranker_parse_failed');
|
|
3543
3543
|
}
|
|
3544
|
+
let rerankerUpdatedCandidates = 0;
|
|
3544
3545
|
for (let idx = 0; idx < rerankSlice.length; idx++) {
|
|
3545
3546
|
const rank = rerankRanks.get(idx);
|
|
3546
3547
|
if (!rank) {
|
|
@@ -3549,9 +3550,10 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
3549
3550
|
const rerankRrf = 1 / (SEARCH_RERANK_RRF_K + rank);
|
|
3550
3551
|
rerankSlice[idx].fusionScore += SEARCH_RERANK_WEIGHT * rerankRrf;
|
|
3551
3552
|
rerankSlice[idx].finalScore = (rerankSlice[idx].fusionScore + rerankSlice[idx].lexicalScore) * rerankSlice[idx].pathMultiplier * rerankSlice[idx].changedFilesMultiplier;
|
|
3553
|
+
rerankerUpdatedCandidates++;
|
|
3552
3554
|
}
|
|
3553
3555
|
exactMatchPinningApplied = this.sortSearchCandidates(scored, rerankDecision.exactMatchPinningEnabled, parsedOperators.must.length > 0) || exactMatchPinningApplied;
|
|
3554
|
-
rerankerApplied =
|
|
3556
|
+
rerankerApplied = rerankerUpdatedCandidates > 0;
|
|
3555
3557
|
}
|
|
3556
3558
|
catch {
|
|
3557
3559
|
if (!rerankerFailurePhase) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zokizuan/satori-mcp",
|
|
3
|
-
"version": "4.11.
|
|
3
|
+
"version": "4.11.1",
|
|
4
4
|
"description": "MCP server for Satori with agent-safe semantic search and indexing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"jsonc-parser": "^3.3.1",
|
|
16
16
|
"zod": "^3.25.55",
|
|
17
17
|
"zod-to-json-schema": "^3.25.1",
|
|
18
|
-
"@zokizuan/satori-core": "1.6.
|
|
18
|
+
"@zokizuan/satori-core": "1.6.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^20.0.0",
|