A Meridian model provider for Strands Agents. Run your Strands agents on your Claude Max subscription quota instead of per-token API billing — by pointing the standard Anthropic model provider at a local Meridian proxy.
A community model-provider extension for Strands Agents. Not affiliated with, sponsored by, or endorsed by Anthropic or AWS.
from strands import Agent
from strands_meridian import MeridianModel
agent = Agent(model=MeridianModel())
agent("Hello from my Claude Max quota")Meridian is a local proxy that bridges the Claude Code SDK to the standard Anthropic Messages API (POST /v1/messages). It runs on http://127.0.0.1:3456 and authenticates through your Claude Code login, so requests draw from your Claude Max subscription — no API key required.
strands-meridian is a thin wrapper around Strands' AnthropicModel. The only thing it changes is the client transport: base_url points at Meridian and api_key is a harmless placeholder. Because Meridian speaks the native Anthropic protocol, prompt caching, structured output, streaming, and extended thinking all keep working — your Max quota is used efficiently.
Strands Agent ──► MeridianModel (AnthropicModel) ──► http://127.0.0.1:3456 ──► Claude Code SDK ──► Claude Max
MeridianModel is a real Strands model provider — it subclasses AnthropicModel, which itself implements strands.models.model.Model, so it satisfies the exact same provider contract (stream, structured_output, format_request, …) as a from-scratch provider like strands-mlx. The difference: MLX is local inference with no compatible endpoint, so it implements that contract by hand; Meridian is an Anthropic-compatible endpoint, so the correct path is to inherit the implementation and only override the transport — caching/streaming/structured-output come for free.
Install and start Meridian, and log in once:
npm install -g @rynfar/meridian
claude login # one-time: stores Claude Code credentials
meridian # starts the proxy on http://127.0.0.1:3456Verify it's up: curl http://127.0.0.1:3456/health (or python -m strands_meridian.meridian).
pip install strands-meridianfrom strands import Agent
from strands_meridian import MeridianModel
# Defaults: base_url=http://127.0.0.1:3456, model=claude-opus-4-8
agent = Agent(model=MeridianModel())
print(agent("Summarize the theory of relativity in one sentence."))# Opus with 1M context — included with Claude Max at no extra cost.
# model_id may be positional (like strands-mlx's MLXModel("...")):
agent = Agent(model=MeridianModel("opus[1m]"))
# A full model id (works through Meridian and in direct fallback)
agent = Agent(model=MeridianModel("claude-opus-4-6", max_tokens=8192))Via Meridian you can use the aliases sonnet, opus, haiku, sonnet[1m], opus[1m], or any full Claude model id. The default is the full id claude-opus-4-8 (Claude's most capable model; 1M context is included with Claude Max) so it remains valid in direct-Anthropic fallback mode too.
Billing note: Opus 1M context is included with Claude Max. Sonnet 1M (
sonnet[1m]) is billed as Extra Usage even on Max — this is Anthropic's billing model, enforced by Meridian, not this package.
Every AnthropicModel / AnthropicConfig option passes straight through:
agent = Agent(
model=MeridianModel(
model_id="opus[1m]",
max_tokens=8192,
params={"thinking": {"type": "enabled", "budget_tokens": 4000}},
)
)MeridianModel(...) arguments take precedence over environment variables, which take precedence over the built-in defaults.
| Variable | Default | Description |
|---|---|---|
MERIDIAN_BASE_URL |
http://127.0.0.1:3456 |
Meridian proxy URL |
MERIDIAN_MODEL |
claude-opus-4-8 |
Default model id (or Meridian alias) |
MERIDIAN_MAX_TOKENS |
4096 |
Default max response tokens |
MERIDIAN_API_KEY |
(placeholder) | Only needed if you enabled Meridian's own API-key auth gate |
MERIDIAN_DIRECT |
(unset) | When truthy, use_meridian() bypasses Meridian (see below) |
ANTHROPIC_API_KEY |
(unset) | Real Anthropic key for the opt-in direct fallback |
agent = Agent(
model=MeridianModel(
base_url="http://192.168.1.10:3456", # remote Meridian host
model_id="opus[1m]",
timeout=120.0,
)
)use_meridian() is the factory form of MeridianModel, plus one extra capability: an explicit, manual escape hatch to the direct Anthropic API (per-token billed). There is no automatic fallback — switching to per-token billing is always your decision.
from strands import Agent
from strands_meridian import use_meridian
# Default: Meridian (Claude Max quota)
agent = Agent(model=use_meridian(model_id="opus[1m]"))
# Opt-in: bypass Meridian, bill per token (needs ANTHROPIC_API_KEY)
agent = Agent(model=use_meridian(direct=True, model_id="claude-opus-4-6"))You can also flip the default for a whole process with MERIDIAN_DIRECT=1 (still requires ANTHROPIC_API_KEY). In direct mode, model_id must be a real Anthropic model id — not a Meridian alias like opus.
from strands_meridian import health_check, is_available
if not is_available():
raise SystemExit("Start Meridian first: `meridian` (after `claude login`)")
info = health_check()
print(info["auth"]["loggedIn"], info["auth"].get("subscriptionType"))health_check() returns Meridian's /health JSON (status, version, auth, mode, plugin) and raises MeridianError if the proxy is unreachable. is_available() is the never-raising boolean form.
Installing the package adds a strands-meridian command:
strands-meridian health # check the proxy + auth status
strands-meridian models # list the models Meridian exposes (/v1/models)
strands-meridian chat "hello" # one-shot agent call on your Max quota
strands-meridian chat "explain X" --model "opus[1m]" --max-tokens 2048
strands-meridian --base-url http://192.168.1.10:3456 health| Name | Description |
|---|---|
MeridianModel(model_id=None, **kwargs) |
A Strands AnthropicModel pre-wired to Meridian (model_id may be positional). Drop-in model= for Agent. |
use_meridian(direct=False, **kwargs) |
Factory returning a MeridianModel, or a direct Anthropic model when direct=True. |
health_check(base_url=None, timeout=5.0) |
Query /health; returns parsed JSON or raises MeridianError. |
is_available(base_url=None, timeout=5.0) |
True/False reachability check (never raises). |
MeridianError |
Raised when Meridian is unreachable or misconfigured. |
Common keyword arguments: base_url, api_key, timeout, model_id, max_tokens, client_args, plus any AnthropicConfig key your installed strands-agents supports (params everywhere; recent versions also accept context_window_limit and use_native_token_count). use_meridian additionally accepts direct and anthropic_api_key.
- Meridian binds to
127.0.0.1by default; theapi_keyfield is a placeholder because authentication happens through the Claude Code SDK. - If you expose Meridian beyond loopback (LAN, Tailscale, Docker), enable Meridian's
MERIDIAN_API_KEYauth gate and set the matchingMERIDIAN_API_KEYhere — an unprotected network-accessible proxy is a Claude Max credential leak. - This package never logs credentials.
- Python 3.10+
strands-agentsanthropic- A running Meridian proxy + a Claude subscription (
claude login)
Apache License 2.0