@zokizuan/satori-mcp 4.11.1 → 4.11.2
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 +3 -3
- package/dist/config.js +1 -1
- package/dist/core/handlers.d.ts +1 -0
- package/dist/core/handlers.js +54 -8
- package/dist/core/search-types.d.ts +6 -4
- package/dist/server/bootstrap-stdio.js +1 -0
- package/dist/server/stdio-safety.d.ts +2 -0
- package/dist/server/stdio-safety.js +7 -7
- package/package.json +2 -2
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.2 install --client all
|
|
11
|
+
npx -y @zokizuan/satori-cli@0.4.2 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,7 +16,7 @@ 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.2 --help
|
|
20
20
|
```
|
|
21
21
|
|
|
22
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.
|
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.2 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.d.ts
CHANGED
|
@@ -116,6 +116,7 @@ export declare class ToolHandlers {
|
|
|
116
116
|
private collapseDuplicateDeclarationGroups;
|
|
117
117
|
private buildFallbackGroupId;
|
|
118
118
|
private isCallGraphLanguageSupported;
|
|
119
|
+
private loadCallGraphSidecarForSearch;
|
|
119
120
|
private buildCallGraphHint;
|
|
120
121
|
private sanitizeIndexedRelativeFilePath;
|
|
121
122
|
private buildNavigationFallback;
|
package/dist/core/handlers.js
CHANGED
|
@@ -1905,20 +1905,60 @@ export class ToolHandlers {
|
|
|
1905
1905
|
}
|
|
1906
1906
|
return false;
|
|
1907
1907
|
}
|
|
1908
|
-
|
|
1908
|
+
loadCallGraphSidecarForSearch(codebaseRoot) {
|
|
1909
|
+
const loadSidecar = this.callGraphManager?.loadSidecar;
|
|
1910
|
+
if (typeof loadSidecar !== 'function') {
|
|
1911
|
+
return null;
|
|
1912
|
+
}
|
|
1913
|
+
const sidecar = loadSidecar.call(this.callGraphManager, codebaseRoot);
|
|
1914
|
+
if (!sidecar || !Array.isArray(sidecar.nodes)) {
|
|
1915
|
+
return null;
|
|
1916
|
+
}
|
|
1917
|
+
return {
|
|
1918
|
+
builtAt: typeof sidecar.builtAt === 'string' ? sidecar.builtAt : undefined,
|
|
1919
|
+
nodes: sidecar.nodes,
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
buildCallGraphHint(file, language, sidecar, symbolId, symbolLabel) {
|
|
1909
1923
|
if (!symbolId) {
|
|
1910
1924
|
return { supported: false, reason: 'missing_symbol' };
|
|
1911
1925
|
}
|
|
1912
1926
|
if (!this.isCallGraphLanguageSupported(language, file)) {
|
|
1913
1927
|
return { supported: false, reason: 'unsupported_language' };
|
|
1914
1928
|
}
|
|
1929
|
+
if (!sidecar) {
|
|
1930
|
+
return { supported: false, reason: 'missing_sidecar' };
|
|
1931
|
+
}
|
|
1932
|
+
const normalizedFile = this.sanitizeIndexedRelativeFilePath(file);
|
|
1933
|
+
if (!normalizedFile) {
|
|
1934
|
+
return { supported: false, reason: 'stale_symbol_ref' };
|
|
1935
|
+
}
|
|
1936
|
+
const sidecarNode = sidecar.nodes.find((node) => node.symbolId === symbolId);
|
|
1937
|
+
const normalizedSidecarFile = sidecarNode ? this.sanitizeIndexedRelativeFilePath(sidecarNode.file) : undefined;
|
|
1938
|
+
const sidecarSpan = sidecarNode?.span;
|
|
1939
|
+
if (!sidecarNode ||
|
|
1940
|
+
normalizedSidecarFile !== normalizedFile ||
|
|
1941
|
+
!sidecarSpan ||
|
|
1942
|
+
!Number.isFinite(sidecarSpan.startLine) ||
|
|
1943
|
+
!Number.isFinite(sidecarSpan.endLine)) {
|
|
1944
|
+
return { supported: false, reason: 'stale_symbol_ref' };
|
|
1945
|
+
}
|
|
1946
|
+
const safeStartLine = Math.max(1, Number(sidecarSpan.startLine));
|
|
1947
|
+
const safeEndLine = Math.max(safeStartLine, Number(sidecarSpan.endLine));
|
|
1948
|
+
const validatedAt = new Date(this.now()).toISOString();
|
|
1915
1949
|
return {
|
|
1916
1950
|
supported: true,
|
|
1951
|
+
validated: true,
|
|
1952
|
+
validatedAt,
|
|
1953
|
+
sidecarBuiltAt: sidecar.builtAt || validatedAt,
|
|
1917
1954
|
symbolRef: {
|
|
1918
|
-
file,
|
|
1955
|
+
file: normalizedSidecarFile,
|
|
1919
1956
|
symbolId,
|
|
1920
|
-
symbolLabel: symbolLabel || undefined,
|
|
1921
|
-
span
|
|
1957
|
+
symbolLabel: sidecarNode.symbolLabel || symbolLabel || undefined,
|
|
1958
|
+
span: {
|
|
1959
|
+
startLine: safeStartLine,
|
|
1960
|
+
endLine: safeEndLine
|
|
1961
|
+
}
|
|
1922
1962
|
}
|
|
1923
1963
|
};
|
|
1924
1964
|
}
|
|
@@ -1978,12 +2018,13 @@ export class ToolHandlers {
|
|
|
1978
2018
|
if (!callGraphHint.supported) {
|
|
1979
2019
|
return undefined;
|
|
1980
2020
|
}
|
|
1981
|
-
const normalizedFile = this.sanitizeIndexedRelativeFilePath(relativeFilePath);
|
|
2021
|
+
const normalizedFile = this.sanitizeIndexedRelativeFilePath(callGraphHint.symbolRef.file || relativeFilePath);
|
|
1982
2022
|
if (!normalizedFile) {
|
|
1983
2023
|
return undefined;
|
|
1984
2024
|
}
|
|
1985
|
-
const
|
|
1986
|
-
const
|
|
2025
|
+
const actionSpan = callGraphHint.symbolRef.span || span;
|
|
2026
|
+
const safeStartLine = Number.isFinite(actionSpan.startLine) ? Math.max(1, Number(actionSpan.startLine)) : 1;
|
|
2027
|
+
const safeEndLine = Number.isFinite(actionSpan.endLine) ? Math.max(safeStartLine, Number(actionSpan.endLine)) : safeStartLine;
|
|
1987
2028
|
const absolutePath = path.resolve(codebaseRoot, normalizedFile);
|
|
1988
2029
|
const symbolRef = {
|
|
1989
2030
|
...callGraphHint.symbolRef,
|
|
@@ -3730,6 +3771,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
3730
3771
|
? this.snapshotManager.getCodebaseCallGraphSidecar(effectiveRoot)
|
|
3731
3772
|
: undefined;
|
|
3732
3773
|
const sidecarReadyForOutline = Boolean(sidecarInfo && sidecarInfo.version === 'v3');
|
|
3774
|
+
const callGraphSidecar = sidecarReadyForOutline ? this.loadCallGraphSidecarForSearch(effectiveRoot) : null;
|
|
3733
3775
|
const groupedResults = [];
|
|
3734
3776
|
for (const group of groups.values()) {
|
|
3735
3777
|
exactMatchPinningApplied = this.sortSearchCandidates(group.chunks, queryPlan.exactMatchPinningEnabled, parsedOperators.must.length > 0) || exactMatchPinningApplied;
|
|
@@ -3750,7 +3792,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
3750
3792
|
const repSymbolId = typeof representative.result.symbolId === 'string' ? representative.result.symbolId : null;
|
|
3751
3793
|
const repSymbolLabel = typeof representative.result.symbolLabel === 'string' ? representative.result.symbolLabel : null;
|
|
3752
3794
|
const groupId = repSymbolId || this.buildFallbackGroupId(representative.result.relativePath, span);
|
|
3753
|
-
const callGraphHint = this.buildCallGraphHint(representative.result.relativePath,
|
|
3795
|
+
const callGraphHint = this.buildCallGraphHint(representative.result.relativePath, representative.result.language || 'unknown', callGraphSidecar, repSymbolId || undefined, repSymbolLabel || undefined);
|
|
3754
3796
|
const navigationFallback = this.buildNavigationFallback(effectiveRoot, representative.result.relativePath, span, callGraphHint, sidecarReadyForOutline);
|
|
3755
3797
|
const nextActions = this.buildSearchNextActions(effectiveRoot, representative.result.relativePath, span, callGraphHint, sidecarReadyForOutline);
|
|
3756
3798
|
groupedResults.push({
|
|
@@ -4063,6 +4105,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
4063
4105
|
const endsAfterWindowStart = windowStart === undefined || node.span.endLine >= windowStart;
|
|
4064
4106
|
return startsBeforeWindowEnd && endsAfterWindowStart;
|
|
4065
4107
|
});
|
|
4108
|
+
const outlineValidatedAt = new Date(this.now()).toISOString();
|
|
4066
4109
|
const symbols = this.sortFileOutlineSymbols(windowed.map((node) => {
|
|
4067
4110
|
const symbolLabel = (typeof node.symbolLabel === 'string' && node.symbolLabel.trim().length > 0)
|
|
4068
4111
|
? node.symbolLabel
|
|
@@ -4076,6 +4119,9 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
4076
4119
|
},
|
|
4077
4120
|
callGraphHint: {
|
|
4078
4121
|
supported: true,
|
|
4122
|
+
validated: true,
|
|
4123
|
+
validatedAt: outlineValidatedAt,
|
|
4124
|
+
sidecarBuiltAt: sidecar.builtAt,
|
|
4079
4125
|
symbolRef: {
|
|
4080
4126
|
file: normalizedFile,
|
|
4081
4127
|
symbolId: node.symbolId,
|
|
@@ -15,9 +15,12 @@ export interface CallGraphSymbolRef {
|
|
|
15
15
|
export type CallGraphHint = {
|
|
16
16
|
supported: true;
|
|
17
17
|
symbolRef: CallGraphSymbolRef;
|
|
18
|
+
validated: true;
|
|
19
|
+
validatedAt: string;
|
|
20
|
+
sidecarBuiltAt: string;
|
|
18
21
|
} | {
|
|
19
22
|
supported: false;
|
|
20
|
-
reason: "missing_symbol" | "unsupported_language";
|
|
23
|
+
reason: "missing_symbol" | "unsupported_language" | "missing_sidecar" | "stale_symbol_ref";
|
|
21
24
|
};
|
|
22
25
|
export interface SearchNextActionReadSymbol {
|
|
23
26
|
tool: "read_file";
|
|
@@ -334,10 +337,9 @@ export interface FileOutlineSymbolResult {
|
|
|
334
337
|
symbolId: string;
|
|
335
338
|
symbolLabel: string;
|
|
336
339
|
span: SearchSpan;
|
|
337
|
-
callGraphHint: {
|
|
340
|
+
callGraphHint: Extract<CallGraphHint, {
|
|
338
341
|
supported: true;
|
|
339
|
-
|
|
340
|
-
};
|
|
342
|
+
}>;
|
|
341
343
|
}
|
|
342
344
|
export interface FileOutlineResponseEnvelope {
|
|
343
345
|
status: FileOutlineStatus;
|
|
@@ -2,6 +2,7 @@ import { installCliStdoutRedirect, installConsoleToStderrPatch } from "./stdio-s
|
|
|
2
2
|
export function installBootstrapStdioSafety(options) {
|
|
3
3
|
const restoreConsole = installConsoleToStderrPatch({
|
|
4
4
|
writeToStderr: options.writeToStderr,
|
|
5
|
+
methods: options.runMode === "mcp" ? ["warn", "error"] : undefined,
|
|
5
6
|
});
|
|
6
7
|
let restoreStdout = () => { };
|
|
7
8
|
if (options.guardMode !== "off") {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type StdoutGuardMode = "drop" | "redirect";
|
|
2
|
+
type ConsoleMethodName = "log" | "info" | "warn" | "error" | "debug";
|
|
2
3
|
interface ConsolePatchOptions {
|
|
3
4
|
writeToStderr?: (text: string) => void;
|
|
5
|
+
methods?: ConsoleMethodName[];
|
|
4
6
|
}
|
|
5
7
|
interface CliStdoutRedirectOptions {
|
|
6
8
|
mode?: StdoutGuardMode;
|
|
@@ -37,6 +37,7 @@ export function installConsoleToStderrPatch(options = {}) {
|
|
|
37
37
|
const writeToStderr = options.writeToStderr || ((text) => {
|
|
38
38
|
process.stderr.write(text);
|
|
39
39
|
});
|
|
40
|
+
const methods = options.methods || ["log", "info", "warn", "error", "debug"];
|
|
40
41
|
const original = {};
|
|
41
42
|
const patchMethod = (method) => {
|
|
42
43
|
original[method] = console[method];
|
|
@@ -44,11 +45,9 @@ export function installConsoleToStderrPatch(options = {}) {
|
|
|
44
45
|
writeToStderr(ensureTrailingNewline(args.map(toLogString).join(" ")));
|
|
45
46
|
};
|
|
46
47
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
patchMethod("error");
|
|
51
|
-
patchMethod("debug");
|
|
48
|
+
for (const method of methods) {
|
|
49
|
+
patchMethod(method);
|
|
50
|
+
}
|
|
52
51
|
return () => {
|
|
53
52
|
for (const method of Object.keys(original)) {
|
|
54
53
|
const fn = original[method];
|
|
@@ -72,10 +71,11 @@ export function installCliStdoutRedirect(options = {}) {
|
|
|
72
71
|
writeToStderr(ensureTrailingNewline(`[STDOUT_BLOCKED] ${text}`));
|
|
73
72
|
return;
|
|
74
73
|
}
|
|
75
|
-
writeToStderr(ensureTrailingNewline(`[STDOUT_BLOCKED] dropped len=${text.length}`));
|
|
76
74
|
return;
|
|
77
75
|
}
|
|
78
|
-
|
|
76
|
+
if (mode === "redirect") {
|
|
77
|
+
writeToStderr(ensureTrailingNewline(`[STDOUT_BLOCKED_BINARY len=${chunkLength(chunk)}]`));
|
|
78
|
+
}
|
|
79
79
|
};
|
|
80
80
|
const patch = (methodName, replacement) => {
|
|
81
81
|
const original = stdout[methodName];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zokizuan/satori-mcp",
|
|
3
|
-
"version": "4.11.
|
|
3
|
+
"version": "4.11.2",
|
|
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.2"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^20.0.0",
|