opencode-mtel
v1.2.2
Published
Install the MTEL dynamic model catalog plugin for OpenCode
Readme
opencode-mtel
Installs MTEL's dynamic OpenCode model catalog plugin.
When the gate enables Glory, the plugin includes mtel/Qwen/Qwen3.8-27B-FP8
under the existing MTEL Anthropic provider. Claude/GPT configuration is unchanged.
Glory defaults to disabled tool/reasoning capabilities when metadata is absent;
unknown prices and limits are omitted except for the verified client budget below.
Streaming and tools are unverified live.
The exact resolved model mtel/Qwen/Qwen3.8-27B-FP8 gets token limits
context: 262144 and output: 32768 when its catalog owner is Glory. These override
only those two metadata fields after provider selection and before limit
normalization, preserving a valid input limit even in partial metadata. Other
models and providers, including an identical ID owned by Claude/OpenAI in a
catalog collision, are unchanged. An absent model is not added. The budget is
applied on every catalog load and bundled by the installer, so plugin regeneration
retains it. This is client metadata reflecting the approved backend-supported limits;
it does not configure the upstream or enable tools/reasoning or change credentials,
pricing, or routing.
Key verification first probes Claude as before. After a 403 only, it fetches the
public catalog and tries the first Glory model once with max_tokens: 1. This
supports Qwen-only keys without scanning all models. It is not an exhaustive
permission check: GPT-only keys or keys limited to a future later Glory entry
may still fail. No retries are made for timeouts, 401, 429, or server errors.
Requires Node.js >=14.18.
npx opencode-mtel install
npx opencode-mtel install --key VALUE
npx opencode-mtel install --key=VALUEThe installer copies the bundled mtel-catalog.ts to:
${XDG_CONFIG_HOME:-$HOME/.config}/opencode/plugins/mtel-catalog.tsIt then uses ${XDG_CONFIG_HOME:-$HOME/.config}/opencode/opencode.jsonc when present, otherwise
opencode.json, and creates opencode.jsonc when neither exists. The plugin
is added once to the top-level plugin array as a local file: URI. Existing
plugins and unrelated configuration, including JSONC comments and trailing
commas, are retained. A timestamped *.bak copy is created beside an existing
config immediately before an actual config edit. Existing config and plugin
symlinks are preserved and updated through their targets.
npx opencode-mtel install --dry-run
npx opencode-mtel install --helpAPI key setup is optional. On a normal install, --key takes precedence over
MTEL_API_KEY. When either is provided, the installer verifies the key with a
minimal request before changing the plugin or config, then stores the trimmed
key at ${XDG_CONFIG_HOME:-$HOME/.config}/opencode/mtel-api-key with mode
0600. When neither is provided, the installer does not prompt, verify, or
create/write the key file; plugin and config installation still succeeds,
including in non-interactive environments. MTEL_BASE_URL is optional and
defaults to https://polycon.mtel.cloud.
The built-in HTTP verification request uses a 15,000 ms timeout by default; set
MTEL_VERIFY_TIMEOUT_MS to a positive whole-number millisecond value to customize it.
Invalid, non-positive, or out-of-range values use the 15,000 ms default.
The plugin uses MTEL_API_KEY first and otherwise reads that key file.
Warning: putting a key in a CLI argument can expose it through shell history or
process listings. Prefer MTEL_API_KEY in production.
Model catalog
The plugin does not ship a static model list. On every OpenCode startup it fetches
${MTEL_BASE_URL:-https://polycon.mtel.cloud}/models and registers every model the
gate currently exposes under the mtel provider, so new models (and retired ones)
appear automatically without an opencode-mtel upgrade.
Each model's name, reasoning support, tool-call support, context/output limits, and
supported reasoning effort levels (e.g. none, low, medium, high, xhigh,
max) are read from the gate's per-model metadata. Claude/GPT metadata mirrors
the upstream models.dev catalog; Glory uses the gate's explicit
static catalog. Reasoning effort variants are generated
per model from its own reasoning_options, so a model that doesn't support none
or max won't advertise a variant for it. If the configured gate predates the
metadata field, or a Claude/GPT model has no metadata, the plugin falls back to
reasoning: true, tool_call: true, and the effort levels low/medium/high/xhigh.
Cost is populated from the gate's /models pricing map whenever both input and
output prices are known.
Safety and limitations
The installer validates the selected config and its intended edit, and verifies
the API key when one is provided, before it creates, replaces, or backs up files. It exits nonzero without mutations when
the selected config is invalid JSON/JSONC, has duplicate top-level keys, or has
a top-level plugin value that is not an array.
The JSONC editor is intentionally small and preserves source text around the edited array or top-level object. It supports standard JSONC line/block comments and trailing commas. It does not support non-JSON extensions, JSON5 syntax such as single-quoted strings or unquoted keys, or configurations whose top-level keys are duplicated. In unusual empty containers with comments, surrounding whitespace may be normalized to keep the resulting source valid.
Development
npm test
npm run test:compat
npm pack --dry-runnpm test uses Node's built-in test runner and requires a newer Node release
where that runner is available; the catalog plugin tests additionally require
Node 22.6+ for --experimental-strip-types to load the TypeScript plugin directly.
For Node 14.18+ runtime validation, use npm run test:compat; it exercises the
installed CLI against a local mock HTTP endpoint without making an external request.
For end-to-end runtime validation in clean containers, run:
npm run test:dockerThis packs the local package and runs the install test in node:14-alpine,
node:16-alpine, node:18-alpine, node:20-alpine, and node:22-alpine.
Docker must be installed and running. The containers use --network none; the
verification server runs on container loopback, so no MTEL or other host
network request is possible. Each run uses a temporary container HOME and
checks key verification, the plugin/config/key files, the local plugin URI,
and 0600 key permissions on POSIX systems. The first run downloads the five
images and commonly takes about 2–5 minutes; later runs generally take under a
minute. Set OPENCODE_MTEL_DOCKER_NODE_VERSIONS=14,22 for a shorter smoke
matrix.
