# AGENTS.md This repo is not an application. It is a **local MCP server stack**: a docker-compose file that runs AI-coding-tool helpers in Docker so opencode, crush, and VS Code plugins (Cline/Roo/Kilo) can all share the same local services over Streamable HTTP. There is no app source, no test suite, no linter — verification is manual (health endpoints, MCP handshakes, `opencode mcp list`). ## Commands ```bash cp .env.example .env # once; add BRAVE_API_KEY ./add-project.sh # register a project for code indexing (idempotent; starts stack) ./add-project.sh --remove docker compose up -d --build docker compose ps / logs -f mcp / logs -f mcp-codebase-index opencode reload && sleep 3 && opencode mcp list # acceptance check ``` ## Architecture Two services, one image (`Dockerfile`, `node:24-slim`: supergateway@4 + open-codebase-index + context7/brave/`mcp-server-fetch` preinstalled, glibc because the index ships NAPI binaries — do not switch the base to alpine): - `mcp-gateway` (:8000) — supergateway `--config supergateway.config.jsonc`; one endpoint per shared tool: `/fetch/mcp`, `/context7/mcp`, `/brave-search/mcp` (edit the jsonc to add servers, then `docker compose restart mcp`). - `mcp-codebase-index` (:8001) — supergateway `--config supergateway.projects.jsonc` (GENERATED by add-project.sh from `projects.env`; do not hand-edit, re-run the script). One endpoint per registered project: `//mcp`. Mounts `PROJECTS_ROOT` (default `~/src`, kept in `.env`) at the identical container path so index results return valid host paths. Runs as `user: node` (uid 1000) so index data is host-user owned. Index data lives in each project at `.opencode/index/` (structural mode: BM25 + call graph, no embedding provider; ollama upgrade documented in README). Per-project client configs (written into each project by add-project.sh): `opencode.json`, `.crush.json`, `.roo/mcp.json`, each pointing at `http://localhost:8001//mcp`. Global client configs only carry the shared tools (fetch/context7/brave-search). ## Gotchas - **Host docker networking**: the Arch host's default docker0 bridge has NO egress (DNS/TCP fail), so there `BUILD_NETWORK=host` is set in `.env`. On hosts with a working bridge leave it unset — newer compose delegates builds to buildx bake, which rejects `network: host` ("Pass --allow=network.host...") and compose cannot grant the entitlement. - `opencode mcp list` can print "No MCP servers configured" for a few seconds after `opencode reload` (daemon reconnects asynchronously). Retry before assuming breakage. - After changing client configs, crush/opencode sessions must be restarted/reloaded; VS Code plugins need the workspace reopened. - `supergateway.projects.jsonc`, `projects.env`, `.env` are gitignored and machine-specific. `docker-compose.override.yml` (if present) is the documented way to mount extra project roots. - supergateway runs stateful Streamable HTTP; each client session spawns its own stdio server process (nothing idles; index data persists on disk between sessions). - Add brief imperative commit messages; keep disabled blocks commented rather than deleted.