Claude Code's built-in /model picker lists Anthropic's current lineup: Fable 5, Opus 5, Sonnet 5, Haiku 4.5, and a handful of legacy models. That's the right default for most people, but it breaks down the moment an organization standardises on something the picker doesn't know about, a specific Amazon Bedrock inference profile, a Google Cloud deployment, or an internal name developers actually use day to day rather than a raw model ID. modelPicker, added in Claude Code v2.1.242 (25 August 2026), is the setting that fixes this: it lets you curate exactly what the picker shows, in your own order, under your own labels.
It's documented in Claude Code's settings reference, and this guide covers the full schema, both usage modes, and where a curated picker earns its keep on a team running many models across providers.
The schema
modelPicker takes an object with two fields:
| Field | Type | What it does |
|---|---|---|
options | array of rows, each with a required model and an optional label and description | The rows the picker shows, in this order, except that a grayed-out row moves to the bottom |
replaceBuiltInOptions | boolean, default false | true shows only these rows, Default, and a row for the model the session is already using. Left unset, these rows are added after the built-in lineup |
Each row's model value is taken verbatim and accepts anything --model accepts: a built-in alias like opus, an Anthropic model ID, or a provider-format ID for Amazon Bedrock, Google Cloud's Agent Platform, Microsoft Foundry, or an LLM gateway. Without a label, Claude Code titles the row with the built-in name for a model it recognises, or the raw model ID otherwise; without a description, it writes a generic second line.
A worked example
This example, adapted from Anthropic's own reference, adds two Bedrock deployments after the built-in lineup, under names a team would actually recognise:
{
"modelPicker": {
"options": [
{ "model": "us.anthropic.claude-opus-4-8", "label": "Opus (production)" },
{
"model": "us.anthropic.claude-sonnet-4-6",
"label": "Sonnet (production)",
"description": "Day-to-day work"
}
]
}
}
With replaceBuiltInOptions left unset, developers still see Fable 5, Opus 5, Sonnet 5 and Haiku 4.5 exactly as before, with "Opus (production)" and "Sonnet (production)" added underneath, pointing at the organisation's actual Bedrock inference profiles rather than Anthropic's own model IDs.
Replacing the picker entirely
Set replaceBuiltInOptions: true to hide everything else and show only your curated list:
{
"modelPicker": {
"options": [
{ "model": "us.anthropic.claude-opus-4-8", "label": "Opus (production)" },
{ "model": "us.anthropic.claude-sonnet-4-6", "label": "Sonnet (production)" }
],
"replaceBuiltInOptions": true
}
}
With this on, Claude Code hides the built-in lineup, any rows it would otherwise add for availableModels entries, models found through gateway discovery, and any model added through ANTHROPIC_CUSTOM_MODEL_OPTION. The picker instead shows exactly your rows, plus Default and a row for the model the current session is already using. With replaceBuiltInOptions off, Claude Code quietly skips a listed model that the built-in lineup already covers, rather than showing a duplicate.
Scope: why this can't live in a repository's settings
modelPicker has a deliberately narrow scope: User or managed only. Claude Code reads the key from managed settings, from a file passed via --settings, and from your personal ~/.claude/settings.json. It ignores the key entirely in project settings (.claude/settings.json) and project-local settings (.claude/settings.local.json).
That's not an oversight. It closes off a specific attack surface: if a checked-in repository file could relabel the model picker, cloning a malicious or compromised repository could silently trick a developer into running a different model than they think they've selected, since a label is arbitrary text under Claude Code's control, not a guarantee about which model actually runs. Keeping modelPicker out of project scope means a repository you clone can influence your prompts and permissions, but never what your /model picker claims to be offering you.
When more than one of the three valid sources sets modelPicker, Claude Code doesn't merge them. The highest-precedence source that sets the key supplies the entire lineup, and a lower-precedence source's modelPicker is ignored outright rather than layered underneath it.
How a bad or unreachable row is handled
Claude Code checks every row against the current session before showing the picker, and handles three outcomes differently:
- Dropped silently: a row naming a retired model, or one your organization has no access to, simply doesn't appear. No error, no placeholder.
- Grayed out: a row you can't select yet for some other reason is shown, with the reason attached, rather than hidden entirely.
- Nothing survives: if every listed row is dropped or otherwise unusable, Claude Code falls back to showing the built-in lineup, filtered by your
availableModelsallowlist as usual, rather than leaving you with an empty picker.
Claude Code also drops any row it can't parse, keeping the rest of the list intact; see fixing a broken settings file if a modelPicker change doesn't take effect as expected.
What "any model --model accepts" actually covers
It's worth being concrete about how wide the model field's acceptance really is, since it's the detail that makes modelPicker useful beyond Anthropic's own first-party API. A row's model value can be:
- A built-in alias, like
opus,sonnet, orhaiku, resolving the same way it would on the command line. - A full Anthropic model ID, dated or dateless, exactly as it appears in the models overview table.
- An Amazon Bedrock inference profile ID, such as
us.anthropic.claude-opus-4-8, matching what Bedrock's own console shows for a deployed model. - A Google Cloud Agent Platform or Microsoft Foundry identifier, in whatever format those platforms use for a Claude deployment.
- An LLM gateway model name, when Claude Code is configured against a gateway rather than a provider directly.
This is the same acceptance logic --model uses on the command line, which is why Anthropic's own documentation describes modelPicker rows as taking "anything --model accepts" rather than listing a separate, narrower format. Practically, this means a modelPicker rollout can mix an Anthropic alias and a Bedrock-specific ID in the same options array without issue, useful for an organization mid-migration between providers, or one running some workloads first-party and others through a specific cloud platform for compliance reasons.
modelPicker vs availableModels
It's worth distinguishing this from availableModels, an existing, related setting that's easy to conflate with it. availableModels is an allowlist: it restricts which models a session is permitted to run at all, independent of how the picker displays them. modelPicker is presentational: it controls what the picker shows and how, but doesn't grant access to anything availableModels would otherwise block. The two compose rather than compete: an availableModels allowlist still applies to rows you add through modelPicker, and a listed model your allowlist excludes is filtered out the same way an inaccessible model would be. Before adding a listed model to your allowlist, check merge behaviour: a specific model ID narrows its family's wildcard entry rather than adding to it.
When curating the picker is worth doing
Three situations where modelPicker earns its place over the default:
A fleet standardised on specific cloud deployments. If your organisation runs Claude exclusively through named Bedrock inference profiles or Vertex deployments rather than Anthropic's first-party API, the built-in picker's aliases (opus, sonnet) don't map cleanly onto what developers actually have access to. Labelling the real deployment IDs removes that translation step for everyone.
Reducing choice on purpose. A team that wants every developer defaulting to one or two sanctioned models, for cost control, compliance, or simply reducing variance across a codebase, can set replaceBuiltInOptions: true and offer exactly those options, nothing more.
Internal naming conventions. Even without changing which models are technically available, giving rows names like "Production" and "Experimental" instead of raw version strings makes the picker legible to developers who don't track Anthropic's model-naming scheme closely.
Pairing it with modelPricing
modelPicker is often deployed alongside another setting that shipped in the same v2.1.242/v2.1.243 window: modelPricing, which reports spend in /usage, the status line, and telemetry at an organization's actual contracted rates instead of Anthropic's list price. The two solve adjacent but distinct problems. modelPicker controls what developers see and select; modelPricing controls what the dollar figures mean once they've selected it. A fleet running curated Bedrock deployments through labelled modelPicker rows gets little value from those labels if the cost figures next to them are still list price rather than the organization's negotiated rate. Setting both together, modelPicker for the labelled lineup and modelPricing for the rates behind it, gives developers a picker that matches both what they can run and what it actually costs when they run it. Like modelPicker, modelPricing is a Managed-scope setting, deployed through managed settings, an MDM policy, or a policy helper program, and it requires Claude Code v2.1.242 or later.
Testing a rollout before shipping it org-wide
Because modelPicker in managed settings affects every developer who reads that policy, it's worth verifying a change on your own machine before deploying it broadly. The --settings flag accepts the same JSON shape and lets you preview the exact picker your managed settings would produce, without touching a shared file:
claude --settings my-modelpicker-test.json
Open /model inside that session and confirm the rows, order, and labels look right, including that replaceBuiltInOptions behaves as expected and that no row you meant to include has silently dropped because the model behind it isn't reachable from your account. Once confirmed, moving the same JSON into managed settings, an MDM policy, or a policy helper program is a matter of deployment mechanics rather than further debugging the schema itself.
Troubleshooting
A row I added doesn't appear anywhere in the picker. Check whether it's a retired model or one your organisation lacks access to; both are dropped silently rather than shown as an error. Confirm the model identifier is exactly what --model would accept for that provider.
The picker still shows the built-in lineup even though I set modelPicker. Confirm you're setting it in managed settings, --settings, or ~/.claude/settings.json, not in a project-scoped file, where it's ignored entirely. Also confirm you're on Claude Code v2.1.242 or later.
I set replaceBuiltInOptions: true and the picker is empty. This shouldn't happen: if every row you listed is unusable, Claude Code falls back to the built-in lineup rather than leaving the picker with nothing. If you're seeing an empty picker regardless, that points at a different bug than the modelPicker configuration itself; check with --debug.
Two different settings sources both set modelPicker, and I'm not sure which one won. Claude Code doesn't merge lineups. Whichever source is highest in the precedence order, managed settings first, then --settings, then ~/.claude/settings.json, supplies the whole list, and the others are ignored outright for this key.
Where to go next
For the model-side setting that decides which model new sessions start on by default rather than what the picker lists, see ANTHROPIC_DEFAULT_MODEL: setting Claude Code's default model per machine. For the companion cache-lifetime settings that shipped the same week, see Claude Code's promptCacheTtl and subagentPromptCacheTtl settings. For distributing settings like this one across a whole fleet of developer machines, see how to configure auto mode's trusted infrastructure for a team. Browse the current Claude Code catalogue at getclaudeskills.com/platforms/claude-code.
Verified 31 August 2026 directly against Claude Code's settings reference documentation at code.claude.com, read in full, including the complete modelPicker schema, its worked example, and its scope restrictions, following the setting's introduction in v2.1.242 (25 August 2026).
