@zokizuan/satori-mcp 1.0.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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +215 -0
  3. package/dist/config.d.ts +89 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +221 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/core/ast_breadcrumbs.test.d.ts +2 -0
  8. package/dist/core/ast_breadcrumbs.test.d.ts.map +1 -0
  9. package/dist/core/ast_breadcrumbs.test.js +72 -0
  10. package/dist/core/ast_breadcrumbs.test.js.map +1 -0
  11. package/dist/core/capabilities.d.ts +31 -0
  12. package/dist/core/capabilities.d.ts.map +1 -0
  13. package/dist/core/capabilities.js +80 -0
  14. package/dist/core/capabilities.js.map +1 -0
  15. package/dist/core/capabilities.test.d.ts +2 -0
  16. package/dist/core/capabilities.test.d.ts.map +1 -0
  17. package/dist/core/capabilities.test.js +49 -0
  18. package/dist/core/capabilities.test.js.map +1 -0
  19. package/dist/core/handlers.d.ts +79 -0
  20. package/dist/core/handlers.d.ts.map +1 -0
  21. package/dist/core/handlers.js +1295 -0
  22. package/dist/core/handlers.js.map +1 -0
  23. package/dist/core/handlers.scope.test.d.ts +2 -0
  24. package/dist/core/handlers.scope.test.d.ts.map +1 -0
  25. package/dist/core/handlers.scope.test.js +122 -0
  26. package/dist/core/handlers.scope.test.js.map +1 -0
  27. package/dist/core/snapshot.d.ts +67 -0
  28. package/dist/core/snapshot.d.ts.map +1 -0
  29. package/dist/core/snapshot.js +362 -0
  30. package/dist/core/snapshot.js.map +1 -0
  31. package/dist/core/snapshot.test.d.ts +2 -0
  32. package/dist/core/snapshot.test.d.ts.map +1 -0
  33. package/dist/core/snapshot.test.js +119 -0
  34. package/dist/core/snapshot.test.js.map +1 -0
  35. package/dist/core/sync.d.ts +43 -0
  36. package/dist/core/sync.d.ts.map +1 -0
  37. package/dist/core/sync.js +337 -0
  38. package/dist/core/sync.js.map +1 -0
  39. package/dist/core/sync.test.d.ts +2 -0
  40. package/dist/core/sync.test.d.ts.map +1 -0
  41. package/dist/core/sync.test.js +101 -0
  42. package/dist/core/sync.test.js.map +1 -0
  43. package/dist/embedding.d.ts +5 -0
  44. package/dist/embedding.d.ts.map +1 -0
  45. package/dist/embedding.js +81 -0
  46. package/dist/embedding.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +235 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/telemetry/search.d.ts +16 -0
  52. package/dist/telemetry/search.d.ts.map +1 -0
  53. package/dist/telemetry/search.js +4 -0
  54. package/dist/telemetry/search.js.map +1 -0
  55. package/dist/tools/list_codebases.d.ts +3 -0
  56. package/dist/tools/list_codebases.d.ts.map +1 -0
  57. package/dist/tools/list_codebases.js +78 -0
  58. package/dist/tools/list_codebases.js.map +1 -0
  59. package/dist/tools/manage_index.d.ts +3 -0
  60. package/dist/tools/manage_index.d.ts.map +1 -0
  61. package/dist/tools/manage_index.js +48 -0
  62. package/dist/tools/manage_index.js.map +1 -0
  63. package/dist/tools/read_file.d.ts +3 -0
  64. package/dist/tools/read_file.d.ts.map +1 -0
  65. package/dist/tools/read_file.js +115 -0
  66. package/dist/tools/read_file.js.map +1 -0
  67. package/dist/tools/read_file.test.d.ts +2 -0
  68. package/dist/tools/read_file.test.d.ts.map +1 -0
  69. package/dist/tools/read_file.test.js +96 -0
  70. package/dist/tools/read_file.test.js.map +1 -0
  71. package/dist/tools/registry.d.ts +9 -0
  72. package/dist/tools/registry.d.ts.map +1 -0
  73. package/dist/tools/registry.js +30 -0
  74. package/dist/tools/registry.js.map +1 -0
  75. package/dist/tools/registry.test.d.ts +2 -0
  76. package/dist/tools/registry.test.d.ts.map +1 -0
  77. package/dist/tools/registry.test.js +58 -0
  78. package/dist/tools/registry.test.js.map +1 -0
  79. package/dist/tools/search_codebase.d.ts +3 -0
  80. package/dist/tools/search_codebase.d.ts.map +1 -0
  81. package/dist/tools/search_codebase.js +386 -0
  82. package/dist/tools/search_codebase.js.map +1 -0
  83. package/dist/tools/search_codebase.test.d.ts +2 -0
  84. package/dist/tools/search_codebase.test.d.ts.map +1 -0
  85. package/dist/tools/search_codebase.test.js +269 -0
  86. package/dist/tools/search_codebase.test.js.map +1 -0
  87. package/dist/tools/types.d.ts +33 -0
  88. package/dist/tools/types.d.ts.map +1 -0
  89. package/dist/tools/types.js +8 -0
  90. package/dist/tools/types.js.map +1 -0
  91. package/dist/utils.d.ts +10 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +27 -0
  94. package/dist/utils.js.map +1 -0
  95. package/package.json +55 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ham-zax
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ # @zokizuan/satori-mcp
2
+
3
+ MCP server for Satori.
4
+ Satori means "sudden insight"; this package turns core indexing/search into agent-safe MCP actions.
5
+
6
+ Maintained by: `ham-zax` (`@zokizuan`).
7
+
8
+ ## Breaking Change (v1.0.0)
9
+
10
+ Tool surface is now hard-broken to 4 tools only:
11
+
12
+ - `manage_index`
13
+ - `search_codebase`
14
+ - `read_file`
15
+ - `list_codebases`
16
+
17
+ Removed tools from pre-1.0 releases are no longer routed.
18
+
19
+ ## Features
20
+
21
+ - Capability-driven execution via `CapabilityResolver`.
22
+ - Unified `search_codebase` flow with optional reranker override:
23
+ - `useReranker=true`: force rerank (errors if capability missing)
24
+ - `useReranker=false`: disable rerank
25
+ - `useReranker` omitted: auto behavior by capability/profile
26
+ - Snapshot `v3` safety with index fingerprints and strict `requires_reindex` access gates.
27
+ - Deterministic train-in-the-error responses for incompatible or legacy index states.
28
+ - Query-time exclusion support with `.gitignore`-style matching.
29
+ - Structured search telemetry logs (`[TELEMETRY]` JSON to `stderr`).
30
+ - Zod-first tool schemas converted to MCP JSON Schema for `ListTools`.
31
+ - Auto-generated tool docs in this README from live tool schemas.
32
+ - `read_file` line-range retrieval with default large-file truncation guard.
33
+ - Optional proactive sync watcher mode (debounced filesystem events).
34
+ - Index-time AST scope breadcrumbs (TS/JS/Python) rendered in search output as `🧬 Scope`.
35
+ - Fingerprint schema bump to `dense_v2`/`hybrid_v2` with strict reindex gate for legacy `*_v1` indexes.
36
+ - Non-AST files (for example Markdown) remain searchable when included and not ignored; they simply omit `🧬 Scope`.
37
+
38
+ ## Architecture Evolution
39
+
40
+ ### Before (pre-v1.0.0)
41
+
42
+ - Monolithic routing and execution concentrated in `index.ts` + `handlers.ts`.
43
+ - Redundant tool surface (9 tools) increased agent/tool-selection ambiguity.
44
+ - Inline JSON schemas and docs drift risk.
45
+ - Environment checks leaked across runtime paths.
46
+ - Snapshot state lacked robust fingerprint protection for model/provider changes.
47
+
48
+ ### After (v1.0.0+)
49
+
50
+ - Lightweight bootstrap in `index.ts` with registry-based tool routing.
51
+ - Hard-break 4-tool surface optimized for agent cognition.
52
+ - Modular tool execution in `src/tools/*.ts` with a shared `ToolContext`.
53
+ - Zod schemas as canonical source, converted to JSON Schema at runtime.
54
+ - Snapshot `v3` + fingerprint compatibility gates for safe multi-provider usage.
55
+ - Deterministic train-in-the-error messages for self-healing agent loops.
56
+ - Search observability via structured telemetry.
57
+ - `read_file` upgraded for context-density control (ranges + truncation guard).
58
+
59
+ ### Architectural Shape (Current)
60
+
61
+ ```text
62
+ [MCP Client]
63
+ -> [index.ts bootstrap + ListTools/CallTool]
64
+ -> [tool registry]
65
+ -> [manage_index | search_codebase | read_file | list_codebases]
66
+ -> [ToolContext DI]
67
+ -> [CapabilityResolver]
68
+ -> [SnapshotManager v3 + access gate]
69
+ -> [Context / Vector store / Embedding / Reranker adapters]
70
+ ```
71
+
72
+ ## Phase Summary
73
+
74
+ - Phase 1 (state safety + API hard break):
75
+ - 9 tools -> 4 tools
76
+ - capability-driven behavior
77
+ - snapshot `v3` with index fingerprinting and strict reindex gating
78
+ - Phase 2 (modularization + observability):
79
+ - tool registry and modular `src/tools/*`
80
+ - Zod-first schemas and generated docs
81
+ - structured search telemetry
82
+ - Phase 3 (context density):
83
+ - `read_file` line-range semantics
84
+ - safe clamping for out-of-range requests
85
+ - `READ_FILE_MAX_LINES` truncation and continuation hints
86
+ - Phase 5A (advanced context density, search-first):
87
+ - index-time AST breadcrumbs stored in chunk metadata (`breadcrumbs`)
88
+ - `search_codebase` scope rendering (`🧬 Scope: outer > inner`) across standard and rerank views
89
+ - fingerprint schema version bump to `*_v2` requiring reindex for `*_v1` snapshots
90
+
91
+ ## read_file Behavior
92
+
93
+ - Supports optional `start_line` and `end_line` (1-based, inclusive).
94
+ - When no range is provided and file length exceeds `READ_FILE_MAX_LINES` (default `1000`), output is truncated and includes a continuation hint with `path` and next `start_line`.
95
+
96
+ ## Proactive Sync (Optional)
97
+
98
+ - Enabled by default. Set `MCP_ENABLE_WATCHER=false` to disable.
99
+ - Debounce window via `MCP_WATCH_DEBOUNCE_MS` (default `5000`).
100
+ - Watch events reuse the same incremental sync pipeline (`reindexByChange`) and keep `manage_index(action="sync")` as explicit fallback.
101
+ - Safety gates:
102
+ - watch-triggered sync only runs for `indexed`/`sync_completed` codebases.
103
+ - events are dropped for `indexing`, `indexfailed`, and `requires_reindex`.
104
+ - ignored/hidden paths are excluded to avoid watcher explosion (`node_modules`, `.git`, build artifacts, dotfiles).
105
+ - On shutdown (`SIGINT`/`SIGTERM`), watchers are explicitly closed.
106
+
107
+ ## Future Plan
108
+
109
+ ### 1) Agent Context Density
110
+
111
+ - Add optional `read_file` paging ergonomics beyond current line ranges (for very large files/workflows).
112
+ - Explore syntax-aware snippet shaping in `search_codebase` so results preserve function/class boundaries more reliably.
113
+
114
+ ### 2) Proactive Sync
115
+
116
+ - Introduce optional filesystem watching with debounce for near-real-time incremental indexing.
117
+ - Keep manual `manage_index(action="sync")` as explicit fallback.
118
+
119
+ ### 3) Provider Expansion
120
+
121
+ - Extend reranker adapters (for example, Cohere) behind the same capability model.
122
+ - Evaluate local vector-store adapters to support fully offline deployments.
123
+
124
+ ### 4) Observability Productization
125
+
126
+ - Expand telemetry consumption into a local stats/report workflow (latency, reranker utilization, filter/drop rates).
127
+ - Keep CI fast with deterministic unit/in-memory tests; run provider-backed integration checks on scheduled/manual workflows.
128
+
129
+ <!-- TOOLS_START -->
130
+
131
+ ## Tool Reference
132
+
133
+ ### `manage_index`
134
+
135
+ Manage index lifecycle operations (create/sync/status/clear) for a codebase path.
136
+
137
+ | Parameter | Type | Required | Default | Description |
138
+ |---|---|---|---|---|
139
+ | `action` | enum("create", "sync", "status", "clear") | yes | | Required operation to run. |
140
+ | `path` | string | yes | | ABSOLUTE path to the target codebase. |
141
+ | `force` | boolean | no | | Only for action='create'. Force rebuild from scratch. |
142
+ | `splitter` | enum("ast", "langchain") | no | | Only for action='create'. Code splitter strategy. |
143
+ | `customExtensions` | array<string> | no | | Only for action='create'. Additional file extensions to include. |
144
+ | `ignorePatterns` | array<string> | no | | Only for action='create'. Additional ignore patterns to apply. |
145
+
146
+ ### `search_codebase`
147
+
148
+ Unified semantic search tool. Supports optional reranking and query-time excludes. Reranker is available. If useReranker is omitted, reranking is enabled automatically for fast/standard profiles.
149
+
150
+ | Parameter | Type | Required | Default | Description |
151
+ |---|---|---|---|---|
152
+ | `path` | string | yes | | ABSOLUTE path to an indexed codebase or subdirectory. |
153
+ | `query` | string | yes | | Natural-language query. |
154
+ | `limit` | integer | no | `50` | Maximum results to return. |
155
+ | `extensionFilter` | array<string> | no | `[]` | Optional file-extension filter (e.g. ['.ts','.py']). |
156
+ | `useIgnoreFiles` | boolean | no | `true` | Apply repo ignore files at search-time. |
157
+ | `excludePatterns` | array<string> | no | `[]` | Optional query-time exclude patterns. |
158
+ | `returnRaw` | boolean | no | `false` | Return machine-readable JSON results. |
159
+ | `showScores` | boolean | no | `false` | Include similarity scores in formatted output. |
160
+ | `useReranker` | boolean | no | | Optional override: true=force rerank, false=disable rerank, omitted=resolver default. |
161
+
162
+ ### `read_file`
163
+
164
+ Read file content from the local filesystem, with optional 1-based inclusive line ranges and safe truncation.
165
+
166
+ | Parameter | Type | Required | Default | Description |
167
+ |---|---|---|---|---|
168
+ | `path` | string | yes | | ABSOLUTE path to the file. |
169
+ | `start_line` | integer | no | | Optional start line (1-based, inclusive). |
170
+ | `end_line` | integer | no | | Optional end line (1-based, inclusive). |
171
+
172
+ ### `list_codebases`
173
+
174
+ List tracked codebases and their indexing state.
175
+
176
+ No parameters.
177
+
178
+
179
+ <!-- TOOLS_END -->
180
+
181
+ ## Run Locally
182
+
183
+ ```bash
184
+ pnpm --filter @zokizuan/satori-mcp start
185
+ ```
186
+
187
+ ## Example MCP Configuration
188
+
189
+ ```json
190
+ {
191
+ "mcpServers": {
192
+ "satori": {
193
+ "command": "npx",
194
+ "args": ["@zokizuan/satori-mcp@latest"],
195
+ "env": {
196
+ "EMBEDDING_PROVIDER": "VoyageAI",
197
+ "VOYAGEAI_API_KEY": "your-api-key",
198
+ "MILVUS_ADDRESS": "your-milvus-endpoint",
199
+ "MILVUS_TOKEN": "your-milvus-token"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ ## Development
207
+
208
+ ```bash
209
+ pnpm --filter @zokizuan/satori-mcp build
210
+ pnpm --filter @zokizuan/satori-mcp typecheck
211
+ pnpm --filter @zokizuan/satori-mcp test
212
+ pnpm --filter @zokizuan/satori-mcp docs:check
213
+ ```
214
+
215
+ `build` automatically runs docs generation from tool schemas.
@@ -0,0 +1,89 @@
1
+ export type EmbeddingProvider = 'OpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama';
2
+ export type VectorStoreProvider = 'Milvus';
3
+ export type FingerprintSource = 'verified' | 'assumed_v2';
4
+ export interface IndexFingerprint {
5
+ embeddingProvider: EmbeddingProvider;
6
+ embeddingModel: string;
7
+ embeddingDimension: number;
8
+ vectorStoreProvider: VectorStoreProvider;
9
+ schemaVersion: 'dense_v2' | 'hybrid_v2';
10
+ }
11
+ export interface ContextMcpConfig {
12
+ name: string;
13
+ version: string;
14
+ encoderProvider: EmbeddingProvider;
15
+ encoderModel: string;
16
+ encoderOutputDimension?: number;
17
+ openaiKey?: string;
18
+ openaiEndpoint?: string;
19
+ voyageKey?: string;
20
+ geminiKey?: string;
21
+ geminiEndpoint?: string;
22
+ ollamaEncoderModel?: string;
23
+ ollamaEndpoint?: string;
24
+ milvusEndpoint?: string;
25
+ milvusApiToken?: string;
26
+ rankerModel?: 'rerank-2.5' | 'rerank-2.5-lite' | 'rerank-2' | 'rerank-2-lite';
27
+ readFileMaxLines?: number;
28
+ watchSyncEnabled?: boolean;
29
+ watchDebounceMs?: number;
30
+ }
31
+ export interface CodebaseSnapshotV1 {
32
+ indexedCodebases: string[];
33
+ indexingCodebases: string[] | Record<string, number>;
34
+ lastUpdated: string;
35
+ }
36
+ interface CodebaseInfoBase {
37
+ lastUpdated: string;
38
+ indexFingerprint?: IndexFingerprint;
39
+ fingerprintSource?: FingerprintSource;
40
+ reindexReason?: 'legacy_unverified_fingerprint' | 'fingerprint_mismatch' | 'missing_fingerprint';
41
+ }
42
+ export interface CodebaseInfoIndexing extends CodebaseInfoBase {
43
+ status: 'indexing';
44
+ indexingPercentage: number;
45
+ }
46
+ export interface CodebaseInfoIndexed extends CodebaseInfoBase {
47
+ status: 'indexed';
48
+ indexedFiles: number;
49
+ totalChunks: number;
50
+ indexStatus: 'completed' | 'limit_reached';
51
+ }
52
+ export interface CodebaseInfoIndexFailed extends CodebaseInfoBase {
53
+ status: 'indexfailed';
54
+ errorMessage: string;
55
+ lastAttemptedPercentage?: number;
56
+ }
57
+ export interface CodebaseInfoSyncCompleted extends CodebaseInfoBase {
58
+ status: 'sync_completed';
59
+ added: number;
60
+ removed: number;
61
+ modified: number;
62
+ totalChanges: number;
63
+ }
64
+ export interface CodebaseInfoRequiresReindex extends CodebaseInfoBase {
65
+ status: 'requires_reindex';
66
+ message: string;
67
+ }
68
+ export type CodebaseInfo = CodebaseInfoIndexing | CodebaseInfoIndexed | CodebaseInfoIndexFailed | CodebaseInfoSyncCompleted | CodebaseInfoRequiresReindex;
69
+ export interface CodebaseSnapshotV2 {
70
+ formatVersion: 'v2';
71
+ codebases: Record<string, Omit<CodebaseInfo, 'status'> & {
72
+ status: 'indexing' | 'indexed' | 'indexfailed' | 'sync_completed';
73
+ }>;
74
+ lastUpdated: string;
75
+ }
76
+ export interface CodebaseSnapshotV3 {
77
+ formatVersion: 'v3';
78
+ codebases: Record<string, CodebaseInfo>;
79
+ lastUpdated: string;
80
+ }
81
+ export type CodebaseSnapshot = CodebaseSnapshotV1 | CodebaseSnapshotV2 | CodebaseSnapshotV3;
82
+ export declare function getDefaultModelForProvider(provider: string): string;
83
+ export declare function getEmbeddingModelForProvider(provider: string): string;
84
+ export declare function buildRuntimeIndexFingerprint(config: ContextMcpConfig, embeddingDimension: number): IndexFingerprint;
85
+ export declare function createMcpConfig(): ContextMcpConfig;
86
+ export declare function logConfigurationSummary(config: ContextMcpConfig): void;
87
+ export declare function showHelpMessage(): void;
88
+ export {};
89
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,221 @@
1
+ import { envManager } from "@zokizuan/satori-core";
2
+ // Helper function to get default model for each provider
3
+ export function getDefaultModelForProvider(provider) {
4
+ switch (provider) {
5
+ case 'OpenAI':
6
+ return 'text-embedding-3-small';
7
+ case 'VoyageAI':
8
+ return 'voyage-4-large';
9
+ case 'Gemini':
10
+ return 'gemini-embedding-001';
11
+ case 'Ollama':
12
+ return 'nomic-embed-text';
13
+ default:
14
+ return 'text-embedding-3-small';
15
+ }
16
+ }
17
+ // Helper function to get embedding model with provider-specific environment variable priority
18
+ export function getEmbeddingModelForProvider(provider) {
19
+ switch (provider) {
20
+ case 'Ollama': {
21
+ // For Ollama, prioritize OLLAMA_MODEL over EMBEDDING_MODEL for backward compatibility
22
+ const ollamaEncoderModel = envManager.get('OLLAMA_MODEL') || envManager.get('EMBEDDING_MODEL') || getDefaultModelForProvider(provider);
23
+ return ollamaEncoderModel;
24
+ }
25
+ case 'OpenAI':
26
+ case 'VoyageAI':
27
+ case 'Gemini':
28
+ default: {
29
+ // For all other providers, use EMBEDDING_MODEL or default
30
+ const selectedModel = envManager.get('EMBEDDING_MODEL') || getDefaultModelForProvider(provider);
31
+ return selectedModel;
32
+ }
33
+ }
34
+ }
35
+ function getSchemaVersionFromEnv() {
36
+ const hybridModeRaw = envManager.get('HYBRID_MODE');
37
+ if (!hybridModeRaw) {
38
+ return 'hybrid_v2';
39
+ }
40
+ return hybridModeRaw.toLowerCase() === 'true' ? 'hybrid_v2' : 'dense_v2';
41
+ }
42
+ export function buildRuntimeIndexFingerprint(config, embeddingDimension) {
43
+ return {
44
+ embeddingProvider: config.encoderProvider,
45
+ embeddingModel: config.encoderModel,
46
+ embeddingDimension,
47
+ vectorStoreProvider: 'Milvus',
48
+ schemaVersion: getSchemaVersionFromEnv()
49
+ };
50
+ }
51
+ export function createMcpConfig() {
52
+ const defaultProvider = envManager.get('EMBEDDING_PROVIDER') || 'VoyageAI';
53
+ const defaultReadFileMaxLines = 1000;
54
+ const defaultWatchDebounceMs = 5000;
55
+ // Parse output dimension from env var
56
+ const outputDimensionStr = envManager.get('EMBEDDING_OUTPUT_DIMENSION');
57
+ let encoderOutputDimension;
58
+ if (outputDimensionStr) {
59
+ const parsed = parseInt(outputDimensionStr, 10);
60
+ if ([256, 512, 1024, 2048].includes(parsed)) {
61
+ encoderOutputDimension = parsed;
62
+ }
63
+ else {
64
+ console.warn(`[WARN] Invalid EMBEDDING_OUTPUT_DIMENSION value: ${outputDimensionStr}. Must be 256, 512, 1024, or 2048.`);
65
+ }
66
+ }
67
+ else if (defaultProvider === 'VoyageAI') {
68
+ // Default to 1024 for VoyageAI to balance quality/cost.
69
+ encoderOutputDimension = 1024;
70
+ }
71
+ // Parse reranker model from env var
72
+ const rankerModelEnv = envManager.get('VOYAGEAI_RERANKER_MODEL');
73
+ let rankerModel;
74
+ if (rankerModelEnv && ['rerank-2.5', 'rerank-2.5-lite', 'rerank-2', 'rerank-2-lite'].includes(rankerModelEnv)) {
75
+ rankerModel = rankerModelEnv;
76
+ }
77
+ else {
78
+ rankerModel = 'rerank-2.5';
79
+ }
80
+ let readFileMaxLines = defaultReadFileMaxLines;
81
+ const readFileMaxLinesRaw = envManager.get('READ_FILE_MAX_LINES');
82
+ if (readFileMaxLinesRaw) {
83
+ const parsed = Number.parseInt(readFileMaxLinesRaw, 10);
84
+ if (Number.isFinite(parsed) && parsed > 0) {
85
+ readFileMaxLines = parsed;
86
+ }
87
+ else {
88
+ console.warn(`[WARN] Invalid READ_FILE_MAX_LINES value: ${readFileMaxLinesRaw}. Using default ${defaultReadFileMaxLines}.`);
89
+ }
90
+ }
91
+ const watchSyncEnabledRaw = envManager.get('MCP_ENABLE_WATCHER');
92
+ const watchSyncEnabled = watchSyncEnabledRaw
93
+ ? watchSyncEnabledRaw.toLowerCase() === 'true'
94
+ : true;
95
+ let watchDebounceMs = defaultWatchDebounceMs;
96
+ const watchDebounceRaw = envManager.get('MCP_WATCH_DEBOUNCE_MS');
97
+ if (watchDebounceRaw) {
98
+ const parsed = Number.parseInt(watchDebounceRaw, 10);
99
+ if (Number.isFinite(parsed) && parsed > 0) {
100
+ watchDebounceMs = parsed;
101
+ }
102
+ else {
103
+ console.warn(`[WARN] Invalid MCP_WATCH_DEBOUNCE_MS value: ${watchDebounceRaw}. Using default ${defaultWatchDebounceMs}.`);
104
+ }
105
+ }
106
+ const config = {
107
+ name: envManager.get('MCP_SERVER_NAME') || "Satori MCP Server",
108
+ version: envManager.get('MCP_SERVER_VERSION') || "1.0.0",
109
+ // Embedding provider configuration
110
+ encoderProvider: defaultProvider,
111
+ encoderModel: getEmbeddingModelForProvider(defaultProvider),
112
+ encoderOutputDimension,
113
+ // Provider-specific API keys
114
+ openaiKey: envManager.get('OPENAI_API_KEY'),
115
+ openaiEndpoint: envManager.get('OPENAI_BASE_URL'),
116
+ voyageKey: envManager.get('VOYAGEAI_API_KEY'),
117
+ geminiKey: envManager.get('GEMINI_API_KEY'),
118
+ geminiEndpoint: envManager.get('GEMINI_BASE_URL'),
119
+ // Ollama configuration
120
+ ollamaEncoderModel: envManager.get('OLLAMA_MODEL'),
121
+ ollamaEndpoint: envManager.get('OLLAMA_HOST'),
122
+ // Vector database configuration - address can be auto-resolved from token
123
+ milvusEndpoint: envManager.get('MILVUS_ADDRESS'), // Optional, can be resolved from token
124
+ milvusApiToken: envManager.get('MILVUS_TOKEN'),
125
+ // Reranker configuration
126
+ rankerModel,
127
+ // read_file behavior
128
+ readFileMaxLines,
129
+ // proactive sync watcher behavior
130
+ watchSyncEnabled,
131
+ watchDebounceMs,
132
+ };
133
+ return config;
134
+ }
135
+ export function logConfigurationSummary(config) {
136
+ // Log configuration summary before starting server
137
+ console.log(`[MCP] 🚀 Starting Satori MCP Server`);
138
+ console.log(`[MCP] Configuration Summary:`);
139
+ console.log(`[MCP] Server: ${config.name} v${config.version}`);
140
+ console.log(`[MCP] Embedding Provider: ${config.encoderProvider}`);
141
+ console.log(`[MCP] Embedding Model: ${config.encoderModel}`);
142
+ console.log(`[MCP] Milvus Address: ${config.milvusEndpoint || (config.milvusApiToken ? '[Auto-resolve from token]' : '[Not configured]')}`);
143
+ console.log(`[MCP] Proactive Watcher: ${config.watchSyncEnabled ? `enabled (${config.watchDebounceMs || 5000}ms debounce)` : 'disabled'}`);
144
+ // Log provider-specific configuration without exposing sensitive data
145
+ switch (config.encoderProvider) {
146
+ case 'OpenAI':
147
+ console.log(`[MCP] OpenAI API Key: ${config.openaiKey ? '✅ Configured' : '❌ Missing'}`);
148
+ if (config.openaiEndpoint) {
149
+ console.log(`[MCP] OpenAI Base URL: ${config.openaiEndpoint}`);
150
+ }
151
+ break;
152
+ case 'VoyageAI':
153
+ console.log(`[MCP] VoyageAI API Key: ${config.voyageKey ? '✅ Configured' : '❌ Missing'}`);
154
+ break;
155
+ case 'Gemini':
156
+ console.log(`[MCP] Gemini API Key: ${config.geminiKey ? '✅ Configured' : '❌ Missing'}`);
157
+ if (config.geminiEndpoint) {
158
+ console.log(`[MCP] Gemini Base URL: ${config.geminiEndpoint}`);
159
+ }
160
+ break;
161
+ case 'Ollama':
162
+ console.log(`[MCP] Ollama Host: ${config.ollamaEndpoint || 'http://127.0.0.1:11434'}`);
163
+ console.log(`[MCP] Ollama Model: ${config.encoderModel}`);
164
+ break;
165
+ }
166
+ console.log(`[MCP] 🔧 Initializing server components...`);
167
+ }
168
+ export function showHelpMessage() {
169
+ console.log(`
170
+ Satori MCP Server
171
+
172
+ Usage: npx @zokizuan/satori-mcp@latest [options]
173
+
174
+ Options:
175
+ --help, -h Show this help message
176
+
177
+ Environment Variables:
178
+ MCP_SERVER_NAME Server name
179
+ MCP_SERVER_VERSION Server version
180
+
181
+ Embedding Provider Configuration:
182
+ EMBEDDING_PROVIDER Embedding provider: OpenAI, VoyageAI, Gemini, Ollama (default: VoyageAI)
183
+ EMBEDDING_MODEL Embedding model name (works for all providers)
184
+
185
+ Provider-specific API Keys:
186
+ OPENAI_API_KEY OpenAI API key (required for OpenAI provider)
187
+ OPENAI_BASE_URL OpenAI API base URL (optional, for custom endpoints)
188
+ VOYAGEAI_API_KEY VoyageAI API key (required for VoyageAI provider)
189
+ GEMINI_API_KEY Google AI API key (required for Gemini provider)
190
+ GEMINI_BASE_URL Gemini API base URL (optional, for custom endpoints)
191
+
192
+ Ollama Configuration:
193
+ OLLAMA_HOST Ollama server host (default: http://127.0.0.1:11434)
194
+ OLLAMA_MODEL Ollama model name (alternative to EMBEDDING_MODEL for Ollama)
195
+
196
+ Vector Database Configuration:
197
+ MILVUS_ADDRESS Milvus address (optional, can be auto-resolved from token)
198
+ MILVUS_TOKEN Milvus token (optional, used for authentication and address resolution)
199
+
200
+ Read File Configuration:
201
+ READ_FILE_MAX_LINES Max lines returned by read_file when no explicit range is provided (default: 1000)
202
+
203
+ Proactive Sync Configuration:
204
+ MCP_ENABLE_WATCHER Enable filesystem watch mode for near-real-time sync (default: true)
205
+ MCP_WATCH_DEBOUNCE_MS Debounce window for watch-triggered sync in milliseconds (default: 5000)
206
+
207
+ Examples:
208
+ # Start MCP server with OpenAI and explicit Milvus address
209
+ OPENAI_API_KEY=sk-xxx MILVUS_ADDRESS=localhost:19530 npx @zokizuan/satori-mcp@latest
210
+
211
+ # Start MCP server with VoyageAI and specific model
212
+ EMBEDDING_PROVIDER=VoyageAI VOYAGEAI_API_KEY=pa-xxx EMBEDDING_MODEL=voyage-4-large MILVUS_TOKEN=your-token npx @zokizuan/satori-mcp@latest
213
+
214
+ # Start MCP server with Gemini and specific model
215
+ EMBEDDING_PROVIDER=Gemini GEMINI_API_KEY=xxx EMBEDDING_MODEL=gemini-embedding-001 MILVUS_TOKEN=your-token npx @zokizuan/satori-mcp@latest
216
+
217
+ # Start MCP server with Ollama and specific model
218
+ EMBEDDING_PROVIDER=Ollama EMBEDDING_MODEL=nomic-embed-text MILVUS_TOKEN=your-token npx @zokizuan/satori-mcp@latest
219
+ `);
220
+ }
221
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ast_breadcrumbs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast_breadcrumbs.test.d.ts","sourceRoot":"","sources":["../../src/core/ast_breadcrumbs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { AstCodeSplitter } from '@zokizuan/satori-core';
4
+ test('AstCodeSplitter emits TS class/method breadcrumbs', async () => {
5
+ const splitter = new AstCodeSplitter();
6
+ const code = [
7
+ 'export class AuthManager {',
8
+ ' async validateSession(token: string) {',
9
+ ' return token.length > 0;',
10
+ ' }',
11
+ '}'
12
+ ].join('\n');
13
+ const chunks = await splitter.split(code, 'typescript', '/tmp/auth.ts');
14
+ const target = chunks.find((chunk) => chunk.content.includes('return token.length > 0;')
15
+ && Array.isArray(chunk.metadata.breadcrumbs)
16
+ && chunk.metadata.breadcrumbs.length === 2);
17
+ assert.ok(target);
18
+ assert.deepEqual(target?.metadata.breadcrumbs, ['class AuthManager', 'async method validateSession(token: string)']);
19
+ });
20
+ test('AstCodeSplitter emits Python class/function breadcrumbs', async () => {
21
+ const splitter = new AstCodeSplitter();
22
+ const code = [
23
+ 'class SessionManager:',
24
+ ' async def validate(self, token: str):',
25
+ ' return token',
26
+ ''
27
+ ].join('\n');
28
+ const chunks = await splitter.split(code, 'python', '/tmp/auth.py');
29
+ const target = chunks.find((chunk) => chunk.content.includes('return token')
30
+ && Array.isArray(chunk.metadata.breadcrumbs)
31
+ && chunk.metadata.breadcrumbs.length === 2);
32
+ assert.ok(target);
33
+ assert.deepEqual(target?.metadata.breadcrumbs, ['class SessionManager', 'async function validate(self, token: str)']);
34
+ });
35
+ test('AstCodeSplitter caps breadcrumb depth at 2', async () => {
36
+ const splitter = new AstCodeSplitter();
37
+ const code = [
38
+ 'class A {',
39
+ ' outer() {',
40
+ ' const inner = () => {',
41
+ ' return 1;',
42
+ ' };',
43
+ ' return inner();',
44
+ ' }',
45
+ '}'
46
+ ].join('\n');
47
+ const chunks = await splitter.split(code, 'typescript', '/tmp/depth.ts');
48
+ for (const chunk of chunks) {
49
+ if (Array.isArray(chunk.metadata.breadcrumbs)) {
50
+ assert.ok(chunk.metadata.breadcrumbs.length <= 2);
51
+ }
52
+ }
53
+ });
54
+ test('AstCodeSplitter preserves breadcrumbs when splitting large chunks', async () => {
55
+ const splitter = new AstCodeSplitter(80, 0);
56
+ const repeatedBody = Array.from({ length: 30 }, (_, i) => ` const v${i} = token + ${i};`).join('\n');
57
+ const code = [
58
+ 'class LargeAuth {',
59
+ ' validate(token: string) {',
60
+ repeatedBody,
61
+ ' return token;',
62
+ ' }',
63
+ '}'
64
+ ].join('\n');
65
+ const chunks = await splitter.split(code, 'typescript', '/tmp/large.ts');
66
+ const methodChunks = chunks.filter((chunk) => Array.isArray(chunk.metadata.breadcrumbs) && chunk.metadata.breadcrumbs.includes('method validate(token: string)'));
67
+ assert.ok(methodChunks.length > 1);
68
+ for (const chunk of methodChunks) {
69
+ assert.deepEqual(chunk.metadata.breadcrumbs, ['class LargeAuth', 'method validate(token: string)']);
70
+ }
71
+ });
72
+ //# sourceMappingURL=ast_breadcrumbs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast_breadcrumbs.test.js","sourceRoot":"","sources":["../../src/core/ast_breadcrumbs.test.ts"],"names":[],"mappings":"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"}