Metadata-Version: 2.3
Name: astroid-mcp
Version: 0.1.0
Summary: High-performance, local FastEmbed vector MCP server for Astro documentation
Author: Nitin
Author-email: Nitin <pypi@600613017.xyz>
License: MIT
Requires-Dist: mcp>=1.2.0,<2.0.0
Requires-Dist: fastembed>=0.4.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: typer>=0.12.0
Requires-Dist: rich>=13.7.0
Requires-Dist: pydantic>=2.7.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# Astroid (astroid-mcp)

High-performance, local FastEmbed ONNX vector + SQLite FTS5 Model Context
Protocol (MCP) server for Astro documentation.

- **Hybrid search**: 384-dim BAAI/bge-small-en-v1.5 embeddings + SQLite FTS5
  BM25, fixed candidate pools, deterministic rankings.
- **Clean chunks**: heading-aware splitting, tiny-section merging, cross-doc
  dedupe; every chunk fully inside the model's 512-token window (zero silent
  truncation).
- **Native stdio**: local execution, zero network ports.
- **Additive-only installer**: never rewrites your existing MCPs or settings.

## Install (Windows and WSL — same package, simultaneously)

One wheel (`py3-none-any`) serves both OSes. Install it as an *application*
so the `astroid` command lands on PATH: `pipx install` or `uv tool install`.
Plain `pip install` / `uv pip install` only drops the library into a Python
environment (no command on PATH) — if you went that way by habit and get
`astroid: command not found`, reinstall with one of the two below.

What `astroid install` does — all three, every time:

1. Registers the server in the global OpenCode config (one additive entry;
   sibling MCPs, comments, and formatting are preserved).
2. Copies the prebuilt docs database into the per-OS user path
   (see table below). An existing database is left byte-identical.
3. Downloads the embedding model (~70 MB, once per OS — shared with other
   MCPs using the same model) into the per-OS model cache (see table below).

Offline? The config entry still applies; the data steps print a skip line
and happen on the first search instead — so the first answer is the slow
one, never the install.

Windows (PowerShell):

```powershell
pipx install astroid-mcp
# or: uv tool install astroid-mcp
astroid install
astroid search "routing" --limit 1   # verify: expect routing docs back
```

WSL / Linux (bash). The `export` line is one-time setup — persist it so
every new shell finds the command:

```bash
uv tool install astroid-mcp
# or: pipx install astroid-mcp
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"   # this shell only; new shells use .bashrc
astroid install
astroid search "routing" --limit 1   # verify: expect routing docs back
```

> **Close OpenCode first.** It holds locks on the server executable and the
> database; installing, uninstalling, or reinstalling while it runs will
> fail or half-finish.

Each OS keeps its **own** database, model cache, and config (see paths
below). Never point the DB across the Windows/WSL boundary (`/mnt/...`):
SQLite locking is unreliable there and both sides will corrupt or stall.

No step above builds anything from source: the wheel already contains the
database and the code, so install is copy + download + one config entry.

### Per-OS paths

| What                  | Windows                                            | WSL / Linux                          |
|-----------------------|----------------------------------------------------|--------------------------------------|
| Server executable     | pipx venv `Scripts\astroid.EXE` (on PATH)          | pipx venv `bin/astroid` (on PATH)    |
| Vector database       | `%USERPROFILE%\.astroid\astroid.db`                | `~/.astroid/astroid.db`              |
| Embedding model cache | `%TEMP%\fastembed_cache`                           | `$TMPDIR/fastembed_cache` or `~/.cache/fastembed` |
| Global MCP config     | `%USERPROFILE%\.config\opencode\opencode.jsonc`    | `~/.config/opencode/opencode.jsonc`  |
| Repo-local MCP config | `<repo>\opencode.jsonc`                            | `<repo>/opencode.jsonc`              |

## Usage (commands run standalone — no uv/pip prefix needed)

```bash
astroid serve                    # boot the MCP stdio server (what OpenCode launches)
astroid search "routing"         # test hybrid search in the terminal
astroid search "query" --category reference --limit 3
astroid install                  # global config, from anywhere (the simple default)
astroid install <path>           # repo-local install into that directory
astroid install --global         # explicit global (same as bare)
astroid uninstall                # global entry + wipe DB + model cache (asks first)
astroid uninstall <path>         # same, for that directory
astroid uninstall --global --yes # same, global scope, no prompt
astroid build --docs ./assets    # rebuild the vector DB from markdown (rare)
```

Categories: `tutorials`, `guides`, `examples`, `reference`, `migration`.

`install` is additive-only: sibling MCPs, comments, and formatting in your
config are preserved (verified by `test_installer.py`). If your main config
file is unparseable, it is backed up, left untouched, and the entry goes
into a sibling `opencode.json` that OpenCode merges automatically.

`uninstall` is a full wipe of astroid artifacts only: our config entry, the
SQLite database, and our model-cache subtree. Note: the model subtree is
shared by name with other MCPs using the same embedding model — uninstalling
one forces the others to re-download (~70 MB) on next use. Self-healing, no
breakage. Everything else is left byte-identical. Removing the package
itself is a second, separate step — and order matters: `astroid uninstall`
**first** (it needs the CLI present), `pip uninstall astroid-mcp` second.
Reversed order strands the database with no tool to remove it.

## Rebuilding the database

Only needed when the documentation sources change. From the source tree
(`assets/` lives in this repo, so clones can rebuild anywhere):

```bash
astroid build --docs ./assets --db astroid/astroid.db
```

Release snapshot (v0.1.0 database, built 2026-09-07): 241 documents,
3,904 chunks, 23.24 MB (`astroid/astroid.db`, sha256 `04674b47e5c1d6a7…`).
Chunk budget 460 tokens + ~30-token embed prefix (zero silent truncation
past the 512-token wall). Determinism baselines (hybrid search, limit 3):
`routing` → `Internationalization (i18n) Routing > routing` (0.5654);
`content collections` → `Content collections > What are Content
Collections?` (0.6227).

Expect per-batch log lines; a flat 0% for the first minutes is normal
(model load). Run it yourself in a plain terminal (never from inside an
agent session with a timeout).

## WSL validation (no Windows crossover)

The wheel bundles one OS-portable database (relative paths, float32 blobs,
cross-platform SQLite). Install copies it into `~/.astroid/` and downloads
the model automatically; after installing the tool (see Install above,
including the one-time PATH line):

```bash
astroid install
astroid search "routing" --limit 1   # instant after provisioning
```

No build, no manual copy. What stays forbidden is *running* two servers
against one shared file across `/mnt` (locking) — each OS keeps its own
copy.

## Troubleshooting

- **First search is slow**: install provisions the DB + model, so this only
  happens when install ran offline — the first search then fetches what is
  missing, and everything is local after that.
- **First MCP answer times out once**: the freshly spawned server loads the
  model on its first embed. Retry — the process is warm from then on.
- **`astroid: command not found` after install**: you used `pip install` /
  `uv pip install` (library into an environment, no command on PATH).
  Reinstall with `pipx install astroid-mcp` or
  `uv tool install astroid-mcp`. On WSL/Linux, also check the one-time
  `~/.bashrc` PATH line from Install above (new shells need it).
- **Install/uninstall errors about locked files**: quit OpenCode first.
- **Unparseable config**: the installer backs it up, leaves it alone, and
  prints the exact block to paste manually.

## Release checklist (maintainers)

1. Bump `version` in pyproject.toml (+ uv.lock) and commit + push code.
2. Only when the docs changed: rebuild the DB (`astroid build --docs
   ./assets --db astroid/astroid.db`, filepaths stored relative, no machine
   paths leak), commit the DB + `assets/` (yes, the binary lives in git —
   it is the release artifact) and push. Code-only releases reuse the
   committed DB blob untouched.
3. Run both suites with the venv python directly.
4. `uv build`, then audit: wheel must contain `astroid/astroid.db` (sha256
   matches the committed blob), must not contain `__pycache__`.
5. Clean-venv trial with an isolated HOME: install the wheel, bare `install`
   must land global and provision data, `astroid serve --help` exits 0,
   first `search` answers.
6. Publish, then validate with a real pipx/uv-tool install on each OS.
