diff --git a/mcp-config/README.md b/mcp-config/README.md index 11181b3..9a20fb7 100644 --- a/mcp-config/README.md +++ b/mcp-config/README.md @@ -122,6 +122,30 @@ Models are different: they live on the gateway Add a folder under `skills/` and push to `main` — see `skills/README.md`. Verify with `opencode debug skill`. +## "I added a model on the gateway and opencode doesn't see it" + +Almost always a stale local config, not a gateway or key problem. The sync runs +**only at shell start** and is throttled to `MCP_SYNC_TTL` (1h), so a new model +can take up to an hour *and* a new terminal to appear. + +Pull it immediately: + +```sh +mcp-sync # force a refresh now, ignoring the TTL; prints the model list +``` + +If the model still isn't listed, it isn't reaching your key — check the gateway, +not the client: + +```sh +curl -fsS -H "Authorization: Bearer $LITELLM_KEY" \ + https://llm.covert-gpt.com/v1/models | jq -r '.data[].id' +``` + +Whatever that prints is exactly what `sync.sh` will deploy. A model present here +but missing in opencode is a sync problem; a model missing here is a LiteLLM +`model_list` or key-scoping problem. + ## Notes / caveats - **Local-server precedence**: opencode merges with later-config-wins on key @@ -130,4 +154,8 @@ Verify with `opencode debug skill`. - **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=0` to force a pull every shell. +- **Throttle**: `mcp-sync` forces one refresh; `MCP_SYNC_TTL=0` in the + environment makes every new shell pull. +- **python3 is required** for model discovery. Without it `sync.sh` deploys the + base config verbatim, so the provider comes up with an EMPTY model list. It + warns when this happens; `bootstrap.sh` installs python3. diff --git a/mcp-config/sync.sh b/mcp-config/sync.sh index b842bd5..37a2a74 100644 --- a/mcp-config/sync.sh +++ b/mcp-config/sync.sh @@ -211,4 +211,31 @@ _mcp_sync_skills # the synced file so it is layered on top of the user's global opencode.json. [ -f "$MCP_SYNC_DEST" ] && export OPENCODE_CONFIG="$MCP_SYNC_DEST" +# --- mcp-sync: force a refresh now, ignoring the TTL ------------------------ +# The automatic sync above runs ONLY at shell start and is throttled to +# MCP_SYNC_TTL (1h). So a model or MCP server added on the gateway can take up +# to an hour AND a new terminal before it shows up in opencode -- which reads +# as "my new model isn't there" when in fact the gateway is fine and the local +# config is just stale. Run `mcp-sync` to pull it immediately. +# +# Defined for the interactive shell (zsh/bash), which is the only place sync.sh +# is sourced; the hyphen in the name is fine there. +MCP_SYNC_SELF="${MCP_SYNC_SELF:-$HOME/.config/mcp-sync/sync.sh}" +mcp-sync() { + [ -f "$MCP_SYNC_SELF" ] || { + printf 'mcp-sync: %s not found\n' "$MCP_SYNC_SELF" >&2; return 1 + } + # Re-source with the throttle disabled; this redefines and re-runs everything. + # shellcheck disable=SC1090 + MCP_SYNC_TTL=0 . "$MCP_SYNC_SELF" || return 1 + command -v python3 >/dev/null 2>&1 || { printf 'mcp-sync: refreshed.\n' >&2; return 0; } + MCP_SYNC_PY_DEST="$MCP_SYNC_DEST" MCP_SYNC_PY_PROVIDER="$MCP_SYNC_PROVIDER" \ + python3 - <<'PYEOF' >&2 +import json, os +cfg = json.load(open(os.environ["MCP_SYNC_PY_DEST"])) +models = cfg.get("provider", {}).get(os.environ["MCP_SYNC_PY_PROVIDER"], {}).get("models", {}) +print(f"mcp-sync: {len(models)} models -> {', '.join(models) or '(none)'}") +PYEOF +} + unset -f _mcp_sync_export_key _mcp_sync_refresh _mcp_sync_skills 2>/dev/null || true