<!-- llms-explorer concept facts · https://llms-explorer.com/tree/codex-model-catalog-json-model-catalog-json-for/ · pack 2026-10-05 · ~2625 tokens -->

# Codex model catalog JSON (model_catalog_json) for local model slugs

> The config schema describes `model_catalog_json` as "Optional path to a JSON model catalog (applied on startup only). Per-thread `config` overrides are accepted but do not reapply this (no-ops)."

Parent: [Mac local LLMs: Agent clients, context and compaction](https://llms-explorer.com/tree/mac-local-llms-agent-clients-context-and-compaction/) · 1 facets · 33 facts · page: https://llms-explorer.com/tree/codex-model-catalog-json-model-catalog-json-for/

## Facts

- The config schema describes `model_catalog_json` as "Optional path to a JSON model catalog (applied on startup only). Per-thread `config` overrides are accepted but do not reapply this (no-ops)." — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/core/config.schema.json)
- The catalog file is a JSON object with a `models` array; the Rust type `ModelsResponse` holds `models: Vec<ModelInfo>`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- On main (read 2026-10-04) these `ModelInfo` fields have no serde default and no `Option` type, so a catalog entry must supply them: `slug`, `display_name`, `supported_reasoning_levels`, `shell_type`, `visibility`, `supported_in_api`, `priority`, `support_verbosity`, `truncation_policy` and `experimental_supported_tools`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- An entry that has neither a top-level `base_instructions` nor `model_messages.instructions_template` fails to load with the error "model `<slug>` is missing both `base_instructions` and `model_messages.instructions_template`". — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- The deserializer promotes a deprecated top-level `base_instructions` string into `model_messages.instructions_template` when no template is present. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `shell_type` accepts `unified_exec` (aliases `default`, `local`, `shell_command`) or `disabled`; `visibility` accepts `list`, `hide` or `none`; `apply_patch_tool_type` accepts `freeform`; `web_search_tool_type` accepts `text` or `text_and_image`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `truncation_policy` is an object with `mode` (`bytes` or `tokens`) and an integer `limit`; `tool_mode` accepts `direct`, `code_mode` or `code_mode_only`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `input_modalities` takes `text`, `image` or `audio` and defaults to text plus image when omitted, so a text-only local model needs an explicit `["text"]`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `effective_context_window_percent` defaults to 95, and `usable_context_window` is `context_window * percent / 100`, where the window is `context_window` or else `max_context_window`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- When `auto_compact_token_limit` is absent Codex derives it as 90 percent of the context window, and a configured limit is clamped to the smaller of the limit and 90 percent of the window. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `supports_reasoning_summary_parameter` defaults to true and says whether the model accepts the Responses `reasoning.summary` parameter, so a local server that rejects it needs `false`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- `supports_search_tool` and `use_responses_lite` default to false; `supports_reasoning_effort_updates` defaults to false and, when absent, keeps effort changes on the ordinary request parameter. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/protocol/src/openai_models.rs)
- For an unknown slug `model_info_from_slug` logs "Unknown model {slug} is used. This will use fallback model metadata." and returns a 272,000-token `context_window` and `max_context_window`, 95 percent effective window, a 10,000-byte truncation policy, `unified_exec` shell, `visibility: none` and text-plus-image input. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/models-manager/src/model_info.rs)
- So an uncatalogued 32K local model is treated as a 272K model, and auto-compaction would not trigger until about 245K tokens unless `model_context_window` is set. — source: `asserted`
- `with_config_overrides` sets `context_window` to the smaller of `model_context_window` and the entry's `max_context_window` (when it has one), replaces `auto_compact_token_limit` with the configured value, rewrites the truncation limit from `tool_output_token_limit`, and replaces the instruction template with a configured `base_instructions`. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/models-manager/src/model_info.rs)
- The model manager has an "explicit provider" catalog mode that, per its own comment, serialises refresh and suppresses the bundled fallback list; the default mode merges fetched entries over bundled ones by slug. — [source](https://raw.githubusercontent.com/openai/codex/main/codex-rs/models-manager/src/manager.rs)
- A user reported that when `model_catalog_json` is set, `load_model_catalog` in `codex-rs/core/src/config/mod.rs` replaces the built-in catalog and the TUI picker lists only catalog entries, so OpenAI models vanish. — [source](https://api.github.com/repos/openai/codex/issues/30994)
- The Codex app's "connect to Ollama" flow wrote top-level `model_provider = "ollama-launch-codex-app"` and `model_catalog_json = ".../ollama-launch-models.json"`, leaving `model = "gpt-5.5"` pointed at `http://127.0.0.1:11434/v1/responses` and failing with `404 model 'gpt-5.5' not found` (Codex 0.142.5, app 26.623). — [source](https://api.github.com/repos/openai/codex/issues/30994)
- The 19694 reporter's example entry used `displayName`, `provider` and `hidden`, none of which is a `ModelInfo` field name on main, so that file would not describe a catalog entry the struct accepts. — [source](https://github.com/openai/codex/issues/19694)
- The picker bug in 19694 (app-server `model/list` returned the custom models, the Desktop renderer filtered them) was closed, but 34487 ("loaded but custom models not shown", regression), 37379 (hidden in API-key-only sessions) and 36582 ("Custom High" label) were open on 2026-10-04. — [source](https://api.github.com/search/issues?q=repo:openai/codex+model_catalog_json&per_page=20)
- A Codex CLI 0.143.0 user on Windows kept getting "Model metadata for `MiniMax-M2.7` not found. Defaulting to fallback metadata" with a valid catalog, and their `config.toml` shows `model_catalog_json` written after the `[model_providers.minimax]` header. — [source](https://api.github.com/repos/openai/codex/issues/32349)
- TOML scopes a key written after a table header to that table, so the 32349 setting sat inside the provider table and was probably never read as the top-level key. — source: `asserted`
- The catalog is resolved once at process start, so a window cannot follow a provider switch behind a running process; the reporter's workaround was the minimum window across all providers serving that model name (for example 1,000,000 lowered to 262,144). — [source](https://api.github.com/repos/openai/codex/issues/47917)
- That reporter saw upstream error "This model's maximum context length is 262144 tokens. However, you requested 0 output tokens and your prompt contains at least 262145 input tokens" because Codex believed it had about 1M tokens and never compacted. — [source](https://api.github.com/repos/openai/codex/issues/47917)
- Issue 35129 reports `model/list` caching the catalog until restart, and 49930 asks for a reload without restarting the app-server or Desktop. — [source](https://api.github.com/search/issues?q=repo:openai/codex+model_catalog_json&per_page=20)
- A catalog copied from `main` failed to load in Codex 0.148.0-alpha.9 with "failed to parse model_catalog_json path `/dev/stdin` as JSON: missing field `supports_parallel_tool_calls`", because the field had been removed from `ModelInfo` in commit 86b1123f. — [source](https://api.github.com/repos/openai/codex/issues/38934)
- The matching-tag catalog (`rust-v0.148.0-alpha.9/codex-rs/models-manager/models.json`) loaded, and `codex -c 'model_catalog_json="/dev/stdin"' debug models` is a way to validate a catalog file. — [source](https://api.github.com/repos/openai/codex/issues/38934)
- A catalog written before a new model launch silently hid the new model in Codex 0.153.4 until the override was removed, with no warning. — [source](https://api.github.com/repos/openai/codex/issues/43052)
- Profile files can override `model_catalog_json` and Codex uses the profile value when both set it; since 0.134.0 `--profile` reads `~/.codex/<name>.config.toml` and no longer reads `[profiles.<name>]` in `config.toml`. — [source](https://developers.openai.com/codex/config-advanced)
- Issue 39650 (v0.148.0, open) reports a `model_catalog_json` set in a profile file is not applied, and 26308 reports Desktop ignoring a project-local catalog for fresh project threads. — [source](https://api.github.com/repos/openai/codex/issues/39650)
- With a local catalog entry that sets `supports_search_tool: true`, Codex sent a `tool_search` tool with `"execution": "client"` and kept the MCP tools out of the `tools` array (Codex CLI 0.153.4 against Ollama 0.34). — [source](https://api.github.com/repos/ollama/ollama/issues/18306)
- A Desktop session on the built-in `openai` provider with a custom slug from `model_catalog_json` had declared tools (`web.run`, connector tools) intermittently rejected with the literal error "unsupported call: <name>" (bundled codex-cli 0.156.1). — [source](https://api.github.com/repos/openai/codex/issues/49095)
- Inferred: for a local llama-server or Ollama slug the minimum catalog entry is slug, display name, an instruction template, `shell_type`, `visibility`, `supported_reasoning_levels: []`, `truncation_policy`, an accurate `context_window`, `input_modalities` and `supports_reasoning_summary_parameter: false` if the server rejects it. — source: `asserted`
