Skip to main content

llm-transport

Run a prompt through the claude CLI in print mode, or straight through the Anthropic Messages API - directly, or via a LiteLLM gateway in front of Bedrock, Vertex and the rest - with one environment switch and one result shape.

import llm_transport

env = llm_transport.run(
    "Read notes.md and reply with a one-line summary.",
    cwd=".",
    allowed_tools="Read,Grep,Glob",
)
if env["is_error"]:
    raise RuntimeError(env["result"])
print(env["result"], env["total_cost_usd"], env["num_turns"])

env is the JSON envelope claude -p --output-format json prints (result, is_error, subtype, stop_reason, api_error_status, num_turns, usage, total_cost_usd) plus a warnings list - in both modes. Code that already parses the CLI's output can switch transport without touching its error handling.

Install

pip install llm-transport              # CLI mode only: no dependencies
pip install "llm-transport[anthropic]" # adds the anthropic SDK for API mode

Python 3.12+.

Configuration

Variable Default Meaning
LLM_USE_API unset → CLI 1 / true / yes / on → the Messages API. Anything else, blank or unset → claude -p.
LLM_API_URL ANTHROPIC_BASE_URL, else https://api.anthropic.com Base URL. A LiteLLM gateway URL works as is: LiteLLM serves /v1/messages natively.
LLM_API_KEY ANTHROPIC_API_KEY Sent as x-api-key.
LLM_MODEL ANTHROPIC_MODEL, else claude-opus-5-5 Model id, or the gateway's alias for it.
LLM_EFFORT high output_config.effort. Set it blank to omit the field for a gateway that rejects it.
LLM_MAX_TOKENS 32000 Per response (requests stream, so large values are safe).
LLM_MAX_TURNS 40 Tool-loop turns per call.
LLM_REQUEST_RETRIES 4 SDK retries of one request on 408/409/429/5xx.
LLM_CA_BUNDLE SSL_CERT_FILE, else REQUESTS_CA_BUNDLE TLS trust for a gateway with a private CA.
LLM_PRICE_INPUT_PER_MTOK, LLM_PRICE_OUTPUT_PER_MTOK - USD per million tokens, for a model the price table does not know.
LLM_WEB_SEARCH_TOOL by model Override the server web-search tool type.
CLAUDE_BIN claude CLI mode: the executable, or a quoted multi-token command.

LLM_API_KEY and LLM_API_URL drive both transports: in CLI mode they are passed to claude as ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL, unless those are already set.

Why the Anthropic Messages format, not OpenAI's

Behind LiteLLM you could speak the OpenAI chat format instead. This package doesn't, because for Claude that format drops what matters most in a tool loop: prompt caching (cache_control), which keeps a turn from re-paying for the whole prompt; thinking blocks, which must go back unchanged between tool turns; server-side web search; effort; refusal details; and cache token accounting.

Tools in API mode

Grants use the CLI's own --allowed-tools / --disallowed-tools / --tools syntax and meaning, so one grant string works in both modes:

llm_transport.run(prompt, cwd=repo,
                  allowed_tools="Read,Grep,Bash(python scripts/lookup.py*),WebFetch,WebSearch",
                  disallowed_tools="Write,Edit",
                  tools=None)   # None: derive from the grant; "": no tools at all
Tool API-mode behaviour
Read, Grep, Glob Same input fields as Claude Code. Confined to cwd, $RUN_DIR (from env) and any read_roots.
Bash(<prefix>*) Runs only commands that start with the prefix, without a shell: pipes, redirects, ;, &&, backticks and $(...) are refused. python maps to the current interpreter. A bare Bash grant is not honoured.
WebFetch GET through fetch(url) -> (status, text) - default default_fetch, which converts HTML to text and refuses any blocked_hosts you pass.
WebSearch Anthropic's server-side search tool. Where the endpoint rejects it (e.g. Bedrock behind LiteLLM) the call continues without it and says so in warnings.

Deny beats allow. Tools the CLI has but API mode does not (Write, Edit, ...) are left out with a note in warnings. In API mode this package is the permission boundary; in CLI mode the CLI is.

API mode does not load .claude/rules/, CLAUDE.md or skills the way the CLI does from its working directory. Inline what the prompt needs.

Limits and cost

llm_transport.run(prompt, cwd=".", timeout_s=900, max_usd=2.0)
  • timeout_s bounds the call (CLI: the process tree is killed; API: checked between turns and as the request timeout).
  • max_usd is --max-budget-usd in CLI mode (dropped, and listed in dropped_flags, if the installed build lacks it) and is checked between turns in API mode, ending with subtype: "error_max_budget_usd".
  • total_cost_usd in API mode is LiteLLM's x-litellm-response-cost when the gateway sends it, otherwise an estimate at first-party list prices (llm_transport.PRICES). Bedrock and Vertex bill at their own rates. A model the table cannot price is recorded at $0 with a warning.

Errors

run, run_api and run_cli never raise on a model or transport failure: the envelope has is_error: true, api_error_status (HTTP status, when there was one) and a readable result such as API error 401: authentication_error: .... Classify on those. Lower-level pieces (run_cli_raw, spawn_kwargs, kill_process_tree, cli_env) are public for callers that drive the CLI themselves.

License

MIT

Metadata

Release files for llm-transport 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llm-transport 0.1.0
File Size Uploaded
llm_transport-0.1.0.tar.gz 24.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for llm-transport 0.1.0
File Interpreter ABI Platform
llm_transport-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.4 kB

Release files / llm_transport-0.1.0.tar.gz

Download URL llm_transport-0.1.0.tar.gz
Size 24.1 kB
Tags Source
SHA-256 checksum
How to use checksums
b8a49e97722876bc83f4abe996e9ca01765e723f9fed2741f0de0c7ea6410143
BLAKE2b-256 checksum
How to use checksums
2a472cb4507727fa8a424fc6675ade54548d304d2c6dea9c3d5c3ec9a79e1121
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / llm_transport-0.1.0-py3-none-any.whl

Download URL llm_transport-0.1.0-py3-none-any.whl
Size 22.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8b6478380df89bf7a3ed7a601ab60d77025d2541f46b6e416f9d282efc8d3a06
BLAKE2b-256 checksum
How to use checksums
0c72c46db869b608386eeba33913e940f1d6dde1c1dbf9698551662609399190
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page