Providers
tm routes turns through a provider fabric with twenty-one backends. Run tm provider detect (add
--json for machine-readable output) to see which are configured in your environment, tm provider list
for the role-to-candidate routing from the project’s providers.toml, and tm provider test <slug> for a
real (potentially billed) smoke test.
tm init scaffolds providers.toml (provider role routing) and a separate harness.toml (harness
behavior). A generated providers.toml follows the environment: if DEVPASS_* is set, coder.fast
routes to DevPass; a hand-edited file is never touched. tm provider reset regenerates it (keeping the old
one as providers.toml.bak). Local model names are never guessed; select one with /model <provider>/<model>.
A providers.toml role candidate may name any slug below:
coderfast
candidates = [
{ provider = "openai", model = "gpt-4o-mini", max_concurrency = 20 },
]Anthropic🔗
- Slug:
anthropic - Env vars:
ANTHROPIC_API_KEY(required) - Base URL:
https://api.anthropic.com - Free tier: no
- Capabilities: completion, streaming, tool use
OpenAI🔗
- Slug:
openai - Env vars:
OPENAI_API_KEY(required);OPENAI_BASE_URL,OPENAI_ORGANIZATION,OPENAI_PROJECT(optional) - Base URL:
https://api.openai.com/v1 - Free tier: no (new-account trial credit only, not a standing free tier)
- Capabilities: completion, embedding, streaming, tool use
- Known gap: reasoning-model families (
o1/o3/gpt-5-style) requiremax_completion_tokensinstead ofmax_tokens; the shared compat core always sendsmax_tokens, so those specific models are not correctly reachable through this backend yet (see the module’s own doc comment).
OpenRouter🔗
- Slug:
openrouter - Env vars:
OPENROUTER_API_KEY(required);OPENROUTER_BASE_URL,OPENROUTER_HTTP_REFERER,OPENROUTER_APP_TITLE(optional) - Base URL:
https://openrouter.ai/api/v1 - Free tier: yes — several
:free-suffixed routed models - Capabilities: completion, streaming, tool use
GitHub Models🔗
- Slug:
github-models - Env vars:
GITHUB_TOKEN(required — a GitHub PAT or Actions token scoped for GitHub Models, orGITHUB_MODELS_TOKEN);GITHUB_MODELS_BASE_URL(optional) - Base URL:
https://models.github.ai/inference - Free tier: yes — free within GitHub-imposed per-model rate limits
- Capabilities: completion, streaming, tool use
Groq🔗
- Slug:
groq - Env vars:
GROQ_API_KEY(required);GROQ_BASE_URL(optional) - Base URL:
https://api.groq.com/openai/v1 - Free tier: yes — free developer tier with rate limits
- Capabilities: completion, streaming, tool use
Cerebras🔗
- Slug:
cerebras - Env vars:
CEREBRAS_API_KEY(required);CEREBRAS_BASE_URL(optional) - Base URL:
https://api.cerebras.ai/v1 - Free tier: yes — free tier with daily request/token caps
- Capabilities: completion, streaming, tool use
DeepSeek🔗
- Slug:
deepseek - Env vars:
DEEPSEEK_API_KEY(required);DEEPSEEK_BASE_URL(optional) - Base URL:
https://api.deepseek.com - Free tier: no (pay-as-you-go only)
- Capabilities: completion, streaming, tool use
Mistral🔗
- Slug:
mistral - Env vars:
MISTRAL_API_KEY(required);MISTRAL_BASE_URL(optional) - Base URL:
https://api.mistral.ai/v1 - Free tier: yes — a rate-limited free “La Plateforme” experiment tier
- Capabilities: completion, embedding, streaming, tool use
xAI🔗
- Slug:
xai - Env vars:
XAI_API_KEY(required);XAI_BASE_URL(optional) - Base URL:
https://api.x.ai/v1 - Free tier: no (new-account trial credit only)
- Capabilities: completion, streaming, tool use
Together AI🔗
- Slug:
together - Env vars:
TOGETHER_API_KEY(required);TOGETHER_BASE_URL(optional) - Base URL:
https://api.together.xyz/v1 - Free tier: yes — a handful of always-free serverless models
- Capabilities: completion, embedding, streaming, tool use
Fireworks AI🔗
- Slug:
fireworks - Env vars:
FIREWORKS_API_KEY(required);FIREWORKS_BASE_URL(optional) - Base URL:
https://api.fireworks.ai/inference/v1 - Free tier: yes — new-account free credit, not a standing free tier
- Capabilities: completion, embedding, streaming, tool use
Hugging Face🔗
- Slug:
huggingface - Env vars:
HF_TOKEN(required);HF_BASE_URL(optional) - Base URL:
https://router.huggingface.co/v1 - Free tier: yes — rate-limited free inference for many hosted models
- Capabilities: completion, streaming (no tool use through this router)
Google Gemini🔗
- Slug:
gemini - Env vars:
GEMINI_API_KEY(required, falls back toGOOGLE_API_KEYif unset);GOOGLE_API_KEY(optional fallback name);GEMINI_BASE_URL(optional) - Base URL:
https://generativelanguage.googleapis.com/v1beta - Free tier: yes — a free tier with per-model rate limits
- Capabilities: completion, embedding, streaming, tool use
Ollama (local)🔗
- Slug:
ollama - Env vars:
OLLAMA_HOST(optional, all env vars optional — see caveat below) - Base URL:
http://localhost:11434 - Free tier: yes — runs entirely locally, no API key
- Capabilities: completion, embedding, streaming, tool use
- No guessed default model: select a pulled model explicitly, for example
/model ollama/qwen2.5-coder. - Caveat: since every one of this backend’s env vars is optional,
ProviderInfo::is_configured()always reports it as “configured”, regardless of whether an Ollama server is actually reachable at the configured host. Autodetection here means “constructible”, not “reachable”; confirming reachability needs an actual probe (tm provider test), notRegistry::autodetect().
LM Studio (local)🔗
- Slug:
lm-studio - Env vars:
LM_STUDIO_HOST(optional) - Base URL:
http://localhost:1234 - Free tier: yes — runs entirely locally, no API key
- Capabilities: completion, embedding, streaming, tool use
- No guessed default model: select a model exposed by LM Studio explicitly.
- Same “configured means constructible, not reachable” caveat as Ollama above.
llama.cpp (local)🔗
- Slug:
llama-cpp - Env vars:
LLAMA_CPP_HOST(optional);LLAMA_CPP_API_KEY(optional, only needed ifllama-serverwas started with--api-key) - Base URL:
http://localhost:8080 - Free tier: yes — runs entirely locally, no API key required by default
- Capabilities: completion, embedding, streaming, tool use
- No guessed default model: select the model served by
llama-serverexplicitly. - Same “configured means constructible, not reachable” caveat as Ollama above.
Azure OpenAI🔗
- Slug:
azure-openai - Env vars:
AZURE_OPENAI_API_KEY(required);AZURE_OPENAI_ENDPOINT(required, e.g.https://<resource>.openai.azure.com, no path);AZURE_OPENAI_DEPLOYMENT(required, the deployment name, not the underlying model id);AZURE_OPENAI_API_VERSION(optional, default2024-10-21) - Free tier: no (Azure subscription required; some free credit programs exist but no standing free tier)
- Capabilities: completion, embedding, streaming, tool use
AWS Bedrock🔗
- Slug:
bedrock - Env vars:
AWS_ACCESS_KEY_ID(required);AWS_SECRET_ACCESS_KEY(required);AWS_SESSION_TOKEN(optional, for temporary credentials);AWS_REGION(required, e.g.us-east-1);BEDROCK_MODEL_ID(required, Bedrock’s own model id string) - Free tier: no (AWS subscription required)
- Capabilities: completion, streaming (no tool use, no embedding through this module)
Google Vertex AI🔗
- Slug:
vertex - Env vars:
VERTEX_ACCESS_TOKEN(required — a pre-minted OAuth2 bearer token; service-account token minting is not implemented by this module);VERTEX_PROJECT(required, GCP project id);VERTEX_LOCATION(required, e.g.us-central1) - Free tier: no (GCP subscription required; GCP’s general free-credit programs are not a Vertex-specific standing free tier)
- Capabilities: completion, embedding, tool use — not streaming (this module’s
completealways sends a non-streaming request; see the module’s own doc comment for why)
Cloudflare Workers AI🔗
- Slug:
cloudflare - Env vars:
CF_API_TOKEN(required, scoped for Workers AI);CF_ACCOUNT_ID(required, part of the URL path) - Base URL:
https://api.cloudflare.com/client/v4/accounts/<CF_ACCOUNT_ID>/ai/v1(built fromCF_ACCOUNT_ID, not overridable — there is noCF_BASE_URL) - Free tier: yes — a daily free-usage allotment per Cloudflare account
- Capabilities: completion, embedding, streaming, tool use
DevPass (generic OpenAI-compatible)🔗
- Slug:
devpassoverCompatProvider::from_env_prefix) - Env vars:
DEVPASS_API_KEY(required);DEVPASS_BASE_URL(required, no trailing slash);DEVPASS_MODEL(required — the default model; a request routed to anotherdevpasscandidate, or a/model devpass/<name>choice, is served by that model instead) - Free tier: depends entirely on the operator-controlled gateway this points at
- Capabilities: completion, embedding, streaming, tool use
CompatProvider::from_env_prefixitself (not registered under its own slug) is the generic half of this backend: any other bespoke OpenAI-compatible endpoint can reuse it with a new env var prefix without writing a new module.
DevPass as the default provider🔗
When DEVPASS_API_KEY, DEVPASS_BASE_URL and DEVPASS_MODEL are all set to non-empty
values, DevPass becomes the default provider for coder.fast — the one role tm’s interactive
session (bare tm, tm -p <prompt>) and its scheduler dispatcher (tm run/tm sched run)
actually drive an agent-loop turn as. Concretely:
RoleTable::default_table’scoder.fastprimary candidate becomesdevpass/$DEVPASS_MODELinstead ofanthropic/claude-sonnet-5; the existing Anthropic fallback candidate is left in place, untouched.crates/tm-cli/src/agent.rs’sbuild_fabricregisters aDevPassProviderinstead of requiringANTHROPIC_API_KEY— this is the point of the feature: a real end-to-endtmsession can run against a cheap/free OpenAI-compatible backend without touching Anthropic quota or needing an Anthropic account at all.AnthropicProvider::from_envis still attempted best-effort in this mode (registered if it happens to succeed, silently skipped if not), so any other role a ticket names still gets Anthropic service if a key also happens to be present.- A partial set of the three env vars (e.g. only
DEVPASS_API_KEY) does not activate this preference at all — it falls straight through to the unchanged, Anthropic-only default. There is no half-activated state. - This does not touch any other role:
vision.frontier/planner.frontier/architect.frontier(tm genesis’s bootstrap stages, resolved through a separate, Anthropic-only provider-selection path — seecrates/tm-cli/src/project.rs’sresolve_genesis_provider) andembedder(background indexing) are all unaffected, on purpose: genesis’s own resolution hardcodesAnthropicProviderregardless of what a candidate’sproviderslug names, so pointing a frontier role’s default atdevpassthere would silently misconstruct a provider rather than actually use DevPass; embedding needs a model that actually serves embeddings, which a DevPass-testing model is not guaranteed to. - Absent all three env vars, behavior is byte-for-byte unchanged from before this feature existed.
See docs/decisions/D-005-devpass-default-provider.md for the reasoning and what this does not
cover.
Free-tier summary🔗
| Slug | Free tier |
|---|---|
anthropic | no |
openai | no |
openrouter | yes |
github-models | yes |
groq | yes |
cerebras | yes |
deepseek | no |
mistral | yes |
xai | no |
together | yes |
fireworks | yes (new-account credit) |
huggingface | yes |
gemini | yes |
ollama | yes (local) |
lm-studio | yes (local) |
llama-cpp | yes (local) |
azure-openai | no |
bedrock | no |
vertex | no |
cloudflare | yes |
devpass | depends on the operator’s gateway |
Free-tier claims above are as of this document’s writing and are not verified against each vendor’s live terms by this crate; treat them as a starting point for choosing a role’s fallback candidates, not a billing guarantee.