Integration guides ยท 2026-08-29
Adding the LLMTR gateway entry to OpenClaude and how discovery works
Where the LLMTR gateway entry for OpenClaude lives, why the key is read from a dedicated variable only, the three conditions the catalog discovery filter applies, and how aliases keep a model selection alive across restarts.
Which repository and branch the entry lives in
This integration is not an environment variable trick; it is a record that sits in the source tree. It is defined in the knowhycodata/openclaude repository, on the feat/add-llmtr-provider branch, in the file src/integrations/gateways/llmtr.ts. The helper that produces the record is defineGateway, so LLMTR joins the tool's gateway list as an entry of its own.
This has to be stated plainly: the branch was not merged upstream. If you install the official OpenClaude build and open the gateway list, LLMTR will not be there. To try it you need to take the feat/add-llmtr-provider branch from knowhycodata/openclaude and run your own copy.
The top-level fields of the record set the identity and the defaults. The category is marked as aggregating, the base URL is the OpenAI-compatible root of the gateway, and model routing is enabled. A global passthrough route is chosen as the default model; the comment in the source justifies that as the broadly useful choice for a fresh setup.
Top-level fields of the record in src/integrations/gateways/llmtr.ts
export default defineGateway({
id: 'llmtr',
label: 'LLMTR',
category: 'aggregating',
defaultBaseUrl: 'https://llmtr.com/v1',
defaultModel: 'anthropic/claude-sonnet-4.6',
supportsModelRouting: true,
// setup, startup, transportConfig, preset,
// validation, catalog and usage follow
})
The key is read from its own variable only
The most notable decision in the record is credential isolation. The setup section asks for key-based authentication and reads the key from a single variable, LLMTR_API_KEY. A flag next to it disables any fallback to a generic OpenAI key, and the source comment states the reason outright: otherwise a credential held for a different provider would be sent to llmtr.com.
The transport is built on an OpenAI-compatible shim with the required format pinned to chat completions. The output ceiling travels in the max_tokens field, and the credential is carried in the Authorization header only, with additional auth headers switched off. Validation preserves the same isolation: the record matches the default base URL and the llmtr.com host, and a missing key produces a message that names the variable to fill in.
| Field | Value | Effect |
|---|---|---|
| defaultBaseUrl | https://llmtr.com/v1 | Base URL for provider requests |
| authMode | api-key | Setup prompts for a key |
| credentialEnvVars | LLMTR_API_KEY | The only variable the key is read from |
| dedicatedCredentialsOnly | true | No fallback to a generic OpenAI key |
| requiredApiFormat | chat_completions | Requests go out in chat completion shape |
| maxTokensField | max_tokens | The output ceiling uses this field name |
| supportsAuthHeaders | false | Credentials travel in the Authorization header only |
| probeReadiness | openai-compatible-models | Startup readiness is probed on the model list endpoint |
The single credential variable the record expects
export LLMTR_API_KEY=llmtr-your_key
The model list fills from a hybrid catalog
The catalog source is marked hybrid: a handful of seed entries are written into the file and the rest is pulled from the model list endpoint at runtime. The source comment gives the reason as well, since the gateway serves hundreds of routes and keeping all of them in a static list is not worth the maintenance.
Discovery runs without a key. Because the catalog is identical for every credential, the record deliberately avoids transmitting secrets and avoids partitioning the cache by key. The cache is held for a day, refresh happens in the background when the entry is stale, and a manual refresh is allowed.
The distinguishing part is the filter inside the mapping function. The LLMTR model list also describes embedding, image, audio, video and reranking operations, so routes that are useless in a coding agent session are dropped here. A record that fails any one of three conditions never reaches the list.
- Chat completions must appear among the supported operations
- The chat completions endpoint must appear among the supported endpoints
- Tool definitions must appear among the supported parameters
- Once all three hold, vision and reasoning capabilities are derived from the same record
- Context window and single-response ceiling are read from that record too
Checking the tool filter that discovery applies
curl -s "https://llmtr.com/v1/models?supported_parameters=tools" \
| grep -o '"id":"[^"]*"' \
| head -20
Aliases keep a selection alive across restarts
Each seed entry carries more than one name, and they should not be confused. The catalog id is the tool's internal key, while the wire name is the canonical LLMTR identifier actually sent in the request. Alongside those sit a descriptor id and an optional list of aliases.
The aliases exist as a fix. The source comment explains that the function checking model support matches on the wire name, the catalog id and the aliases, but not on the descriptor id. Without aliases, a selection made by descriptor id would not survive a relaunch. The dash-spelled counterparts of dotted version numbers are in the list for exactly that reason.
| Catalog id | Wire name | Alias |
|---|---|---|
| llmtr-claude-sonnet-4.6 | anthropic/claude-sonnet-4.6 | claude-sonnet-4-6 |
| llmtr-claude-haiku-4.5 | anthropic/claude-haiku-4.5 | claude-haiku-4-5 |
| llmtr-kimi-k2.7-code | moonshot/kimi-k2.7-code | kimi-k2.7-code |
| llmtr-gemma-4 | llmtr/gemma-4 | Not defined |
| llmtr-muse-glimmer-30b-tr | llmtr/muse-glimmer-30b-tr | Not defined |
The default model and the Turkey-hosted routes
A global passthrough route is chosen as the default. The comment in the source justifies it: the gateway is multi-vendor, so on a fresh setup a broadly available route is the more reasonable starting point. The Turkey-hosted routes, the ones carrying the llmtr prefix, stay one selection away in the picker.
Making that distinction deliberately at setup time pays off. Passthrough routes bring vendor variety and familiar behaviour, while llmtr-prefixed routes run on LLMTR's own infrastructure and are what separates this gateway from a generic proxy. The seed list carries the gemma and muse glimmer entries from that second group; the catalog holds further llmtr routes and discovery brings those in as well.
The preset section also declares a model environment variable and tags the vendor id as openai. That tag records which compatible path the tool follows; it does not change where the key is read from, because the credential isolation flag stands separately.
What the record does not offer: usage reporting
The last field of the record marks usage reporting as unsupported. Do not expect token consumption or a spend summary for this gateway inside the OpenClaude interface. Billing is token based, so teams that want to watch consumption need to follow it from the dashboard side; the tool will not surface it.
After finishing setup, check two things in order. First the startup readiness probe, which calls the model list endpoint: if nothing comes back, the base URL or the network path is at fault. Then the first model selection: if the list arrives but the identifier you expected is missing, it most likely failed the three-condition filter, for instance because the route does not accept tool definitions.
- Usage reporting is off, so consumption is not visible inside the tool
- A missing key produces a message naming the variable to fill in
- If the list comes back empty, probe the base URL and network access first
- If an expected model is absent, verify its tool support condition
Frequently asked questions
I cannot find the LLMTR entry in the official OpenClaude build, why?
Because the change was not merged upstream. The entry lives in the knowhycodata/openclaude repository on the feat/add-llmtr-provider branch, in the file src/integrations/gateways/llmtr.ts. To try it you need to take that branch and run your own copy.
Why is my existing OpenAI key not used?
The record is configured to read only its own credential variable, and the fallback to a generic key is explicitly disabled. The reason is written in the source: otherwise a credential held for another provider would be sent to this gateway. Put the key in the LLMTR_API_KEY variable.
Why are some catalog models missing from the picker?
The discovery mapping looks for three conditions: the model must support the chat completions operation, expose the same endpoint, and accept the tool definitions parameter. Embedding, image, audio and video routes do not pass that filter because they cannot serve a coding agent session.
Why does my model selection survive a restart?
That is what the aliases in the seed entries are for. The function checking model support matches on the wire name, the catalog id and the aliases, but not on the descriptor id. As long as an alias is defined, a selection made by descriptor id is still recognised after a relaunch.