cortex-local 2.4.3__tar.gz → 2.4.4__tar.gz

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 (24) hide show
  1. {cortex_local-2.4.3 → cortex_local-2.4.4}/PKG-INFO +12 -3
  2. {cortex_local-2.4.3 → cortex_local-2.4.4}/README.md +10 -1
  3. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/cli.py +68 -5
  4. {cortex_local-2.4.3 → cortex_local-2.4.4}/.gitignore +0 -0
  5. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/__init__.py +0 -0
  6. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/config.py +0 -0
  7. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/__init__.py +0 -0
  8. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/cache.py +0 -0
  9. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/chunker.py +0 -0
  10. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/code_graph.py +0 -0
  11. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/formatters.py +0 -0
  12. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/global_graph.py +0 -0
  13. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/graph.py +0 -0
  14. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/notes_graph.py +0 -0
  15. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/roslyn_analyzer.py +0 -0
  16. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/roslyn_tool/CortexAnalyzer.csproj +0 -0
  17. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/core/roslyn_tool/Program.cs +0 -0
  18. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/embedder.py +0 -0
  19. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/indexer.py +0 -0
  20. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/mcp_server.py +0 -0
  21. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/state.py +0 -0
  22. {cortex_local-2.4.3 → cortex_local-2.4.4}/cortex/watcher.py +0 -0
  23. {cortex_local-2.4.3 → cortex_local-2.4.4}/pyproject.toml +0 -0
  24. {cortex_local-2.4.3 → cortex_local-2.4.4}/tests/test_imports.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: cortex-local
3
- Version: 2.4.3
3
+ Version: 2.4.4
4
4
  Summary: Local semantic search MCP server — notes + code, embedded Qdrant, fastembed
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: click>=8.0.0
@@ -23,7 +23,14 @@ pipx install cortex-local
23
23
  cortex install
24
24
  ```
25
25
 
26
- `cortex install` downloads embedding models and registers the MCP server in Claude Code. Restart Claude Code after.
26
+ `cortex install` downloads embedding models and registers the MCP server in Claude Code with `--scope user` (available in all projects). Restart Claude Code after.
27
+
28
+ ## Update
29
+
30
+ ```bash
31
+ pipx upgrade cortex-local
32
+ cortex install # re-registers MCP (idempotent)
33
+ ```
27
34
 
28
35
  ### Legacy CPUs (no SSE4.2 / X86_V2)
29
36
 
@@ -41,6 +48,8 @@ cortex install
41
48
  ```bash
42
49
  cortex index ~/notes # index Obsidian vault
43
50
  cortex index ~/projects/myapp # index a code repo
51
+ cortex doctor # check version, MCP registration, workspace, index status
52
+ cortex uninstall # remove MCP registration
44
53
  ```
45
54
 
46
55
  Then in Claude Code, `search_notes` and `search_code` are available as MCP tools.
@@ -9,7 +9,14 @@ pipx install cortex-local
9
9
  cortex install
10
10
  ```
11
11
 
12
- `cortex install` downloads embedding models and registers the MCP server in Claude Code. Restart Claude Code after.
12
+ `cortex install` downloads embedding models and registers the MCP server in Claude Code with `--scope user` (available in all projects). Restart Claude Code after.
13
+
14
+ ## Update
15
+
16
+ ```bash
17
+ pipx upgrade cortex-local
18
+ cortex install # re-registers MCP (idempotent)
19
+ ```
13
20
 
14
21
  ### Legacy CPUs (no SSE4.2 / X86_V2)
15
22
 
@@ -27,6 +34,8 @@ cortex install
27
34
  ```bash
28
35
  cortex index ~/notes # index Obsidian vault
29
36
  cortex index ~/projects/myapp # index a code repo
37
+ cortex doctor # check version, MCP registration, workspace, index status
38
+ cortex uninstall # remove MCP registration
30
39
  ```
31
40
 
32
41
  Then in Claude Code, `search_notes` and `search_code` are available as MCP tools.
@@ -11,11 +11,12 @@ import click
11
11
 
12
12
  from .config import (
13
13
  WORKSPACES_DIR, get_active_workspace, set_active_workspace, get_workspace_dir,
14
- data_dir, save_last_indexed_path,
14
+ data_dir, save_last_indexed_path, qdrant_path, get_config, VERSION,
15
15
  )
16
16
 
17
17
 
18
18
  @click.group()
19
+ @click.version_option(VERSION, prog_name="cortex")
19
20
  def cli() -> None:
20
21
  """cortex: local semantic search MCP server."""
21
22
 
@@ -160,25 +161,87 @@ def search_log_cmd(top: int) -> None:
160
161
  click.echo(f" {q}")
161
162
 
162
163
 
164
+ _SYSTEM_DIRS = {"/", "/usr", "/bin", "/etc", "/sbin", "/var", r"C:\Windows"}
165
+ _SCOPE_CHOICES = click.Choice(["user", "local", "project"])
166
+
167
+
163
168
  @cli.command("install")
164
- def install_cmd() -> None:
169
+ @click.option("--scope", default="user", type=_SCOPE_CHOICES, show_default=True,
170
+ help="MCP registration scope.")
171
+ def install_cmd(scope: str) -> None:
165
172
  """Download embedding models and register cortex MCP in Claude Code."""
166
173
  from .embedder import pull_models as _pull
174
+ cwd = str(Path.cwd())
175
+ if scope != "user" and cwd in _SYSTEM_DIRS:
176
+ click.echo(f"Warning: cwd looks like a system directory ({cwd}). Use --scope user to register globally.")
167
177
  click.echo("Downloading embedding models...")
168
178
  _pull()
169
- mcp_cmd = "claude mcp add cortex --transport stdio cortex serve"
179
+ mcp_cmd = f"claude mcp add --scope {scope} cortex --transport stdio cortex serve"
170
180
  claude = shutil.which("claude")
171
181
  if not claude:
172
182
  click.echo("Models ready. Register MCP manually (claude not found in PATH):")
173
183
  click.echo(f" {mcp_cmd}")
174
184
  return
175
185
  click.echo("Registering MCP server in Claude Code...")
186
+ subprocess.run(
187
+ [claude, "mcp", "remove", "cortex", "--scope", scope],
188
+ capture_output=True, text=True,
189
+ )
176
190
  result = subprocess.run(
177
- [claude, "mcp", "add", "cortex", "--transport", "stdio", "cortex", "serve"],
191
+ [claude, "mcp", "add", "--scope", scope, "cortex", "--transport", "stdio", "cortex", "serve"],
178
192
  capture_output=True, text=True,
179
193
  )
180
194
  if result.returncode == 0:
181
- click.echo("Done. cortex is ready — restart Claude Code to activate.")
195
+ click.echo(f"Done. cortex is ready (scope: {scope}) — restart Claude Code to activate.")
182
196
  else:
183
197
  click.echo(f"MCP registration failed. Run manually:\n {mcp_cmd}")
184
198
  click.echo(result.stderr.strip())
199
+
200
+
201
+ @cli.command("uninstall")
202
+ @click.option("--scope", default="user", type=_SCOPE_CHOICES, show_default=True,
203
+ help="MCP registration scope to remove from.")
204
+ def uninstall_cmd(scope: str) -> None:
205
+ """Remove cortex MCP registration from Claude Code."""
206
+ claude = shutil.which("claude")
207
+ if not claude:
208
+ click.echo(f"claude not found in PATH. Remove manually:\n claude mcp remove cortex --scope {scope}")
209
+ return
210
+ result = subprocess.run(
211
+ [claude, "mcp", "remove", "cortex", "--scope", scope],
212
+ capture_output=True, text=True,
213
+ )
214
+ if result.returncode == 0:
215
+ click.echo(f"cortex MCP removed (scope: {scope}).")
216
+ else:
217
+ click.echo(f"Removal failed (scope: {scope}).")
218
+ click.echo(result.stderr.strip())
219
+
220
+
221
+ @cli.command("doctor")
222
+ def doctor_cmd() -> None:
223
+ """Show cortex status: version, model cache, MCP registration, workspace, index."""
224
+ click.echo(f"version {VERSION}")
225
+
226
+ cache_dir = Path.home() / ".cache" / "fastembed"
227
+ cache_ok = cache_dir.exists() and any(cache_dir.iterdir())
228
+ click.echo(f"model cache {'ok' if cache_ok else 'missing — run: cortex pull-models'}")
229
+
230
+ claude = shutil.which("claude")
231
+ mcp_status = "claude not found in PATH"
232
+ if claude:
233
+ r = subprocess.run([claude, "mcp", "list"], capture_output=True, text=True)
234
+ output = r.stdout + r.stderr
235
+ if "cortex" in output.lower():
236
+ lines = [l for l in output.splitlines() if "cortex" in l.lower()]
237
+ mcp_status = lines[0].strip() if lines else "registered"
238
+ else:
239
+ mcp_status = "not registered — run: cortex install"
240
+ click.echo(f"MCP {mcp_status}")
241
+
242
+ ws = get_active_workspace()
243
+ indexed = Path(qdrant_path(ws)).exists()
244
+ click.echo(f"workspace {ws} ({'indexed' if indexed else 'not indexed'})")
245
+
246
+ last = get_config()["index"].get("last_path") or "(none)"
247
+ click.echo(f"last indexed {last}")
File without changes