Skip to content

mertozbas/strands-meridian

strands-meridian

PyPI version Python versions CI License

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")

How it works

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.

Prerequisites

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:3456

Verify it's up: curl http://127.0.0.1:3456/health (or python -m strands_meridian.meridian).

Installation

pip install strands-meridian

Quick Start

from 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."))

Pick a model

# 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.

Extended thinking, caching, and other Anthropic options

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}},
    )
)

Configuration

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() factory + optional fallback

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.

Health check

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.

CLI

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

API reference

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.

Security

  • Meridian binds to 127.0.0.1 by default; the api_key field 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_KEY auth gate and set the matching MERIDIAN_API_KEY here — an unprotected network-accessible proxy is a Claude Max credential leak.
  • This package never logs credentials.

Requirements

  • Python 3.10+
  • strands-agents
  • anthropic
  • A running Meridian proxy + a Claude subscription (claude login)

License

Apache License 2.0

Links

About

Meridian model provider for Strands Agents — run your agents on your Claude Max subscription quota

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages