Running CodeNavi as a team server¶
One CodeNavi host, the whole team's agents querying it. Developers push to the shared repo as usual; the CodeNavi box keeps its own clone and reindexes on a schedule or on push. Nobody runs a GPU locally, everybody searches the same index.
dev laptop ── git push ──► git server ──► CodeNavi host
(Forgejo / git pull
GitHub / POST /reindex (incremental, seconds)
GitLab…) │
dev's agent ◄───── MCP over the network ── :8765/mcp/{codebase}
Two properties fall out of this design, and both are features:
- Results reflect the host's clone, not anyone's working tree. Uncommitted local edits are invisible to search until pushed and pulled. For a shared index that is what you want — everyone queries the same, reviewable state.
- Paths in results are the host's paths. Keep the same repo-relative layout in every checkout and this never matters.
1. Give the host its own clone¶
CodeNavi indexes a local directory — it never talks to a git remote itself.
Clone the repo somewhere the CodeNavi user owns and point CODEBASE_PATH (or
one entry of CODEBASE_CONFIG) at it:
sudo -u codenavi git clone [email protected]:team/myrepo /srv/codenavi/repos/myrepo
The compose file mounts that directory into the container read-only. Leave it that way — it is a deliberate guarantee that the indexing server can never modify your code (see the security model).
2. Keep the index fresh¶
The sync step is always the same two commands on the CodeNavi host:
cd /srv/codenavi/repos/myrepo && git pull --ff-only
curl -s -X POST http://localhost:8765/reindex \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $CODENAVI_AUTH_TOKEN" \
-d '{"codebase": "myrepo"}'
An incremental reindex re-embeds only changed files — typically seconds. (On
the host you can equally use the codenavi reindex CLI; see the
CLI reference.) Pick one way to trigger it:
Cron on the CodeNavi host — simplest, start here. A few minutes of staleness is fine for almost every team:
*/5 * * * * /srv/codenavi/sync-myrepo.sh >> /var/log/codenavi-sync.log 2>&1
where sync-myrepo.sh is the two commands above with the token read from a
chmod 600 file. A no-change pull followed by a no-change reindex costs almost
nothing, so a tight interval is harmless.
Push-triggered — zero staleness. Run the same script from your git
server's post-receive hook (if it can reach the CodeNavi host over SSH), or
from a one-line CI job on merges to the main branch. If you already run a
CodeNavi-backed CI review bot, this is the same wiring — see
CI review bots, which needs a fresh base-branch index for
diff_impact anyway.
To react to a finished reindex (refresh a dashboard, kick a downstream job),
subscribe to the reindex.completed event instead of polling — see
webhooks & event hooks.
Alternative: let the server pull (opt-in)¶
CODENAVI_GIT_PULL_BEFORE_REINDEX=true (env or data/settings.json, read
live — no restart) makes every reindex run git pull --ff-only in the
codebase root first, when that root is a git checkout.1 A forge webhook
aimed straight at POST /reindex then does pull + reindex in one call, with no
cron and no hook script.
A failed or refused pull (dead remote, auth problem, non-fast-forward) is
logged and never blocks indexing — CodeNavi indexes the tree as it is on
disk. Credential prompts are disabled (GIT_TERMINAL_PROMPT=0), so a repo that
would ask for a password fails fast instead of hanging.
Know what it costs before choosing it. In-container pull only works if:
- the codebase mount is read-write — you must change
read_only: truetofalseon the codebase volume in your compose file, giving up the server-can't-touch-your-code guarantee above, and - the container can authenticate to your git server (an HTTPS remote with a read-only token in the URL, or an SSH deploy key mounted read-only).
The host-side recipes need neither, which is why they are the recommended default. Reserve this switch for a clone you treat as a disposable mirror.
3. Connect the team¶
Each developer's agent points at the server instead of localhost — same config as the single-user setup, different host:
{ "mcpServers": { "codenavi": {
"type": "http",
"url": "http://codenavi.internal:8765/mcp/myrepo",
"headers": { "Authorization": "Bearer <token>" } } } }
- Always set the auth token — a CodeNavi bound beyond loopback refuses to
start without one. Token setup, the plain-HTTP LAN recipe (server bind and
firewall, plus the one
settings.jsonenv block that points the Claude Code plugin, its statusline badge and its session hook at the server), and the HTTPS options (Tailscale, reverse proxy) are covered in remote access. - Scope the URL to
/mcp/<codebase>so every query is pinned to that repo; the per-client walkthroughs under Connect your agent all apply unchanged. - Searches share the GPU. Encode and rerank serialize on their GPU phases and everything else overlaps, so a handful of concurrent developers and bots share one instance comfortably; a burst queues rather than fails. Give agents the standard rule — one or two searches in flight, never a burst (see rules for your agent).
Sizing note¶
One box serves multiple repos: add each clone to CODEBASE_CONFIG and repeat
the sync recipe per codebase. For GPU sizing on a shared box, see the
GPU compatibility matrix; if the team's laptops are strong and
the server is weak, the inverse setup — index in the cloud, serve locally — is
covered in cloud reindex.
-
Vendor change reference CN-564. ↩