Two changes to the synced opencode config: - Model provider. opencode can't list models from a custom OpenAI-compatible provider itself, so sync.sh queries the gateway's /v1/models with the user's key and materializes the map client-side. New gateway models land on every box at the next sync with no config edit. If discovery fails the previous map is carried over, so a gateway hiccup never empties the list. - Aggregate MCP endpoint. One entry at /mcp/ (trailing slash required — the bare path 307-redirects and MCP clients don't follow it) exposes every server the key can access, replacing the per-server gitea entry. sync.sh also exports OPENCODE_CONFIG: opencode does not auto-load extra files from its config dir, so without it the synced file was ignored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mcp-config — shared MCP gateway config for laptops
Single source of truth for the shared MCP servers every covert-gpt user
gets through the LiteLLM gateway (llm.covert-gpt.com). Users install once;
their config then refreshes automatically on each new shell.
This repo lives in Gitea at public/dotfiles. (It is mirrored from the
ai-k8s-iac repo under mcp-config/; edit it there or here and keep them in
sync — the laptops pull from Gitea's main.)
How it works
opencode.gateway.json— the shared base config: thecovert-gptmodel provider (LiteLLM's OpenAI-compatible endpoint athttps://llm.covert-gpt.com/v1, models map left empty — it is filled by discovery at sync time) and a single MCP entry for the gateway's aggregate endpointhttps://llm.covert-gpt.com/mcp/(trailing slash required; the bare path 307-redirects, which MCP clients don't follow). That one endpoint exposes every MCP server the user's key can access, so new gateway servers need no client config change at all. Identical for every user: the per-user key is injected via{env:LITELLM_KEY}, never written into the file.sync.sh— sourced from each user's shell rc. On a new shell (throttled ~1h) it pulls the base config from Gitea, queries the gateway's/v1/modelswith the user's key to auto-discover models (opencode can't list models from a custom provider itself, so the map is materialized client-side; if discovery fails the previous map is carried over), deploys the result to~/.config/opencode/opencode.gateway.json, and exportsLITELLM_KEY(from~/.config/mcp-sync/key) plusOPENCODE_CONFIG(pointing at the deployed file — opencode does NOT auto-load extra files in its config dir, so without this export the file is ignored). Silent + non-fatal: a Gitea hiccup never breaks the shell, last-good config stays in place.install.sh— one-time bootstrap (curl-pipe). Fetchessync.sh, stores the user's key (0600), and adds the rc hook.
opencode merges the OPENCODE_CONFIG file on top of the user's global
~/.config/opencode/opencode.json (and under any project opencode.json),
so the synced config coexists with each user's own settings and any
local-only MCP servers (e.g. a client-side kubernetes pointed at their
own kubeconfig). Sync never touches those.
User setup (one time)
Each user needs a LiteLLM virtual key scoped to the gateway servers (see
charts/inference/MCP-GATEWAY.md in ai-k8s-iac for how keys are minted). Then:
curl -fsSL https://git.nic-oconnor.com/public/dotfiles/raw/branch/main/mcp-config/install.sh | sh
# (prompts for the sk-... key; or pass it: ... | LITELLM_KEY=sk-... sh)
Open a new terminal, run opencode, and the gateway tools are there.
Adding a gateway server or model (admin)
Register it on the gateway (charts/inference/values.yaml →
proxy_config.mcp_servers for MCP servers, model_list for models),
deploy, smoke-test. That's it — clients auto-discover both: MCP servers
through the aggregate /mcp/ endpoint, models via the /v1/models query
in sync.sh. Users pick them up within the sync TTL (or immediately on a
new shell). opencode.gateway.json here only needs editing for structural
changes (a new provider, endpoint URLs).
For per-user / per-target tools (cluster access, etc.) do NOT add them
here — those run client-side with the user's own credentials. See
charts/inference/MCP-GATEWAY.md.
Notes / caveats
- Local-server precedence: opencode merges with later-config-wins on key conflicts. If a user names a local server the same as a gateway one, theirs wins. Use distinct names.
- Key rotation: re-run
install.sh(or edit~/.config/mcp-sync/key). - Other clients: this ships an opencode config. Claude Code / open-webui would need their own equivalent file + a parallel sync entry; not done yet.
- Throttle: override with
MCP_SYNC_TTL=0to force a pull every shell.