BEDROCK) with three dispatch paths that cover the entire AWS-hosted catalog:
- Anthropic Messages —
anthropic.*and inference profiles (global./us./eu./apac.anthropic.*). Preserves cache markers and extended-thinking budget. - OpenAI Chat Completions —
openai.gpt-oss-*(OpenAI’s open-weights on Bedrock). - Converse API (default) — AWS’s unified schema covering everything else: Llama, Amazon Nova, Mistral, Cohere, AI21 Jamba, DeepSeek, Stability, Writer Palmyra, Moonshot Kimi, MiniMax, Qwen, Z.AI/GLM, Google Gemma, NVIDIA Nemotron, TwelveLabs Pegasus, and any provider AWS onboards next.
/switch --model listing trusts AWS-side responses from ListFoundationModels + ListInferenceProfiles 100% — there is no hardcoded allowlist. A new model on AWS shows up on the next /switch --model without a ChatCLI release.
Ideal for corporate environments that already manage billing, compliance, and access control through AWS — no need for API keys from the original providers.
Why AWS Bedrock?
No per-provider API key
~/.aws/credentials, AWS_PROFILE). Single identity across every model.AWS billing and compliance
Full catalog
VPC endpoints
BEDROCK_BASE_URL (or the AWS-native AWS_ENDPOINT_URL_BEDROCK_RUNTIME).Auto-detected family
Native embeddings
Configuration
The provider is auto-detected when ChatCLI finds valid AWS credentials (not just file existence):- Static creds in env:
AWS_ACCESS_KEY_ID - Profile selection:
AWS_PROFILE(via env var or.envfile) ~/.aws/credentialsfile with at least one non-emptyaws_access_key_id- AWS SSO: SSO profile in
~/.aws/config(detectssso_session,sso_start_url,sso_account_id) - Assume-role / credential_process: profiles with
role_arnorcredential_processin~/.aws/config - SSO token cache: presence of files in
~/.aws/sso/cache/(indicating a prioraws sso login) - Web Identity Token (EKS IRSA):
AWS_WEB_IDENTITY_TOKEN_FILE - Container Credentials (ECS):
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI/_FULL_URI
Option 1: ~/.aws/credentials (static credentials)
If you already use AWS CLI, just have a profile configured:
Option 2: AWS SSO (IAM Identity Center)
If your company uses AWS SSO, configure the profile in~/.aws/config:
~/.aws/config (via sso_session, sso_start_url, sso_account_id keys). If the SSO token expires, the error will be clear (SSOTokenProviderError) — just run aws sso login again.Important: the AWS SDK does not know which profile is “logged in”. You must indicate the profile via AWS_PROFILE (env, .env, or flag). If your SSO profile is named default, it is used automatically without AWS_PROFILE.Option 3: Environment variables (static credentials)
Option 4: IAM Role (EC2/ECS/EKS)
On AWS-native environments, nothing to configure — the SDK picks up the role automatically through IMDSv2 / webidentity. Just make sure the role has the IAM permissions below.AWS_CONTAINER_CREDENTIALS_*, AWS_WEB_IDENTITY_TOKEN_FILE, ECS_CONTAINER_METADATA_URI*).To force behavior, use:AWS_EC2_METADATA_DISABLED=true— explicitly disable IMDSCHATCLI_BEDROCK_ENABLE_IMDS=1— force enable IMDS (useful on EC2 without standard env vars)
IAM Permissions
Minimum permissions to invoke and list models. Thebedrock:InvokeModel action covers both InvokeModel (Anthropic/OpenAI) and Converse (everything else):
Bedrock Console → Model access → Request access.
Model families and schema selection
Bedrock uses different schemas depending on the model. ChatCLI has three dispatch paths and auto-detects which one to use from the model-id prefix:Manual override
To force a family regardless of the prefix (e.g. test Converse on an Anthropic model), use the env var:anthropic / claude, openai / gpt, converse / auto (case-insensitive). The env var takes precedence over prefix detection.
/switch --model lists every text-output model with on-demand inference your account has access to — Kimi K2.6, GLM 4.7, Qwen3 Coder Next, Nemotron Nano 3, anything new AWS adds — without a release on our side. If a rare ID doesn’t fit Converse, ChatCLI returns a friendly error pointing the way.New-generation Claude and the Messages endpoint (bedrock-mantle)
The newest Claude generation on Bedrock (Fable 5, Opus 5, Sonnet 5, Opus 4.8, Opus 4.7) uses dateless IDs —anthropic.claude-fable-5, anthropic.claude-opus-5, anthropic.claude-sonnet-5, anthropic.claude-opus-4-8, anthropic.claude-opus-4-7 — with no ARN-versioned IDs (...-v1:0). On the InvokeModel path (Opus 4.8/4.7) the bare dateless ID is not on-demand invokable — AWS answers “retry with the ID or ARN of an inference profile” — so ChatCLI invokes them through the global. inference profile (global.anthropic.claude-opus-4-8); the Messages-endpoint models (Opus 5, Sonnet 5, Fable 5) use the bare dateless ID.
Claude Opus 5, Claude Sonnet 5 and Claude Fable 5 have one particularity: they are served exclusively by the Claude in Amazon Bedrock endpoint — the Messages API at https://bedrock-mantle.{region}.api.aws/anthropic/v1/messages. Opus 5 and Sonnet 5 do not exist on legacy InvokeModel, and Fable 5 rejects it with 400 ValidationException: data retention mode 'default' is not available for this model (it requires 30-day data retention, available only under the Claude in Amazon Bedrock agreement). ChatCLI handles this on its own:
- The catalog flags these models with the
bedrock_mantle_onlycapability and the client routes the request through the Messages endpoint automatically —/switch --model claude-opus-5(orclaude-sonnet-5/claude-fable-5) just works. - Inference-profile IDs are canonicalized on the wire: the Messages endpoint only knows the dateless
anthropic.*IDs — sendingus.anthropic.claude-sonnet-5orglobal.anthropic.claude-fable-5verbatim returns404 not_found_error(“model does not exist”). If you pick one of those profiles in/switch(that’s what your account’sListInferenceProfileslists), ChatCLI converts it to the canonical ID (anthropic.claude-sonnet-5) before building the request. - Auth: SigV4 with the
bedrock-mantleservice name over the same credentials chain (IAM, profile, SSO), or a short-lived bearer token viaAWS_BEARER_TOKEN_BEDROCK(x-api-keyheader) for corporate environments without IAM. - Body: same shape as the first-party Messages API — the version travels in the
anthropic-versionheader (theanthropic_versionbody field is InvokeModel-only).cache_controlmarkers reach the wire unchanged, exactly as on the InvokeModel path. - Operational overrides:
BEDROCK_ANTHROPIC_ENDPOINT=mantle|invokeforces every Claude model onto either wire (gradual migration/rollback) andBEDROCK_MANTLE_BASE_URLpoints at VPC endpoints or proxies. Corporate TLS (CHATCLI_BEDROCK_CA_BUNDLEetc.) is honored.
InvokeModel by default (served by the same infrastructure as the Messages endpoint); set BEDROCK_ANTHROPIC_ENDPOINT=mantle to move them to the new endpoint too. Prerequisite for Opus 5/Sonnet 5/Fable 5: enable the model under Model access in the Bedrock console with a data retention mode selected.Inference Profiles vs. Model IDs
This is the most important detail when using Claude on Bedrock. Anthropic models from the 3.7–4.6 era (3.7, 4.x, 4.5, 4.6) do NOT accept direct on-demand invocation by base model ID (the dateless new generation — Fable 5, Opus 5, Sonnet 5, Opus 4.8/4.7 — needs no profile; see the section above). Attempting this with an older-era model returns:global.anthropic.claude-sonnet-4-5-20250929-v1:0). Claude 3 and 3.5 models still accept direct base-ID invocation and are also in the catalog.Model Listing
/switch --model queries two live sources and merges them with the static catalog:
bedrock:ListFoundationModelswithByOutputModality: TEXT— text-output models available in the region.bedrock:ListInferenceProfiles— regional/global profiles (paginated).
- Modality TEXT (server-side) — drops embedding-only and image-only models.
InferenceTypesSupportedcontainsON_DEMAND— drops base IDs that are only invokable via inference profile (Claude 3.7+/4.x and cross-region-only IDs from other providers). Those models still appear viaListInferenceProfileswithglobal./us./eu./apac.prefix.
[api] are the ones your account actually can invoke in that region. [catalog] entries are static registrations that may or may not be enabled.
Corporate Proxy and Private TLS
In corporate environments with a proxy intercepting TLS using a private CA, you may see:CHATCLI_CA_BUNDLE / CHATCLI_TLS_INSECURE_SKIP_VERIFY — they apply to every outbound connection (LLM providers, web tools, gateway, MCP), and Bedrock inherits them as fallback. The Bedrock-specific ones take precedence when both are set. See Global TLS Trust.VPC endpoints / private endpoints / custom DNS
If your company routes Bedrock through a VPC interface endpoint, an API gateway or custom DNS, point the runtime (data plane) at it withBEDROCK_BASE_URL — the same role ANTHROPIC_BEDROCK_BASE_URL plays in Claude Code:
InvokeModel/Converse), embeddings, image generation and model listing in /switch. If your control plane genuinely lives on another host — AWS VPC interface endpoints are created per service (bedrock vs bedrock-runtime), each with its own DNS name — the optional BEDROCK_CONTROL_BASE_URL overrides just the control plane (ListFoundationModels/ListInferenceProfiles). URLs must be absolute http(s) (validated at startup, fail-fast). The AWS-standard variables also work, read natively by SDK v2:
BEDROCK_BASE_URL > AWS_ENDPOINT_URL_BEDROCK_RUNTIME > AWS_ENDPOINT_URL > regional default; control plane: BEDROCK_CONTROL_BASE_URL > BEDROCK_BASE_URL > AWS_ENDPOINT_URL_BEDROCK. AWS_IGNORE_CONFIGURED_ENDPOINT_URLS=true disables the AWS-standard ones but never the BEDROCK_*_BASE_URL pair. For the new-generation Claude Messages endpoint (bedrock-mantle), use BEDROCK_MANTLE_BASE_URL — it is a different host and service.
Environment Variables
global.anthropic.claude-sonnet-4-5-20250929-v1:0
Default region: us-east-1
All these vars surface in /config providers (chat) and /config quality (embeddings). See Environment Variables for the full reference.
Observability — endpoint URL in logs
Bedrock now logs its endpoint URL on every request — parity with Anthropic, OpenAI, and Copilot. Useful for debugging credential / region / VPC endpoint / proxy issues. On init (once per session):https://bedrock-runtime.<region>.amazonaws.com). If you set AWS_ENDPOINT_URL_BEDROCK_RUNTIME (VPC endpoint), the SDK uses your override — the log shows the canonical URL but the actual request goes to your custom endpoint.
Architecture
Thebedrockruntime.Client construction lives in an exported helper (bedrock.LoadBedrockRuntime) shared between the chat client and the embeddings provider — single source of truth for AWS config. Authentication is SigV4, handled transparently by the SDK. The HTTP client can be overridden by ChatCLI when CHATCLI_BEDROCK_CA_BUNDLE or CHATCLI_BEDROCK_INSECURE_SKIP_VERIFY is set (via awshttp.BuildableClient).
Bedrock vs. Direct Anthropic
Troubleshooting
bedrock: model X requires an inference profile
bedrock: model X requires an inference profile
/switch --model automatically filters out base IDs that require profiles, so this only shows up if you typed an ID manually. The filter uses the InferenceTypesSupported field of ListFoundationModels: a model without ON_DEMAND is suppressed from the listing.AccessDeniedException: You don't have access to the model
AccessDeniedException: You don't have access to the model
bedrock:InvokeModel on the model ARN + the inference profile ARN.NoCredentialProviders / unable to load SDK config
NoCredentialProviders / unable to load SDK config
aws configure, aws sso login, or export env vars.no EC2 IMDS role found / dial tcp 169.254.169.254:80: connect: host is down
no EC2 IMDS role found / dial tcp 169.254.169.254:80: connect: host is down
SSOTokenProviderError / expired token (SSO)
SSOTokenProviderError / expired token (SSO)
AWS_PROFILE set (env, .env, or name your profile default).ThrottlingException / ServiceQuotaExceededException
ThrottlingException / ServiceQuotaExceededException
- Use a
global.*inference profile (routes to any available region) - Use Provisioned Throughput (configure in the Bedrock console)
- Raise quotas via AWS Service Quotas
Embeddings via Bedrock
ChatCLI also uses Bedrock as an embeddings provider (HyDE phase 3b, vector retrieval). Activation:BEDROCK_REGION / AWS_REGION / AWS_PROFILE / ~/.aws/credentials etc. See RAG + HyDE for the retrieval architecture.