scythe-context-mcp 0.1.2 → 0.1.4
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/CHANGELOG.md +18 -0
- package/README.en.md +30 -24
- package/README.md +30 -24
- package/README.zh-CN.md +30 -24
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/indexing/binary.js +1 -2
- package/dist/indexing/embeddingWriter.js +4 -1
- package/dist/indexing/hybridSearch.js +9 -0
- package/dist/tools/registerTools.js +120 -25
- package/docs/codex-integration.md +17 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,24 @@ This project follows semantic versioning before npm publication where practical.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.4] - 2026-06-14
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add keyword-only fallback for hybrid search/context-pack calls when query embedding is unavailable, while preserving explicit `embedding_unavailable` diagnostics for semantic-only mode.
|
|
14
|
+
|
|
15
|
+
## [0.1.3] - 2026-06-14
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Clarify MCP server instructions so Codex prefers Scythe Context for unknown-location, semantic, and related-file lookup, while using `rg` or direct file reads for exact strings, known paths, and small targeted checks.
|
|
20
|
+
- Update Windows Codex App + WSL documentation to prefer a `wsl.exe` wrapper that starts WSL Node, avoiding Windows Node direct access to WSL repo-local SQLite indexes.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Avoid false binary detection when a UTF-8 scan prefix ends in the middle of a multibyte character.
|
|
25
|
+
- Overwrite stale sqlite-vec rows before inserting embeddings so incremental reindexing cannot fail when embedding ids are reused.
|
|
26
|
+
|
|
9
27
|
## [0.1.2] - 2026-06-13
|
|
10
28
|
|
|
11
29
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -52,7 +52,7 @@ Codex MCP configuration uses fields such as `command`, `args`, `cwd`, `env`, and
|
|
|
52
52
|
| --- | --- |
|
|
53
53
|
| Codex and MCP both run on Windows | Use Windows `node.exe` plus Windows npm `npx-cli.js`. |
|
|
54
54
|
| Codex CLI runs inside WSL/Linux/macOS | Use `npx` or `node dist/index.js` from the same environment. |
|
|
55
|
-
| Codex App on Windows opens a WSL repo |
|
|
55
|
+
| Codex App on Windows opens a WSL repo | Use Windows `wsl.exe` to start WSL Node, so the SQLite index stays on the WSL filesystem. Avoid Windows Node directly reading or writing `.scythe-context/` inside a WSL repo. |
|
|
56
56
|
|
|
57
57
|
### Native Windows
|
|
58
58
|
|
|
@@ -99,40 +99,42 @@ Here `args` points to the built Scythe Context MCP entrypoint; do not pin `cwd`
|
|
|
99
99
|
|
|
100
100
|
### Windows Codex App + WSL repo
|
|
101
101
|
|
|
102
|
-
Codex App on Windows may not reliably start WSL-side stdio MCP servers while using WSL agent mode.
|
|
102
|
+
Codex App on Windows may not reliably start WSL-side stdio MCP servers while using WSL agent mode. The most reliable tested workaround is to let Codex run Windows `wsl.exe`, then let `wsl.exe` start WSL Node and the WSL npm package.
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
Install inside WSL first:
|
|
105
105
|
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
command
|
|
109
|
-
|
|
110
|
-
cwd = "/mnt/c/Users/you"
|
|
111
|
-
env_vars = ["GEMINI_API_KEY", "PWD"]
|
|
112
|
-
|
|
113
|
-
[mcp_servers.scythe_context.env]
|
|
114
|
-
WSLENV = "PWD/p"
|
|
106
|
+
```bash
|
|
107
|
+
npm install -g scythe-context-mcp
|
|
108
|
+
command -v scythe-context-mcp
|
|
109
|
+
scythe-context-mcp --version
|
|
115
110
|
```
|
|
116
111
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- Keep `cwd` on a Windows-accessible directory such as `/mnt/c/Users/you`. Do not use the WSL repo's UNC directory as `cwd`, because npm/npx may go through CMD, and CMD does not support UNC current directories.
|
|
120
|
-
- This `cwd` is not the repo to index; it is only a safe startup directory for the Windows process. The real WSL repo is passed through `PWD/p`.
|
|
121
|
-
- `PWD/p` lets WSL convert the current workspace path into a UNC path readable by the Windows process, so you do not need to edit config for every repo.
|
|
122
|
-
- If `GEMINI_API_KEY` already exists in the Windows user environment or is forwarded by Codex `env_vars`, you do not need to put the key in `WSLENV`.
|
|
123
|
-
- Do not point Windows `node.exe` at `dist/index.js` inside a WSL checkout unless that checkout's dependencies were installed by Windows npm. `better-sqlite3` and `sqlite-vec` include native modules, and Windows Node cannot load native binaries installed by Linux npm.
|
|
124
|
-
|
|
125
|
-
Proxy URL, model, and auth mode can be written directly in Codex config; they do not need to go through `WSLENV`:
|
|
112
|
+
Then use this Codex config:
|
|
126
113
|
|
|
127
114
|
```toml
|
|
115
|
+
[mcp_servers.scythe_context]
|
|
116
|
+
command = "/mnt/c/Windows/System32/wsl.exe"
|
|
117
|
+
args = ["-d", "Ubuntu", "--", "bash", "-lc", "PATH=/home/you/.nvm/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin exec /home/you/.nvm/current/bin/scythe-context-mcp"]
|
|
118
|
+
startup_timeout_sec = 40
|
|
119
|
+
tool_timeout_sec = 120
|
|
120
|
+
env_vars = ["PWD", "GEMINI_API_KEY"]
|
|
121
|
+
|
|
128
122
|
[mcp_servers.scythe_context.env]
|
|
129
|
-
WSLENV = "PWD
|
|
123
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
130
124
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
131
125
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
132
126
|
GEMINI_AUTH_MODE = "bearer"
|
|
133
127
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
134
128
|
```
|
|
135
129
|
|
|
130
|
+
Notes:
|
|
131
|
+
|
|
132
|
+
- Replace `Ubuntu` with your WSL distribution name; check it with `wsl.exe -l -v`.
|
|
133
|
+
- Replace `/home/you/.nvm/current/bin` with your WSL Node/npm path; check it inside WSL with `which node` and `which scythe-context-mcp`.
|
|
134
|
+
- Do not pin `cwd` or `SCYTHE_CONTEXT_DEFAULT_PROJECT` in global config. This setup follows the current Codex workspace, so you do not need to edit config for every repo.
|
|
135
|
+
- `WSLENV` lists variable names to preserve across WSL/Windows interop; it does not contain the key itself. Prefer keeping `GEMINI_API_KEY` in the environment that starts Codex, then forward it with `env_vars`; write it directly under `[mcp_servers.scythe_context.env]` only for local throwaway testing.
|
|
136
|
+
- Avoid using Windows Node to index `.scythe-context/` directly inside a WSL repo. SQLite can report `database is locked` across the UNC / WSL filesystem boundary, and native modules can also accidentally mix Windows and WSL binaries.
|
|
137
|
+
|
|
136
138
|
### Optional hardening
|
|
137
139
|
|
|
138
140
|
These settings are not required for a minimal launch, but they help for large repos, first-time `npx` downloads, or a fixed tool surface:
|
|
@@ -186,17 +188,19 @@ Supported auth modes:
|
|
|
186
188
|
|
|
187
189
|
Official Gemini usually uses `x-goog-api-key`; many third-party proxies use `bearer`. If a proxy requires a query-string key, use `query` and set `GEMINI_API_KEY_QUERY_PARAM` if needed.
|
|
188
190
|
|
|
189
|
-
`WSLENV` is a WSL interop rule, not a Codex-specific field. You only need it when
|
|
191
|
+
`WSLENV` is a WSL interop rule, not a Codex-specific field. You only need it when Windows Codex App opens a WSL repo and the server is launched through a `wsl.exe` wrapper or another cross-environment command. With the `wsl.exe` wrapper above, use the no-suffix form:
|
|
190
192
|
|
|
191
193
|
```toml
|
|
192
194
|
[mcp_servers.scythe_context.env]
|
|
193
|
-
WSLENV = "PWD
|
|
195
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
194
196
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
195
197
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
196
198
|
GEMINI_AUTH_MODE = "bearer"
|
|
197
199
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
198
200
|
```
|
|
199
201
|
|
|
202
|
+
Use `PWD/p` only if you intentionally run a Windows Node process and need WSL to convert the workspace path to a Windows-readable UNC path. That mode is currently not recommended for directly reading or writing the repo-local SQLite index in WSL.
|
|
203
|
+
|
|
200
204
|
## Typical Workflow
|
|
201
205
|
|
|
202
206
|
1. Check index status first:
|
|
@@ -240,6 +244,8 @@ GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
|
240
244
|
| `repo_related_files` | Shows symbols, imports, and importedBy for one file. |
|
|
241
245
|
| `gemini_embedding_probe` | Tests Gemini or proxy compatibility and returns endpoint, latency, error classification, and remediation hints. |
|
|
242
246
|
|
|
247
|
+
`repo_context_pack(mode="hybrid")` and `repo_semantic_search(mode="hybrid")` degrade to keyword-only results when query embedding is unavailable, returning `effectiveMode: "keyword"` and `fallback.reason: "embedding_unavailable"`. `mode="semantic"` does not degrade and returns `status: "embedding_unavailable"` because pure semantic search requires query embedding. Use `rg` / direct file reads for exact strings, known paths, or small targeted checks.
|
|
248
|
+
|
|
243
249
|
## Feature Status
|
|
244
250
|
|
|
245
251
|
Implemented: repo scanning, chunking, SQLite metadata, SQLite FTS5, sqlite-vec, Gemini Embedding 2 provider, semantic/keyword/hybrid search, lightweight symbol/dependency graph, related-file lookup, `repo_context_pack`, provider diagnostics, and index freshness diagnostics.
|
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ Codex MCP 設定使用 `command`、`args`、`cwd`、`env` 與 `env_vars` 等欄
|
|
|
52
52
|
| --- | --- |
|
|
53
53
|
| Codex 和 MCP 都在 Windows | 用 Windows `node.exe` + Windows npm `npx-cli.js`。 |
|
|
54
54
|
| Codex CLI 在 WSL/Linux/macOS | 用同一個環境內的 `npx` 或 `node dist/index.js`。 |
|
|
55
|
-
| Codex App on Windows 開 WSL repo |
|
|
55
|
+
| Codex App on Windows 開 WSL repo | 建議用 Windows `wsl.exe` 啟動 WSL Node,讓 SQLite index 留在 WSL filesystem。避免 Windows Node 直接讀寫 WSL repo 內的 `.scythe-context/`。 |
|
|
56
56
|
|
|
57
57
|
### Native Windows
|
|
58
58
|
|
|
@@ -99,40 +99,42 @@ env_vars = ["GEMINI_API_KEY"]
|
|
|
99
99
|
|
|
100
100
|
### Windows Codex App + WSL repo
|
|
101
101
|
|
|
102
|
-
目前 Codex App on Windows 的 WSL agent mode
|
|
102
|
+
目前 Codex App on Windows 的 WSL agent mode 可能無法可靠直接啟動 WSL-side stdio MCP server。實測較穩的做法是讓 Codex 執行 Windows `wsl.exe`,再由 `wsl.exe` 在 WSL 內啟動 WSL Node 與 WSL npm package。
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
先在 WSL 內安裝:
|
|
105
105
|
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
command
|
|
109
|
-
|
|
110
|
-
cwd = "/mnt/c/Users/you"
|
|
111
|
-
env_vars = ["GEMINI_API_KEY", "PWD"]
|
|
112
|
-
|
|
113
|
-
[mcp_servers.scythe_context.env]
|
|
114
|
-
WSLENV = "PWD/p"
|
|
106
|
+
```bash
|
|
107
|
+
npm install -g scythe-context-mcp
|
|
108
|
+
command -v scythe-context-mcp
|
|
109
|
+
scythe-context-mcp --version
|
|
115
110
|
```
|
|
116
111
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- `cwd` 放 Windows 可用目錄,例如 `/mnt/c/Users/you`。不要把 `cwd` 設成 WSL repo 的 UNC 目錄,因為 npm/npx 可能經過 CMD,而 CMD 不支援 UNC current directory。
|
|
120
|
-
- 這個 `cwd` 不是要索引的 repo,只是 Windows process 的安全啟動位置;真正的 WSL repo 由 `PWD/p` 傳入。
|
|
121
|
-
- `PWD/p` 會讓 WSL 把目前 workspace 路徑轉成 Windows process 可讀的 UNC path;所以不需要每換一個 repo 就改設定。
|
|
122
|
-
- 如果 `GEMINI_API_KEY` 已存在 Windows 使用者環境或由 Codex `env_vars` 直接轉發,就不需要把 key 放進 `WSLENV`。
|
|
123
|
-
- 不要用 Windows `node.exe` 直接執行 WSL checkout 裡的 `dist/index.js`,除非該 checkout 的 dependencies 是用 Windows npm 安裝的。`better-sqlite3` 和 `sqlite-vec` 都包含 native module,Windows Node 不能載入 Linux npm 安裝出的 native binary。
|
|
124
|
-
|
|
125
|
-
中轉站 URL、model、auth mode 可以直接寫在 Codex config 裡,不需要透過 `WSLENV`:
|
|
112
|
+
然後在 Codex config 使用:
|
|
126
113
|
|
|
127
114
|
```toml
|
|
115
|
+
[mcp_servers.scythe_context]
|
|
116
|
+
command = "/mnt/c/Windows/System32/wsl.exe"
|
|
117
|
+
args = ["-d", "Ubuntu", "--", "bash", "-lc", "PATH=/home/you/.nvm/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin exec /home/you/.nvm/current/bin/scythe-context-mcp"]
|
|
118
|
+
startup_timeout_sec = 40
|
|
119
|
+
tool_timeout_sec = 120
|
|
120
|
+
env_vars = ["PWD", "GEMINI_API_KEY"]
|
|
121
|
+
|
|
128
122
|
[mcp_servers.scythe_context.env]
|
|
129
|
-
WSLENV = "PWD
|
|
123
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
130
124
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
131
125
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
132
126
|
GEMINI_AUTH_MODE = "bearer"
|
|
133
127
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
134
128
|
```
|
|
135
129
|
|
|
130
|
+
注意:
|
|
131
|
+
|
|
132
|
+
- `Ubuntu` 要換成你的 WSL distribution 名稱;可用 `wsl.exe -l -v` 查看。
|
|
133
|
+
- `/home/you/.nvm/current/bin` 要換成你的 WSL Node/npm 路徑;可在 WSL 內用 `which node`、`which scythe-context-mcp` 確認。
|
|
134
|
+
- 不要在全域 config 固定 `cwd` 或 `SCYTHE_CONTEXT_DEFAULT_PROJECT`。這個設定會跟著 Codex 目前 workspace 走,不需要每換 repo 就改一次。
|
|
135
|
+
- `WSLENV` 這裡列的是要跨 WSL/Windows interop 保留的變數名,不是 key 內容。建議把 `GEMINI_API_KEY` 放在 Codex 啟動環境或系統環境,並用 `env_vars` 轉發;本機臨時測試才考慮直接寫在 `[mcp_servers.scythe_context.env]`。
|
|
136
|
+
- 不建議用 Windows Node 直接索引 WSL repo 內的 `.scythe-context/`。SQLite 在 UNC / WSL filesystem 邊界可能出現 `database is locked`,而且 native modules 也容易混到 Windows/WSL 不同平台的 binary。
|
|
137
|
+
|
|
136
138
|
### 可選強化設定
|
|
137
139
|
|
|
138
140
|
以下設定不是最小啟動必需,但在大型 repo、首次 `npx` 下載或想固定工具面時有用:
|
|
@@ -186,17 +188,19 @@ GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
|
186
188
|
|
|
187
189
|
官方 Gemini 通常使用 `x-goog-api-key`;很多第三方中轉站使用 `bearer`。如果中轉站要求 query string key,可以使用 `query`,必要時再設定 `GEMINI_API_KEY_QUERY_PARAM`。
|
|
188
190
|
|
|
189
|
-
`WSLENV` 是 WSL interop 規則,不是 Codex 專用欄位。只有在 Windows Codex App + WSL repo
|
|
191
|
+
`WSLENV` 是 WSL interop 規則,不是 Codex 專用欄位。只有在 Windows Codex App + WSL repo 並透過 `wsl.exe` wrapper 或 Windows Node 跨環境啟動時才需要。若使用上面的 `wsl.exe` wrapper,通常使用無 suffix 形式:
|
|
190
192
|
|
|
191
193
|
```toml
|
|
192
194
|
[mcp_servers.scythe_context.env]
|
|
193
|
-
WSLENV = "PWD
|
|
195
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
194
196
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
195
197
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
196
198
|
GEMINI_AUTH_MODE = "bearer"
|
|
197
199
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
198
200
|
```
|
|
199
201
|
|
|
202
|
+
若你刻意採用 Windows Node 方案,才需要 `PWD/p` 把 WSL path 轉成 Windows 可讀 UNC path;但目前不建議用它直接讀寫 WSL repo 內的 SQLite index。
|
|
203
|
+
|
|
200
204
|
## 常用工作流
|
|
201
205
|
|
|
202
206
|
1. 先檢查索引狀態:
|
|
@@ -240,6 +244,8 @@ GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
|
240
244
|
| `repo_related_files` | 查看單一檔案的 symbols、imports、importedBy。 |
|
|
241
245
|
| `gemini_embedding_probe` | 測試 Gemini 或 proxy 相容性,回傳 endpoint、latency、錯誤分類與可修復建議。 |
|
|
242
246
|
|
|
247
|
+
`repo_context_pack(mode="hybrid")` 和 `repo_semantic_search(mode="hybrid")` 在 query embedding 不可用時會降級成 keyword-only 結果,並回傳 `effectiveMode: "keyword"` 與 `fallback.reason: "embedding_unavailable"`。`mode="semantic"` 不會降級,會回傳 `status: "embedding_unavailable"`,因為純 semantic search 必須有 query embedding。精確字串、已知路徑或小範圍檢查仍建議直接用 `rg` / 直接讀檔。
|
|
248
|
+
|
|
243
249
|
## 功能狀態
|
|
244
250
|
|
|
245
251
|
已完成:repo 掃描、chunking、SQLite metadata、SQLite FTS5、sqlite-vec、Gemini Embedding 2 provider、semantic/keyword/hybrid search、輕量 symbol/dependency graph、related-file lookup、`repo_context_pack`、provider diagnostics、index freshness diagnostics。
|
package/README.zh-CN.md
CHANGED
|
@@ -52,7 +52,7 @@ Codex MCP 配置使用 `command`、`args`、`cwd`、`env` 与 `env_vars` 等字
|
|
|
52
52
|
| --- | --- |
|
|
53
53
|
| Codex 和 MCP 都在 Windows | 用 Windows `node.exe` + Windows npm `npx-cli.js`。 |
|
|
54
54
|
| Codex CLI 在 WSL/Linux/macOS | 用同一个环境内的 `npx` 或 `node dist/index.js`。 |
|
|
55
|
-
| Codex App on Windows 打开 WSL repo |
|
|
55
|
+
| Codex App on Windows 打开 WSL repo | 建议用 Windows `wsl.exe` 启动 WSL Node,让 SQLite index 留在 WSL filesystem。避免 Windows Node 直接读写 WSL repo 内的 `.scythe-context/`。 |
|
|
56
56
|
|
|
57
57
|
### Native Windows
|
|
58
58
|
|
|
@@ -99,40 +99,42 @@ env_vars = ["GEMINI_API_KEY"]
|
|
|
99
99
|
|
|
100
100
|
### Windows Codex App + WSL repo
|
|
101
101
|
|
|
102
|
-
目前 Codex App on Windows 的 WSL agent mode
|
|
102
|
+
目前 Codex App on Windows 的 WSL agent mode 可能无法可靠直接启动 WSL-side stdio MCP server。实测较稳定的做法是让 Codex 执行 Windows `wsl.exe`,再由 `wsl.exe` 在 WSL 内启动 WSL Node 与 WSL npm package。
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
先在 WSL 内安装:
|
|
105
105
|
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
command
|
|
109
|
-
|
|
110
|
-
cwd = "/mnt/c/Users/you"
|
|
111
|
-
env_vars = ["GEMINI_API_KEY", "PWD"]
|
|
112
|
-
|
|
113
|
-
[mcp_servers.scythe_context.env]
|
|
114
|
-
WSLENV = "PWD/p"
|
|
106
|
+
```bash
|
|
107
|
+
npm install -g scythe-context-mcp
|
|
108
|
+
command -v scythe-context-mcp
|
|
109
|
+
scythe-context-mcp --version
|
|
115
110
|
```
|
|
116
111
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- `cwd` 放 Windows 可用目录,例如 `/mnt/c/Users/you`。不要把 `cwd` 设成 WSL repo 的 UNC 目录,因为 npm/npx 可能经过 CMD,而 CMD 不支持 UNC current directory。
|
|
120
|
-
- 这个 `cwd` 不是要索引的 repo,只是 Windows process 的安全启动位置;真正的 WSL repo 由 `PWD/p` 传入。
|
|
121
|
-
- `PWD/p` 会让 WSL 把当前 workspace 路径转成 Windows process 可读的 UNC path;所以不需要每换一个 repo 就改配置。
|
|
122
|
-
- 如果 `GEMINI_API_KEY` 已存在 Windows 用户环境或由 Codex `env_vars` 直接转发,就不需要把 key 放进 `WSLENV`。
|
|
123
|
-
- 不要用 Windows `node.exe` 直接执行 WSL checkout 里的 `dist/index.js`,除非该 checkout 的 dependencies 是用 Windows npm 安装的。`better-sqlite3` 和 `sqlite-vec` 都包含 native module,Windows Node 不能加载 Linux npm 安装出的 native binary。
|
|
124
|
-
|
|
125
|
-
中转站 URL、model、auth mode 可以直接写在 Codex config 里,不需要通过 `WSLENV`:
|
|
112
|
+
然后在 Codex config 使用:
|
|
126
113
|
|
|
127
114
|
```toml
|
|
115
|
+
[mcp_servers.scythe_context]
|
|
116
|
+
command = "/mnt/c/Windows/System32/wsl.exe"
|
|
117
|
+
args = ["-d", "Ubuntu", "--", "bash", "-lc", "PATH=/home/you/.nvm/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin exec /home/you/.nvm/current/bin/scythe-context-mcp"]
|
|
118
|
+
startup_timeout_sec = 40
|
|
119
|
+
tool_timeout_sec = 120
|
|
120
|
+
env_vars = ["PWD", "GEMINI_API_KEY"]
|
|
121
|
+
|
|
128
122
|
[mcp_servers.scythe_context.env]
|
|
129
|
-
WSLENV = "PWD
|
|
123
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
130
124
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
131
125
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
132
126
|
GEMINI_AUTH_MODE = "bearer"
|
|
133
127
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
134
128
|
```
|
|
135
129
|
|
|
130
|
+
注意:
|
|
131
|
+
|
|
132
|
+
- `Ubuntu` 要换成你的 WSL distribution 名称;可用 `wsl.exe -l -v` 查看。
|
|
133
|
+
- `/home/you/.nvm/current/bin` 要换成你的 WSL Node/npm 路径;可在 WSL 内用 `which node`、`which scythe-context-mcp` 确认。
|
|
134
|
+
- 不要在全局 config 固定 `cwd` 或 `SCYTHE_CONTEXT_DEFAULT_PROJECT`。这个设置会跟着 Codex 当前 workspace 走,不需要每换 repo 就改一次。
|
|
135
|
+
- `WSLENV` 这里列的是要跨 WSL/Windows interop 保留的变量名,不是 key 内容。建议把 `GEMINI_API_KEY` 放在 Codex 启动环境或系统环境,并用 `env_vars` 转发;只有本机临时测试才考虑直接写在 `[mcp_servers.scythe_context.env]`。
|
|
136
|
+
- 不建议用 Windows Node 直接索引 WSL repo 内的 `.scythe-context/`。SQLite 在 UNC / WSL filesystem 边界可能出现 `database is locked`,而且 native modules 也容易混到 Windows/WSL 不同平台的 binary。
|
|
137
|
+
|
|
136
138
|
### 可选强化配置
|
|
137
139
|
|
|
138
140
|
以下配置不是最小启动必需,但在大型 repo、首次 `npx` 下载或想固定工具面时有用:
|
|
@@ -186,17 +188,19 @@ GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
|
186
188
|
|
|
187
189
|
官方 Gemini 通常使用 `x-goog-api-key`;很多第三方中转站使用 `bearer`。如果中转站要求 query string key,可以使用 `query`,必要时再设置 `GEMINI_API_KEY_QUERY_PARAM`。
|
|
188
190
|
|
|
189
|
-
`WSLENV` 是 WSL interop 规则,不是 Codex 专用字段。只有在 Windows Codex App + WSL repo
|
|
191
|
+
`WSLENV` 是 WSL interop 规则,不是 Codex 专用字段。只有在 Windows Codex App + WSL repo 并通过 `wsl.exe` wrapper 或 Windows Node 跨环境启动时才需要。若使用上面的 `wsl.exe` wrapper,通常使用无 suffix 形式:
|
|
190
192
|
|
|
191
193
|
```toml
|
|
192
194
|
[mcp_servers.scythe_context.env]
|
|
193
|
-
WSLENV = "PWD
|
|
195
|
+
WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"
|
|
194
196
|
GEMINI_BASE_URL = "https://your-proxy.example.com/v1beta"
|
|
195
197
|
GEMINI_MODEL = "gemini-embedding-2"
|
|
196
198
|
GEMINI_AUTH_MODE = "bearer"
|
|
197
199
|
GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
198
200
|
```
|
|
199
201
|
|
|
202
|
+
若你刻意采用 Windows Node 方案,才需要 `PWD/p` 把 WSL path 转成 Windows 可读 UNC path;但目前不建议用它直接读写 WSL repo 内的 SQLite index。
|
|
203
|
+
|
|
200
204
|
## 常用工作流
|
|
201
205
|
|
|
202
206
|
1. 先检查索引状态:
|
|
@@ -240,6 +244,8 @@ GEMINI_OUTPUT_DIMENSIONALITY = "1536"
|
|
|
240
244
|
| `repo_related_files` | 查看单一文件的 symbols、imports、importedBy。 |
|
|
241
245
|
| `gemini_embedding_probe` | 测试 Gemini 或 proxy 兼容性,返回 endpoint、latency、错误分类与可修复建议。 |
|
|
242
246
|
|
|
247
|
+
`repo_context_pack(mode="hybrid")` 和 `repo_semantic_search(mode="hybrid")` 在 query embedding 不可用时会降级成 keyword-only 结果,并返回 `effectiveMode: "keyword"` 与 `fallback.reason: "embedding_unavailable"`。`mode="semantic"` 不会降级,会返回 `status: "embedding_unavailable"`,因为纯 semantic search 必须有 query embedding。精确字符串、已知路径或小范围检查仍建议直接用 `rg` / 直接读文件。
|
|
248
|
+
|
|
243
249
|
## 功能状态
|
|
244
250
|
|
|
245
251
|
已完成:repo 扫描、chunking、SQLite metadata、SQLite FTS5、sqlite-vec、Gemini Embedding 2 provider、semantic/keyword/hybrid search、轻量 symbol/dependency graph、related-file lookup、`repo_context_pack`、provider diagnostics、index freshness diagnostics。
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ const server = new McpServer({
|
|
|
24
24
|
name: "scythe-context-mcp",
|
|
25
25
|
version: PACKAGE_VERSION,
|
|
26
26
|
}, {
|
|
27
|
-
instructions: "Scythe Context is a
|
|
27
|
+
instructions: "Scythe Context is a code-context MCP server for Codex. Use it for unknown file locations, semantic/code-intent search, or related files/imports/snippets. Use rg/direct reads for exact strings, known paths, or small checks. Start with repo_index_status; repo_reindex(dry_run=false) only if metadata is missing/stale. Prefer repo_context_pack for task lookup. Set index_embeddings=true only when semantic vectors are needed; chunk text goes to the configured endpoint. Use repo_related_files for focused graphs.",
|
|
28
28
|
});
|
|
29
29
|
registerTools(server, config);
|
|
30
30
|
const transport = new StdioServerTransport();
|
package/dist/indexing/binary.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { TextDecoder } from "node:util";
|
|
2
|
-
const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
3
2
|
export function isProbablyBinary(buffer) {
|
|
4
3
|
if (buffer.length === 0)
|
|
5
4
|
return false;
|
|
6
5
|
if (buffer.includes(0))
|
|
7
6
|
return true;
|
|
8
7
|
try {
|
|
9
|
-
|
|
8
|
+
new TextDecoder("utf-8", { fatal: true }).decode(buffer, { stream: true });
|
|
10
9
|
return false;
|
|
11
10
|
}
|
|
12
11
|
catch {
|
|
@@ -62,9 +62,12 @@ export async function indexMissingEmbeddings(options) {
|
|
|
62
62
|
${limitSql}
|
|
63
63
|
`)
|
|
64
64
|
.all({ embeddingSetId, maxChunks: options.maxChunks });
|
|
65
|
-
const
|
|
65
|
+
const vectorTable = vectorTableName(options.dimensions);
|
|
66
|
+
const deleteVector = db.prepare(`delete from ${vectorTable} where rowid = ?`);
|
|
67
|
+
const insertVector = db.prepare(`insert into ${vectorTable}(rowid, embedding) values (?, ?)`);
|
|
66
68
|
const writeEmbedding = db.transaction((chunkId, vector) => {
|
|
67
69
|
const embeddingId = getOrCreateEmbeddingRecord(db, { chunkId, embeddingSetId });
|
|
70
|
+
deleteVector.run(BigInt(embeddingId));
|
|
68
71
|
insertVector.run(BigInt(embeddingId), vectorToFloat32Buffer(vector, options.dimensions));
|
|
69
72
|
});
|
|
70
73
|
for (const batch of chunkArray(pendingChunks, options.batchSize)) {
|
|
@@ -65,3 +65,12 @@ export function searchHybrid(options) {
|
|
|
65
65
|
});
|
|
66
66
|
return mergeHybridResults(semanticResults, keywordResults, options.maxResults);
|
|
67
67
|
}
|
|
68
|
+
export function searchKeywordOnly(options) {
|
|
69
|
+
const keywordResults = searchByKeyword({
|
|
70
|
+
dbPath: options.dbPath,
|
|
71
|
+
query: options.query,
|
|
72
|
+
maxResults: Math.max(options.maxResults * 2, options.maxResults),
|
|
73
|
+
maxSnippetChars: options.maxSnippetChars,
|
|
74
|
+
});
|
|
75
|
+
return mergeHybridResults([], keywordResults, options.maxResults);
|
|
76
|
+
}
|
|
@@ -4,7 +4,7 @@ import { z } from "zod";
|
|
|
4
4
|
import { buildContextPack } from "../indexing/contextPack.js";
|
|
5
5
|
import { reindexDryRun } from "../indexing/dryRun.js";
|
|
6
6
|
import { indexMissingEmbeddings } from "../indexing/embeddingWriter.js";
|
|
7
|
-
import { searchHybrid } from "../indexing/hybridSearch.js";
|
|
7
|
+
import { searchHybrid, searchKeywordOnly } from "../indexing/hybridSearch.js";
|
|
8
8
|
import { readDetailedIndexStatus, readIndexFreshness, recommendedNextActions } from "../indexing/indexStatus.js";
|
|
9
9
|
import { persistentReindexMetadata } from "../indexing/indexWriter.js";
|
|
10
10
|
import { readRelatedFileGraph, readRelatedFiles } from "../indexing/relatedFiles.js";
|
|
@@ -35,6 +35,37 @@ function searchIndexedChunks(options) {
|
|
|
35
35
|
maxSnippetChars: options.maxSnippetChars,
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
+
function searchKeywordOnlyChunks(options) {
|
|
39
|
+
return searchKeywordOnly({
|
|
40
|
+
dbPath: options.dbPath,
|
|
41
|
+
query: options.query,
|
|
42
|
+
maxResults: options.maxResults,
|
|
43
|
+
maxSnippetChars: options.maxSnippetChars,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function embeddingFailureDetails(error) {
|
|
47
|
+
const geminiError = error instanceof GeminiEmbeddingError ? error : undefined;
|
|
48
|
+
return {
|
|
49
|
+
type: error instanceof Error ? error.name : "UnknownError",
|
|
50
|
+
message: error instanceof Error ? error.message : String(error),
|
|
51
|
+
httpStatus: geminiError?.status,
|
|
52
|
+
retryable: geminiError?.retryable ?? false,
|
|
53
|
+
bodySnippet: geminiError?.bodySnippet,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function embeddingUnavailablePayload(error) {
|
|
57
|
+
return {
|
|
58
|
+
status: "embedding_unavailable",
|
|
59
|
+
fallbackAvailable: "Use mode=hybrid to allow keyword-only fallback, or use rg/direct file reads for exact strings and known paths.",
|
|
60
|
+
error: embeddingFailureDetails(error),
|
|
61
|
+
recommendedNextActions: [
|
|
62
|
+
"Run gemini_embedding_probe with a short test string.",
|
|
63
|
+
"Verify GEMINI_API_KEY, GEMINI_BASE_URL, GEMINI_AUTH_MODE, and GEMINI_OUTPUT_DIMENSIONALITY.",
|
|
64
|
+
"Use repo_context_pack with mode=hybrid for keyword-only degraded results while embeddings are unavailable.",
|
|
65
|
+
"Use rg/direct file reads for exact strings, known paths, or small targeted checks.",
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
38
69
|
function buildGeminiDiagnostics(config, expectedDimensions) {
|
|
39
70
|
const diagnostics = {
|
|
40
71
|
baseUrl: config.baseUrl,
|
|
@@ -223,20 +254,50 @@ export function registerTools(server, config) {
|
|
|
223
254
|
message: "Run repo_reindex with dry_run=false and index_embeddings=true before semantic search.",
|
|
224
255
|
});
|
|
225
256
|
}
|
|
226
|
-
const queryEmbedding = await embeddingProvider.embed({ kind: "query", text: query });
|
|
227
257
|
const dimensions = expectedDimensions;
|
|
228
|
-
|
|
229
|
-
|
|
258
|
+
let effectiveMode = mode;
|
|
259
|
+
let fallback;
|
|
260
|
+
let rawResults;
|
|
261
|
+
try {
|
|
262
|
+
const queryEmbedding = await embeddingProvider.embed({ kind: "query", text: query });
|
|
263
|
+
if (queryEmbedding.dimensions !== dimensions) {
|
|
264
|
+
throw new Error(`Query embedding dimensions mismatch: expected ${dimensions}, got ${queryEmbedding.dimensions}`);
|
|
265
|
+
}
|
|
266
|
+
rawResults = searchIndexedChunks({
|
|
267
|
+
dbPath,
|
|
268
|
+
query,
|
|
269
|
+
dimensions,
|
|
270
|
+
queryVector: queryEmbedding.vector,
|
|
271
|
+
maxResults: max_results,
|
|
272
|
+
maxSnippetChars: max_snippet_chars,
|
|
273
|
+
mode,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
if (mode === "semantic") {
|
|
278
|
+
return asJsonText({
|
|
279
|
+
query,
|
|
280
|
+
projectPath,
|
|
281
|
+
dbPath,
|
|
282
|
+
dimensions,
|
|
283
|
+
mode,
|
|
284
|
+
...embeddingUnavailablePayload(error),
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
effectiveMode = "keyword";
|
|
288
|
+
fallback = {
|
|
289
|
+
reason: "embedding_unavailable",
|
|
290
|
+
fromMode: mode,
|
|
291
|
+
toMode: "keyword",
|
|
292
|
+
error: embeddingFailureDetails(error),
|
|
293
|
+
};
|
|
294
|
+
rawResults = searchKeywordOnlyChunks({
|
|
295
|
+
dbPath,
|
|
296
|
+
query,
|
|
297
|
+
maxResults: max_results,
|
|
298
|
+
maxSnippetChars: max_snippet_chars,
|
|
299
|
+
});
|
|
230
300
|
}
|
|
231
|
-
const rawResults = searchIndexedChunks({
|
|
232
|
-
dbPath,
|
|
233
|
-
query,
|
|
234
|
-
dimensions,
|
|
235
|
-
queryVector: queryEmbedding.vector,
|
|
236
|
-
maxResults: max_results,
|
|
237
|
-
maxSnippetChars: max_snippet_chars,
|
|
238
|
-
mode,
|
|
239
|
-
});
|
|
240
301
|
const formatted = formatSearchResults(query, rawResults, { maxContextChars: max_context_chars });
|
|
241
302
|
return asJsonText({
|
|
242
303
|
query,
|
|
@@ -244,6 +305,8 @@ export function registerTools(server, config) {
|
|
|
244
305
|
dbPath,
|
|
245
306
|
dimensions,
|
|
246
307
|
mode,
|
|
308
|
+
effectiveMode,
|
|
309
|
+
fallback,
|
|
247
310
|
results: formatted.results,
|
|
248
311
|
context: formatted.summary,
|
|
249
312
|
resultCount: rawResults.length,
|
|
@@ -308,20 +371,50 @@ export function registerTools(server, config) {
|
|
|
308
371
|
message: "Run repo_reindex with dry_run=false and index_embeddings=true before building a context pack.",
|
|
309
372
|
});
|
|
310
373
|
}
|
|
311
|
-
const queryEmbedding = await embeddingProvider.embed({ kind: "query", text: query });
|
|
312
374
|
const dimensions = expectedDimensions;
|
|
313
|
-
|
|
314
|
-
|
|
375
|
+
let effectiveMode = mode;
|
|
376
|
+
let fallback;
|
|
377
|
+
let rawResults;
|
|
378
|
+
try {
|
|
379
|
+
const queryEmbedding = await embeddingProvider.embed({ kind: "query", text: query });
|
|
380
|
+
if (queryEmbedding.dimensions !== dimensions) {
|
|
381
|
+
throw new Error(`Query embedding dimensions mismatch: expected ${dimensions}, got ${queryEmbedding.dimensions}`);
|
|
382
|
+
}
|
|
383
|
+
rawResults = searchIndexedChunks({
|
|
384
|
+
dbPath,
|
|
385
|
+
query,
|
|
386
|
+
dimensions,
|
|
387
|
+
queryVector: queryEmbedding.vector,
|
|
388
|
+
maxResults: max_results,
|
|
389
|
+
maxSnippetChars: max_snippet_chars,
|
|
390
|
+
mode,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
if (mode === "semantic") {
|
|
395
|
+
return asJsonText({
|
|
396
|
+
query,
|
|
397
|
+
projectPath,
|
|
398
|
+
dbPath,
|
|
399
|
+
dimensions,
|
|
400
|
+
mode,
|
|
401
|
+
...embeddingUnavailablePayload(error),
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
effectiveMode = "keyword";
|
|
405
|
+
fallback = {
|
|
406
|
+
reason: "embedding_unavailable",
|
|
407
|
+
fromMode: mode,
|
|
408
|
+
toMode: "keyword",
|
|
409
|
+
error: embeddingFailureDetails(error),
|
|
410
|
+
};
|
|
411
|
+
rawResults = searchKeywordOnlyChunks({
|
|
412
|
+
dbPath,
|
|
413
|
+
query,
|
|
414
|
+
maxResults: max_results,
|
|
415
|
+
maxSnippetChars: max_snippet_chars,
|
|
416
|
+
});
|
|
315
417
|
}
|
|
316
|
-
const rawResults = searchIndexedChunks({
|
|
317
|
-
dbPath,
|
|
318
|
-
query,
|
|
319
|
-
dimensions,
|
|
320
|
-
queryVector: queryEmbedding.vector,
|
|
321
|
-
maxResults: max_results,
|
|
322
|
-
maxSnippetChars: max_snippet_chars,
|
|
323
|
-
mode,
|
|
324
|
-
});
|
|
325
418
|
const relatedPaths = Array.from(new Set(rawResults.map((result) => result.path))).slice(0, Math.min(max_seed_files, max_related_files));
|
|
326
419
|
const relatedFiles = readRelatedFileGraph({
|
|
327
420
|
dbPath,
|
|
@@ -355,6 +448,8 @@ export function registerTools(server, config) {
|
|
|
355
448
|
dbPath,
|
|
356
449
|
dimensions,
|
|
357
450
|
mode,
|
|
451
|
+
effectiveMode,
|
|
452
|
+
fallback,
|
|
358
453
|
relatedDepth: related_depth,
|
|
359
454
|
relatedSeedCount: relatedPaths.length,
|
|
360
455
|
includeRelatedSnippets: include_related_snippets,
|
|
@@ -42,22 +42,23 @@ Codex's official MCP configuration model is platform-neutral: a stdio server has
|
|
|
42
42
|
|
|
43
43
|
- Native Windows: use Windows `node.exe` and npm's `npx-cli.js`, or the short binary command only when Codex can reliably see the npm global binary on PATH.
|
|
44
44
|
- WSL/Linux/macOS: use `npx -y scythe-context-mcp` or `node dist/index.js` from a build produced in that same environment.
|
|
45
|
-
- Windows Codex App with WSL workspaces:
|
|
45
|
+
- Windows Codex App with WSL workspaces: prefer Windows `wsl.exe` as a wrapper that starts WSL Node and WSL npm package dependencies. This keeps the repo-local SQLite index on the WSL filesystem. Use `SCYTHE_CONTEXT_DEFAULT_PROJECT` only when intentionally pinning one fixed default project.
|
|
46
46
|
|
|
47
47
|
Do not mix a Node runtime from one OS with `node_modules` installed by another OS. This matters because Scythe Context depends on native SQLite modules.
|
|
48
48
|
|
|
49
49
|
### Windows App with WSL workspaces
|
|
50
50
|
|
|
51
|
-
When Codex App runs a WSL project
|
|
51
|
+
When Codex App runs a WSL project, prefer launching Scythe Context through Windows `wsl.exe` and a WSL-installed `scythe-context-mcp` binary:
|
|
52
52
|
|
|
53
|
-
- Current Codex App on Windows may not reliably start WSL-side stdio MCP servers while using WSL agent mode. If MCP tools are missing, handshakes time out, or config paths cross Windows/WSL boundaries, use
|
|
54
|
-
-
|
|
55
|
-
- Keep
|
|
56
|
-
-
|
|
57
|
-
-
|
|
53
|
+
- Current Codex App on Windows may not reliably start WSL-side stdio MCP servers directly while using WSL agent mode. If MCP tools are missing, handshakes time out, or config paths cross Windows/WSL boundaries, use `wsl.exe` as a wrapper.
|
|
54
|
+
- Install the package inside WSL, then point the wrapper command at the WSL global binary, for example `/home/you/.nvm/current/bin/scythe-context-mcp`.
|
|
55
|
+
- Keep the WSL Node path at the front of `PATH` inside the wrapper command. This avoids accidentally resolving a Windows npm global shim from the inherited Windows PATH.
|
|
56
|
+
- Do not pin `cwd` in global config. Let Codex's current workspace and `PWD` decide the target repo.
|
|
57
|
+
- Use `WSLENV = "PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY"` when config env variables must survive the WSL -> Windows `wsl.exe` -> WSL round trip.
|
|
58
|
+
- Do not use Windows Node to directly read or write `.scythe-context/index.sqlite` inside a WSL repo. In live testing this can fail with `database is locked` across the UNC / WSL filesystem boundary.
|
|
58
59
|
- Do not point Windows `node.exe` at a WSL checkout's `dist/index.js` unless dependencies were installed by Windows npm in that checkout.
|
|
59
60
|
|
|
60
|
-
The reason is native dependency compatibility. `better-sqlite3` and `sqlite-vec` load platform-specific binaries
|
|
61
|
+
The reason is both filesystem and native dependency compatibility. `better-sqlite3` and `sqlite-vec` load platform-specific binaries, and SQLite locking is more predictable when the Node process and index database live in the same OS filesystem.
|
|
61
62
|
|
|
62
63
|
### AGENTS.md
|
|
63
64
|
|
|
@@ -90,7 +91,7 @@ Recommended config should expose all tools by default during development, but `e
|
|
|
90
91
|
- Valid Codex TOML examples using `[mcp_servers.scythe_context.env]`.
|
|
91
92
|
- Secret-safe config examples using `env_vars` for `GEMINI_API_KEY`.
|
|
92
93
|
- `cwd` in MCP config so relative `.env` loading is predictable.
|
|
93
|
-
- Windows App + WSL setup guidance using Windows `
|
|
94
|
+
- Windows App + WSL setup guidance using Windows `wsl.exe`, WSL Node, npm package dependencies installed in WSL, `PWD`, and `WSLENV`.
|
|
94
95
|
- `startup_timeout_sec` and `tool_timeout_sec` tuned above defaults.
|
|
95
96
|
- Bounded context output for primary and related snippets.
|
|
96
97
|
- Explicit opt-in embedding and opt-in related snippet packing.
|
|
@@ -114,12 +115,13 @@ Recommended config should expose all tools by default during development, but `e
|
|
|
114
115
|
|
|
115
116
|
### Windows App starts but WSL repo indexing fails
|
|
116
117
|
|
|
117
|
-
1. Prefer the
|
|
118
|
-
2.
|
|
119
|
-
3.
|
|
120
|
-
4.
|
|
121
|
-
5.
|
|
122
|
-
6.
|
|
118
|
+
1. Prefer the `wsl.exe` wrapper that starts WSL Node and a WSL-installed `scythe-context-mcp` binary.
|
|
119
|
+
2. Confirm WSL has its own install: `npm install -g scythe-context-mcp`, then `command -v scythe-context-mcp`.
|
|
120
|
+
3. Keep WSL Node's bin directory before Windows paths in the wrapper command's `PATH`.
|
|
121
|
+
4. Do not set global `cwd` or `SCYTHE_CONTEXT_DEFAULT_PROJECT` unless you intentionally want one fixed repo.
|
|
122
|
+
5. Use `WSLENV` without suffixes for the wrapper mode, for example `PWD:GEMINI_API_KEY:GEMINI_BASE_URL:GEMINI_MODEL:GEMINI_AUTH_MODE:GEMINI_OUTPUT_DIMENSIONALITY`.
|
|
123
|
+
6. If you see `invalid ELF header`, the process probably loaded a Windows npm package or shim from WSL; fix `PATH` or reinstall inside WSL.
|
|
124
|
+
7. If you see `database is locked` while using Windows Node against a WSL repo, switch to the `wsl.exe` wrapper so SQLite is opened by WSL Node on the WSL filesystem.
|
|
123
125
|
|
|
124
126
|
### Tool starts but embedding fails
|
|
125
127
|
|