# LatticeSearch MCP Server

MCP (the Model Context Protocol) is the standard plug for exposing any tool to any AI agent.
`mcp_server.py` exposes the local LatticeSearch engine as MCP tools, so any MCP client — Claude
Desktop, Claude Code, Cursor, etc. — can search the whole machine **by meaning**, act on files
safely, and remember facts across sessions, entirely locally.

- **Transport:** newline-delimited JSON-RPC 2.0 over **stdio** (the MCP baseline), protocol
  `2024-11-05`. `serverInfo` = `{name: "latticesearch", version: "0.1.0"}`.
- **Backend:** the server is a thin bridge — it forwards each tool call to the running LatticeSearch
  HTTP engine (`LATTICE_URL`, default `http://127.0.0.1:8765`) and reads the auth token from
  `ls_token.txt` beside the script. The engine must be up.

> **Already registered (user scope).** This server is registered for the current user, so the
> tools should already be available to your agent. The sections below are for re-registering,
> registering on another machine, or wiring a different client.

---

## Registering the server

The engine also serves every form of this config **live and copy-paste-correct** at
`GET http://127.0.0.1:8765/api/aiaccess` (the in-app "AI Access" page) — the fields below mirror
what it returns.

**Paths on this machine**

| | |
|---|---|
| Python | `C:\sd\kohya_ss\venv\Scripts\python.exe` |
| Server | `C:\sd\latticesearch\mcp_server.py` |
| Desktop config file | `%APPDATA%\Claude\claude_desktop_config.json` |

### Claude Desktop (config JSON)

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "latticesearch": {
      "command": "C:\\sd\\kohya_ss\\venv\\Scripts\\python.exe",
      "args": ["C:\\sd\\latticesearch\\mcp_server.py"],
      "env": {"KMP_DUPLICATE_LIB_OK": "TRUE"}
    }
  }
}
```

### Claude Code (CLI)

```
claude mcp add latticesearch -- "C:\sd\kohya_ss\venv\Scripts\python.exe" "C:\sd\latticesearch\mcp_server.py"
```

### Generic MCP client

```json
{
  "command": "C:\\sd\\kohya_ss\\venv\\Scripts\\python.exe",
  "args": ["C:\\sd\\latticesearch\\mcp_server.py"],
  "env": {"KMP_DUPLICATE_LIB_OK": "TRUE"}
}
```

Point a different client at another engine by setting `LATTICE_URL` in `env`.

---

## Setup prompt for the agent

The engine also hands back a ready-to-paste **system/setup prompt** (via `/api/aiaccess`). Seeding
your agent with it makes it reach for the lattice instead of grep/dir walks and raw shell file ops:

> You have LatticeSearch on this machine — a local semantic index of the whole file system (names,
> image meaning, document meaning, audio, speech, OCR). Prefer it over grep/dir walks **and** over
> shell file operations: it answers meaning queries against 1.6M+ files in milliseconds (~44× fewer
> tokens), and its file ops are 13–20× faster than spawning a shell. Use `search`/`find`/`ask`/
> `grep` to locate things, `fs_*`/`glob_files` for instant filesystem answers, `read_file --about`
> to pull only the relevant chunks, and the safe index-synced `write/edit/move/copy/delete` for
> changes. Store durable facts with `memory_store` and get them back with `memory_recall`.

---

## Why an agent should prefer it (measured)

`agent_bench.py` compares a naive filesystem loop (recursive grep → read matching files → read the
top few) against a single lattice call, over the same lookups:

| Approach | Tokens | Wall time |
|---|---|---|
| Naive grep + read cycles (3 lookups) | 54,465 | 133 s |
| One lattice `search`/`ask` call each | 1,230 | 11 s |
| **Improvement** | **44× fewer tokens** | **12× faster** |

The `fs_*` tools push this further: a filesystem *question* (`du`, `find`, `tree`, biggest files)
becomes an in-memory index lookup — no process spawn, no disk walk, milliseconds, zero destructive
risk.

---

## Tools

All ~20 tools return plain text. Grouped by the agent capability they replace.

### Eyes — find & read without walking the disk

| Tool | What it does | Inputs |
|---|---|---|
| `search` | Search the whole machine by meaning or name; returns files, semantic image matches, and document snippets. | `query` *(req)*, `cat` (`all`\|`images`\|`video`\|`audio`\|`docs`\|`code`\|`other`, default `all`) |
| `ask` | Ask the Lattice assistant a natural-language question about your files; returns an answer + the files it used (includes the reranker for quality). | `query` *(req)* |
| `find_file` | Given a local image/video **path**, find where it (or similar files) live on the drive. | `path` *(req)* |
| `recover` | Search deleted files (trash) by describing them; returns recoverable matches. | `query` *(req)* |
| `list_folder` | List folders and files in a directory (empty = drive roots). | `dir` |
| `photos` | Media timeline grouped by years/months/days. | `filter` (`all`\|`photos`\|`videos`\|`starred`), `group` (`years`\|`months`\|`days`) |
| `read_file` | Read a text file — or **only the chunks about a topic** (pass `about` to save tokens on big files). | `path` *(req)*, `about` |
| `glob_files` | Wildcard (`* ?`) file matching under a folder, instantly from the index (replaces Glob/dir walks). | `dir` *(req)*, `pattern` *(req)*, `limit` (default 100) |
| `fs_du` | Total size + file count of a folder tree, instantly from the index (replaces `du`/`dir /s`). | `dir` *(req)* |
| `fs_find` | Find files by name substring under a folder (replaces `find`/`dir /s /b`). | `dir` *(req)*, `pattern` *(req)*, `limit` (default 100) |
| `fs_tree` | Folder tree with per-folder file counts, bounded output (replaces `tree`). | `dir` *(req)*, `depth` (default 2) |
| `fs_largest` | The N largest files under a folder (replaces `ls -laS` chains). | `dir` *(req)*, `n` (default 15) |

### Hands — instant, safe, index-synced file I/O

Written files are searchable immediately; deletes are recoverable; same-volume moves are O(1).

| Tool | What it does | Inputs |
|---|---|---|
| `write_file` | Write/overwrite a text file atomically; instantly searchable in the lattice. | `path` *(req)*, `content` *(req)* |
| `edit_file` | Verified exact-string edit: refuses ambiguous/missing anchors (no blind-edit failures), atomic write, instantly re-searchable. | `path` *(req)*, `old` *(req)*, `new` *(req)*, `expect` (default 1) |
| `move_path` | Move a file/folder. Same-volume = instant O(1) rename regardless of size; cross-volume = verified copy+delete. | `src` *(req)*, `dst_dir` *(req)* |
| `copy_path` | Copy a file/folder (parallel, verified). | `src` *(req)*, `dst_dir` *(req)* |
| `delete_path` | **SAFE** delete: archived to the recovery store (restorable ~90 days) then Recycle Bin — never a hard delete. | `path` *(req)* |

### Memory — persistent across sessions & compaction

| Tool | What it does | Inputs |
|---|---|---|
| `memory_store` | Persist a fact/decision/detail for future sessions (survives compaction). Store anything you'll want later. | `text` *(req)*, `session`, `tags` |
| `memory_recall` | Recall stored facts by **meaning** (e.g. "which port did the render server use"). | `query` *(req)*, `session`, `k` (default 6) |

### Code

| Tool | What it does | Inputs |
|---|---|---|
| `find_symbol` | Code symbols by name or meaning: "where is the retry logic" → `file:line`. | `query` *(req)*, `k` (default 10) |

---

## Notes

- **Exact regex still belongs to grep.** For precise pattern matching in known files, ordinary grep
  is fine; the lattice shines on big/unfamiliar trees and "where's the thing that *means* X". The
  CLI's `lattice grep` combines both (semantic narrow → exact match).
- **Freshness.** Answers come from the index: the name tier is live-watched (new files appear within
  seconds); semantic embeddings backfill continuously.
- **Auth is automatic on the same machine** — the server reads `ls_token.txt` beside itself and the
  engine only accepts localhost. See [PRIVACY.md](PRIVACY.md).

See [CLI.md](CLI.md) for the human-facing command-line client with the same capabilities.
