Models and MCP servers are discovered from the LiteLLM gateway at sync time
(/v1/models, and the aggregate /mcp/ endpoint). Skills have no gateway side to
query: LiteLLM's /v1/skills is a passthrough to Anthropic's Skills API, which
lists skills on an Anthropic account rather than serving skill files, and
/public/skill_hub is a marketplace catalog. So the repo is the source of truth
and the tree is fetched whole, from the repo tarball.
Deploy to ~/.config/mcp-sync/skills rather than ~/.config/opencode/skills so
the atomic replace can never delete a skill the user wrote by hand; opencode
picks the tree up via skills.paths, which expands {env:HOME} — verified — so
the shared config stays identical for every user.
Same throttle and non-fatal discipline as the config sync: a fetch that yields
no skills/ leaves the last-good tree in place instead of emptying it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.6 KiB
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 repo's skills (see below), deploys the config 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.../skills/— the shared skill folders, deployed to~/.config/mcp-sync/skillsand wired in throughskills.pathsin the config above. Skills are plain files, so — unlike models and MCP servers — there is nothing on the gateway to discover and the repo is the source of truth; the tree is fetched whole from the repo tarball. They deploy to mcp-sync's own directory rather than~/.config/opencode/skillsso the atomic replace can never delete a skill the user wrote by hand. Seeskills/README.md.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).
Adding a skill (admin)
Skills have no gateway side. Add a folder under skills/ and push to main —
see skills/README.md. Verify with opencode debug skill.
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.