Content
# Axelera Voyager Local Assistant
A **local MCP server** that gives an AI coding agent (Claude Code, or any MCP client) working
knowledge of the [Axelera](https://axelera.ai) Voyager SDK and Metis AIPU — semantic search
over the public Axelera sources, plus project/task/document tracking. **No account, no login,
no token, no cloud.**
```
$ claude mcp add voyager --scope project -- .venv/bin/python voyager-mcp/server.py
# then ask your agent: "how do I deploy a custom YOLO model on Metis?"
# → it searches the SDK docs and code semantically, locally
```
## What it does
Two halves that work together:
- **`skills/`** — 15 agent skills covering the Voyager workflow: build and launch a complete
pipeline end to end, deploy/quantize a custom model, run inference on a source, benchmark
FPS on hardware, debug a broken install or board, add a model to the zoo, scaffold an app,
and more. They detect the environment (SDK present? Metis card visible?) and adapt, so they
degrade to package-only output on a machine with no accelerator.
- **`voyager-mcp/`** — the MCP server the skills call: semantic search over the Axelera
sources, plus project/task/document tracking.
| Skill | Use it for |
|---|---|
| `voyager-launch` | one-shot: natural language → runnable pipeline, validated on Metis, with a result viewer |
| `voyager-deploy` | compile / quantize / calibrate a custom model for the AIPU |
| `voyager-run` | run `inference.py` on video, image, USB, RTSP |
| `voyager-bench` | measure FPS, latency, throughput |
| `voyager-debug` | diagnose pipelines, drivers, firmware, board detection |
| `voyager-add-model` | add a PyTorch/ONNX/timm/Ultralytics model to the zoo |
| `voyager-new-pipeline` / `voyager-new-app` | YAML pipeline design / standalone InferenceStream app |
| `voyager-list-models` / `voyager-help` | search the model zoo / explain the SDK |
| `voyager-agent`, `voyager-build`, `voyager-test`, `voyager-changelog`, `voyager-init` | routing, native builds, pytest, changelogs, workspace setup |
### The MCP server
**25 MCP tools**, in three groups:
| Group | Tools |
|---|---|
| **RAG** (3) | `rag_search_knowledge_base`, `rag_search_code_examples`, `rag_get_available_sources` |
| **Tracking** (20) | projects, tasks, documents, versions — full CRUD + version snapshot/restore |
| **Introspection** (2) | `health_check`, `session_info` |
### The RAG
Indexes the **public** Axelera sources with local embeddings (`fastembed`, ONNX, no torch,
no GPU):
| Source | Contents |
|---|---|
| [voyager-sdk](https://github.com/axelera-ai-hub/voyager-sdk) | SDK docs, model-zoo YAMLs, example apps |
| [axelera-driver](https://github.com/axelera-ai-hub/axelera-driver) | Metis PCIe driver (Linux) |
| [meta-axelera](https://github.com/axelera-ai-hub/meta-axelera) | Yocto layer |
| [aisbc.axelera-doc](https://github.com/axelera-ai-hub/aisbc.axelera-doc) | AI SBC documentation |
| [axelera-aisbc-bsp](https://github.com/axelera-ai-hub/axelera-aisbc-bsp) | AI SBC Yocto BSP |
~2.3k chunks / ~290k words, ~7 MB of index. Search is cosine similarity over normalized
embeddings, with a keyword fallback (ripgrep-style scoring) when no index is built — so the
server works with zero setup.
Retrieved text is prefixed with an untrusted-content marker, so an agent treats it as
reference material rather than instructions.
## Install
```bash
git clone https://github.com/fxd0h/Axelera-Voyager-Local-Assistant && cd Axelera-Voyager-Local-Assistant
./install.sh
```
Then start a **new** `claude` session and approve the project MCP server.
`install.sh` creates the venv, resolves a Voyager SDK checkout (uses `$AXELERA_FRAMEWORK` or
clones the public repo), installs the index, and registers the server. If a prebuilt index is
published it downloads it (`VOYAGER_INDEX_URL`); otherwise it builds one locally (~2 min of
CPU).
### Refresh the index
```bash
cd voyager-mcp && ./fetch.sh && .venv/bin/python reindex.py
```
## Sharing with a team
See **[voyager-mcp/DEPLOYMENT.md](voyager-mcp/DEPLOYMENT.md)**. Short version: the index is a
read-only, **portable** artifact (it stores repo-relative paths only, never absolute paths from
the machine that built it — links resolve to GitHub at query time), so sharing knowledge across
a team is just distributing three files, with no server at all. Only shared *state* needs a
server, and the code supports HTTP transport for that:
```bash
VOYAGER_MCP_TRANSPORT=streamable-http VOYAGER_MCP_HOST=0.0.0.0 VOYAGER_MCP_PORT=8080 \
.venv/bin/python server.py # clients: claude mcp add voyager --transport http http://host:8080/mcp
```
## Finding: the video pipeline hides most of the board's throughput
Building the example app surfaced a measurable gap: the same model on the same Metis M.2
delivers 34–61 FPS through the standard annotated-video pipeline and **740 FPS** through a
headless application, while the AIPU stage reports ~840 FPS in both cases. See
**[FINDINGS.md](FINDINGS.md)** for the measurements, interpretation and reproduction steps.
## Limitations
Known and deliberate — read before deploying beyond your own machine.
**Single-user by default.** stdio transport, state in local JSON. Project/task data lives on
one machine and is not shared.
**No authentication.** The server has no auth or authorization of any kind. That is fine for a
local stdio process; on a network, every client that reaches the port gets full access to every
tool, including deletes. Put it behind a proxy with a bearer token or mTLS first, and terminate
TLS — the server speaks plain HTTP. See DEPLOYMENT.md.
**No tenancy.** In a shared deployment all users share one namespace: everyone can see and
modify everyone's projects, tasks and documents.
**Storage is small-team scale.** One JSON file per collection, with an exclusive `flock` held
across each read-modify-write and atomic rename on save. Concurrent writers are safe, but it
requires a POSIX filesystem with working locks (local disk or a single server — **not NFS/SMB**),
rewrites the whole collection on every write, and must not be run from several instances against
one directory. Swap the `JsonStorage` class for SQLite/postgres to go further; the tools only
depend on its method signatures.
**The index is a point-in-time snapshot.** It reflects the public repos as of the day it was
built; it does not track upstream automatically. Re-run `fetch.sh && reindex.py` after an SDK
release, and restart the server so it reloads. A prebuilt index may lag the current SDK.
**Retrieval quality is plain semantic search.** Single-vector cosine over 1500-character
chunks, no reranking, no hybrid keyword+vector fusion, no query expansion. It is good at
"where is this documented / show me a similar example" and weaker at exact-symbol lookups,
where ripgrep still wins.
**Public sources only.** Marketing pages, the store, and product datasheets are not indexed —
this is aimed at code and docs. Hardware spec questions ("how many TOPS does the M.2 have")
may be unanswered.
**Linux-oriented.** Developed and tested on Linux with Python 3.12. The file locking degrades
gracefully on non-POSIX platforms (no locking), which is only safe single-user.
## Layout
```
skills/ 15 Voyager workflow skills (installed into .claude/skills/)
voyager-mcp/
├── server.py 25 MCP tools; stdio / streamable-http / sse
├── rag/__init__.py semantic search + keyword fallback + URL resolution
├── storage/__init__.py JSON store: flock + atomic writes
├── reindex.py build the semantic index
├── fetch.sh clone/update the public source repos
└── DEPLOYMENT.md team / LAN / cloud deployment
install.sh one-shot setup
```
## License
MIT — see [LICENSE](LICENSE).