Liter-LLM Universal LLM Client
Liter-LLM is a universal LLM API client with a Rust core and native bindings for
Python, TypeScript/Node.js, Go, Java, C#, Ruby, PHP, Elixir, WebAssembly, and C
(FFI). One unified interface reaches 165 providers (OpenAI, Anthropic, Google
Gemini, Groq, Mistral, Cohere, AWS Bedrock, Azure, and many more).
Capability map
- Modalities — chat completions, streaming, tool/function calling,
structured outputs, embeddings, image generation, audio (speech,
transcription), moderation, web search, OCR, reranking, batch,
and file operations.
- Provider routing —
provider/model prefix selects the backend
(openai/gpt-4o, anthropic/claude-sonnet-4-20250514,
gemini/gemini-2.0-flash). Set model_hint to skip the prefix.
- Middleware — response caching, rate limiting (RPM/TPM), cost tracking,
budget enforcement (
hard / soft), fallback chains, circuit-breaker
cooldown, and background health checks.
- Search providers (12) and OCR providers (4) — first-class
search
and ocr methods routed by the same prefix convention.
- Proxy server —
liter-llm api exposes an OpenAI-compatible gateway with
22 REST endpoints, virtual API keys, budgets, and SSE streaming.
- MCP server —
liter-llm mcp exposes 22 tools mirroring the proxy
endpoints, for MCP-compatible clients (Claude Code, Claude Desktop).
- 14 language bindings — same surface, language-native naming (snake_case
for Python/Rust/Ruby/Go/Elixir/PHP, camelCase for TS/Node/WASM/C#/Java).
When to use the MCP server vs the SDK vs the proxy
| Use the … |
When you want to … |
Entry point |
| MCP server |
Let the agent call LLM APIs directly as tools, with no glue code |
liter-llm mcp --transport stdio (this plugin auto-registers it) |
| SDK / binding |
Write application code that calls LLMs in a specific language |
pip install liter-llm, cargo add liter-llm, etc. |
| Proxy |
Give many apps/teams a shared OpenAI-compatible endpoint with keys, budgets, and rate limits |
liter-llm api --config liter-llm-proxy.toml |
Rule of thumb: reach for the MCP server inside an agent session; the SDK when
building software; the proxy when centralizing access for multiple consumers.
Installation
CLI (proxy + MCP server)
# Homebrew (macOS / Linux)
brew install xberg-io/tap/liter-llm
# or run it without a persistent install (the CLI proxy package self-installs the binary)
npx @xberg-io/liter-llm-cli --help
uvx --from liter-llm-cli liter-llm --help
# or download a prebuilt binary from the latest GitHub release:
# https://github.com/xberg-io/liter-llm/releases/latest
# or build from source
cargo install liter-llm-cli
# or Docker (35MB image)
docker pull ghcr.io/xberg-io/liter-llm
Language bindings
| Language |
Install |
| Python |
pip install liter-llm |
| Node.js |
pnpm add @xberg-io/liter-llm |
| Rust |
cargo add liter-llm |
| Go |
go get github.com/xberg-io/liter-llm/packages/go/v2 |
| Ruby |
gem install liter_llm |
| PHP |
composer require xberg-io/liter-llm |
| C# |
dotnet add package XbergIo.LiterLlm |
| WASM |
pnpm add @xberg-io/liter-llm-wasm |
Quick start (Python, async)
import asyncio
import os
from liter_llm import create_client
from liter_llm._internal_bindings import ChatCompletionRequest
async def main() -> None:
client = create_client(api_key=os.environ["OPENAI_API_KEY"])
request = ChatCompletionRequest.from_json(
'{"model":"openai/gpt-4o","messages":[{"role":"user","content":"Hello!"}]}'
)
response = await client.chat(request)
print(response.choices[0].message.content)
asyncio.run(main())
Provider routing
The prefix before / in the request's model selects the provider:
ChatCompletionRequest.from_json('{"model":"openai/gpt-4o","messages":[...]}')
ChatCompletionRequest.from_json('{"model":"anthropic/claude-sonnet-4-20250514","messages":[...]}')
ChatCompletionRequest.from_json('{"model":"gemini/gemini-2.0-flash","messages":[...]}')
ChatCompletionRequest.from_json('{"model":"groq/llama3-70b","messages":[...]}')
API keys come from environment variables: OPENAI_API_KEY, ANTHROPIC_API_KEY,
GEMINI_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, CO_API_KEY, and AWS
credentials for Bedrock.
Configuration
Pass basic options to create_client(...) (api_key, base_url,
timeout_secs, max_retries, model_hint), or set the full surface in a
liter-llm.toml (SDK) / liter-llm-proxy.toml (proxy) — both auto-discover
from the cwd upward.
# liter-llm.toml
api_key = "${OPENAI_API_KEY}"
model_hint = "openai"
timeout_secs = 120
max_retries = 5
[cache]
max_entries = 512
ttl_seconds = 600
[budget]
global_limit = 50.0
enforcement = "hard"
[rate_limit]
rpm = 60
tpm = 100000
| Option |
Default |
Description |
api_key |
required |
Provider key, wrapped in SecretString (never logged). |
base_url |
from registry |
Override the provider base URL. |
model_hint |
none |
Pre-resolve a provider, skipping the prefix lookup. |
timeout_secs |
60 |
Request timeout in seconds. |
max_retries |
3 |
Retries on 429/5xx with exponential backoff. |
cache |
none |
max_entries, ttl_seconds. |
budget |
none |
global_limit, model_limits, enforcement. |
rate_limit |
none |
rpm, tpm. |
cost_tracking |
false |
Per-request cost tracking. |
tracing |
false |
OpenTelemetry spans. |
Proxy server
liter-llm api --config liter-llm-proxy.toml
22 OpenAI-compatible endpoints, model routing by prefix, virtual API keys,
per-key RPM/TPM limits, cost tracking, budget enforcement, response caching, SSE
streaming, and an OpenAPI 3.1 spec at /openapi.json.
MCP server
liter-llm mcp --transport stdio # for Claude Code / Claude Desktop
liter-llm mcp --transport http --port 3001
This plugin auto-registers the stdio server via scripts/mcp-launch.sh. The 22
tools mirror the proxy endpoints: chat, embed, generate_image, speech,
transcribe, moderate, rerank, search, ocr, list_models; file ops
(create_file, list_files, retrieve_file, delete_file, file_content);
batch ops (create_batch, list_batches, retrieve_batch, cancel_batch);
and Responses API (create_response, retrieve_response, cancel_response).
Common pitfalls
- Provider prefix is required — use
"provider/model" unless model_hint
is set, or routing fails.
- API keys are SecretString — never logged or serialized. Read from env
vars; never hardcode.
- Python methods are async —
await inside an async context.
- Naming conventions differ — camelCase for TS/Node/WASM/C#/Java,
snake_case elsewhere.
- Streaming chunks may have null content — null-check
chunk.choices[0].delta.content before use.
- Budget modes —
hard rejects over-budget requests; soft logs and
allows.
Additional resources
1---2name: liter-llm-23description: Universal LLM API client for 165 providers with native bindings for 14 languages. Use when writing code that calls LLM APIs via liter-llm in Python, TypeScript, Rust, Go, Java, C#, Ruby, PHP, Elixir, WASM, or C, when running the OpenAI-compatible proxy, or when calling LLMs through the MCP server. Covers chat, streaming, tool calling, embeddings, image generation, speech, transcription, moderation, web search, OCR, reranking, provider routing, middleware, and configuration.4license: MIT5---67# Liter-LLM Universal LLM Client89Liter-LLM is a universal LLM API client with a Rust core and native bindings for10Python, TypeScript/Node.js, Go, Java, C#, Ruby, PHP, Elixir, WebAssembly, and C11(FFI). One unified interface reaches 165 providers (OpenAI, Anthropic, Google12Gemini, Groq, Mistral, Cohere, AWS Bedrock, Azure, and many more).1314## Capability map1516- **Modalities** — chat completions, streaming, tool/function calling,17 structured outputs, embeddings, image generation, audio (speech,18 transcription), moderation, web search, OCR, reranking, batch,19 and file operations.20- **Provider routing** — `provider/model` prefix selects the backend21 (`openai/gpt-4o`, `anthropic/claude-sonnet-4-20250514`,22 `gemini/gemini-2.0-flash`). Set `model_hint` to skip the prefix.23- **Middleware** — response caching, rate limiting (RPM/TPM), cost tracking,24 budget enforcement (`hard` / `soft`), fallback chains, circuit-breaker25 cooldown, and background health checks.26- **Search providers (12)** and **OCR providers (4)** — first-class `search`27 and `ocr` methods routed by the same prefix convention.28- **Proxy server** — `liter-llm api` exposes an OpenAI-compatible gateway with29 22 REST endpoints, virtual API keys, budgets, and SSE streaming.30- **MCP server** — `liter-llm mcp` exposes 22 tools mirroring the proxy31 endpoints, for MCP-compatible clients (Claude Code, Claude Desktop).32- **14 language bindings** — same surface, language-native naming (snake_case33 for Python/Rust/Ruby/Go/Elixir/PHP, camelCase for TS/Node/WASM/C#/Java).3435## When to use the MCP server vs the SDK vs the proxy3637| Use the … | When you want to … | Entry point |38|-----------|--------------------|-------------|39| **MCP server** | Let the agent call LLM APIs directly as tools, with no glue code | `liter-llm mcp --transport stdio` (this plugin auto-registers it) |40| **SDK / binding** | Write application code that calls LLMs in a specific language | `pip install liter-llm`, `cargo add liter-llm`, etc. |41| **Proxy** | Give many apps/teams a shared OpenAI-compatible endpoint with keys, budgets, and rate limits | `liter-llm api --config liter-llm-proxy.toml` |4243Rule of thumb: reach for the MCP server inside an agent session; the SDK when44building software; the proxy when centralizing access for multiple consumers.4546## Installation4748### CLI (proxy + MCP server)4950```bash51# Homebrew (macOS / Linux)52brew install xberg-io/tap/liter-llm5354# or run it without a persistent install (the CLI proxy package self-installs the binary)55npx @xberg-io/liter-llm-cli --help56uvx --from liter-llm-cli liter-llm --help5758# or download a prebuilt binary from the latest GitHub release:59# https://github.com/xberg-io/liter-llm/releases/latest6061# or build from source62cargo install liter-llm-cli6364# or Docker (35MB image)65docker pull ghcr.io/xberg-io/liter-llm66```6768### Language bindings6970| Language | Install |71|----------|---------|72| Python | `pip install liter-llm` |73| Node.js | `pnpm add @xberg-io/liter-llm` |74| Rust | `cargo add liter-llm` |75| Go | `go get github.com/xberg-io/liter-llm/packages/go/v2` |76| Ruby | `gem install liter_llm` |77| PHP | `composer require xberg-io/liter-llm` |78| C# | `dotnet add package XbergIo.LiterLlm` |79| WASM | `pnpm add @xberg-io/liter-llm-wasm` |8081## Quick start (Python, async)8283```python84import asyncio85import os86from liter_llm import create_client87from liter_llm._internal_bindings import ChatCompletionRequest8889async def main() -> None:90 client = create_client(api_key=os.environ["OPENAI_API_KEY"])91 request = ChatCompletionRequest.from_json(92 '{"model":"openai/gpt-4o","messages":[{"role":"user","content":"Hello!"}]}'93 )94 response = await client.chat(request)95 print(response.choices[0].message.content)9697asyncio.run(main())98```99100## Provider routing101102The prefix before `/` in the request's `model` selects the provider:103104```python105ChatCompletionRequest.from_json('{"model":"openai/gpt-4o","messages":[...]}')106ChatCompletionRequest.from_json('{"model":"anthropic/claude-sonnet-4-20250514","messages":[...]}')107ChatCompletionRequest.from_json('{"model":"gemini/gemini-2.0-flash","messages":[...]}')108ChatCompletionRequest.from_json('{"model":"groq/llama3-70b","messages":[...]}')109```110111API keys come from environment variables: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`,112`GEMINI_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, `CO_API_KEY`, and AWS113credentials for Bedrock.114115## Configuration116117Pass basic options to `create_client(...)` (`api_key`, `base_url`,118`timeout_secs`, `max_retries`, `model_hint`), or set the full surface in a119`liter-llm.toml` (SDK) / `liter-llm-proxy.toml` (proxy) — both auto-discover120from the cwd upward.121122```toml123# liter-llm.toml124api_key = "${OPENAI_API_KEY}"125model_hint = "openai"126timeout_secs = 120127max_retries = 5128129[cache]130max_entries = 512131ttl_seconds = 600132133[budget]134global_limit = 50.0135enforcement = "hard"136137[rate_limit]138rpm = 60139tpm = 100000140```141142| Option | Default | Description |143|--------|---------|-------------|144| `api_key` | required | Provider key, wrapped in `SecretString` (never logged). |145| `base_url` | from registry | Override the provider base URL. |146| `model_hint` | none | Pre-resolve a provider, skipping the prefix lookup. |147| `timeout_secs` | 60 | Request timeout in seconds. |148| `max_retries` | 3 | Retries on 429/5xx with exponential backoff. |149| `cache` | none | `max_entries`, `ttl_seconds`. |150| `budget` | none | `global_limit`, `model_limits`, `enforcement`. |151| `rate_limit` | none | `rpm`, `tpm`. |152| `cost_tracking` | false | Per-request cost tracking. |153| `tracing` | false | OpenTelemetry spans. |154155## Proxy server156157```bash158liter-llm api --config liter-llm-proxy.toml159```16016122 OpenAI-compatible endpoints, model routing by prefix, virtual API keys,162per-key RPM/TPM limits, cost tracking, budget enforcement, response caching, SSE163streaming, and an OpenAPI 3.1 spec at `/openapi.json`.164165## MCP server166167```bash168liter-llm mcp --transport stdio # for Claude Code / Claude Desktop169liter-llm mcp --transport http --port 3001170```171172This plugin auto-registers the stdio server via `scripts/mcp-launch.sh`. The 22173tools mirror the proxy endpoints: `chat`, `embed`, `generate_image`, `speech`,174`transcribe`, `moderate`, `rerank`, `search`, `ocr`, `list_models`; file ops175(`create_file`, `list_files`, `retrieve_file`, `delete_file`, `file_content`);176batch ops (`create_batch`, `list_batches`, `retrieve_batch`, `cancel_batch`);177and Responses API (`create_response`, `retrieve_response`, `cancel_response`).178179## Common pitfalls1801811. **Provider prefix is required** — use `"provider/model"` unless `model_hint`182 is set, or routing fails.1832. **API keys are SecretString** — never logged or serialized. Read from env184 vars; never hardcode.1853. **Python methods are async** — `await` inside an async context.1864. **Naming conventions differ** — camelCase for TS/Node/WASM/C#/Java,187 snake_case elsewhere.1885. **Streaming chunks may have null content** — null-check189 `chunk.choices[0].delta.content` before use.1906. **Budget modes** — `hard` rejects over-budget requests; `soft` logs and191 allows.192193## Additional resources194195- Upstream docs: <https://docs.liter-llm.xberg.io>196- GitHub: <https://github.com/xberg-io/liter-llm>