Commit Graph
100 Commits
Author SHA1 Message Date
Matthew Zeng 1fbaac1e50 [codex] Reuse Apps policy evaluation across MCP tool exposure (#27813)
## Summary

- move `AppToolPolicyEvaluator` and the Apps config/requirements policy
logic from `codex-core` into `codex-connectors`
- resolve one immutable policy snapshot per exposure build and reuse it
across every Codex Apps MCP tool
- keep core as a thin adapter from MCP metadata to connector-owned
policy input while preserving the call-time defense-in-depth check

## Why

`build_mcp_tool_exposure` evaluates every Codex Apps tool on each
sampling request. The old path rebuilt effective Apps configuration for
every tool, and the policy implementation lived in the already-large
core crate even though it is connector-specific.

The connector-owned evaluator keeps the expensive config merge/decode
out of the loop and gives core only the effective policy result it
needs.

## Performance

With the real 557-tool Apps corpus, `build_mcp_tool_exposure` measured
3.74 ms and 3.33 ms after the extraction (3.54 ms mean). The original
path measured 807 ms mean, so the final result retains the 99.6%
reduction.

## Validation

- `cargo check -p codex-connectors -p codex-core`
- `just test -p codex-connectors` — 15 passed
- `just test -p codex-core --lib connectors` — 35 passed
- `just test -p codex-core --lib mcp_tool_exposure` — 5 passed
- `just test -p codex-core --lib mcp_tool_call` — 72 passed
- `just bazel-lock-update`
- `just bazel-lock-check`
- `just fix -p codex-connectors`
- `just fix -p codex-core`
- `just fmt`
2026-06-15 15:24:33 -07:00
Matthew Zeng 4a70e0ac1b Cleanup experimentalFeature/enablement/set (#26312)
## Why

`experimentalFeature/enablement/set` still allowed several keys that no
longer need to be managed through this API. Keeping those keys also
preserved corresponding special-case logic, including refreshing the
apps list when the `apps` key was enabled.

The endpoint also rejected an entire request when any key was invalid or
unsupported. That makes clients brittle when they send a mix of current
and stale keys, even when the valid entries can still be applied safely.

## What changed

- remove the feature keys that no longer need to be supported by
`experimentalFeature/enablement/set`
- remove the corresponding apps-list refresh path and its auth/config
plumbing
- ignore and warn on invalid or unsupported keys while still applying
valid keys from the same request
- update the app-server documentation and integration coverage for the
reduced key set and partial-acceptance behavior

## Test plan

- `just test -p codex-app-server experimental_feature_enablement_set` (6
passed)
- `just test -p codex-app-server` exercised the changed tests
successfully; unrelated sandbox-dependent and watcher/timing tests
failed locally
2026-06-04 13:35:31 -07:00
Matthew Zeng 6963145cb6 Support OAuth options in codex mcp add (#24120)
## Summary
- add `--oauth-client-id` and `--oauth-resource` options for streamable
HTTP `codex mcp add` registrations
- persist those options in MCP server config and use them during the
immediate OAuth login flow
- cover add-time serialization of both OAuth options in the CLI
integration tests

## Testing
- `just fmt`
- `cargo test -p codex-cli`
- `just fix -p codex-cli`
2026-05-22 13:21:01 -07:00
Matthew Zeng 0a4179bb19 [codex] Add plugin id to MCP tool call items (#23737)
Add owning plugin id to MCP tool call items so we can better filter them
at plugin level.

## Summary
- add optional `plugin_id` to MCP tool-call items and legacy begin/end
events
- propagate plugin metadata into emitted core items and app-server v2
`ThreadItem::McpToolCall`
- preserve plugin ids through app-server replay/redaction paths and
regenerate v2 schema fixtures

## Testing
- `just write-app-server-schema`
- `just fmt`
- `just fix -p codex-core`
- `cargo test -p codex-protocol -p codex-app-server-protocol`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-core mcp_tool_call_item_includes_plugin_id --lib`
- `cargo check -p codex-tui --tests`
- `cargo check -p codex-app-server --tests`
- `git diff --check`

## Notes
- `just fix -p codex-core` completed with two non-fatal
`too_many_arguments` warnings on the touched MCP notification helpers.
- A broader `cargo test -p codex-core` run passed core unit tests, then
hit shell/sandbox/snapshot failures in the integration target.
- A broader app-server downstream run hit the existing
`in_process::tests::in_process_start_clamps_zero_channel_capacity` stack
overflow; `cargo test -p codex-exec` also hit the existing sandbox
expectation mismatch in
`thread_lifecycle_params_include_legacy_sandbox_when_no_active_profile`.
2026-05-20 17:02:10 -07:00
Matthew Zeng b019a678d8 Remove unused ARC monitor path (#23573)
## Summary
- remove the unreachable ARC monitor path from MCP tool approval
handling
- delete the unused ARC monitor module/tests and trim the orphaned
safety-monitor decision plumbing
- keep `always allow` approvals on the existing auto-approval
short-circuit without a dead monitor hop

## Testing
- `cargo test -p codex-core mcp_tool_call`
- `just fmt`
- `just fix -p codex-core`
- `git diff --check`

## Additional validation
- Attempted `cargo test -p codex-core`; the library test target passed,
then the integration target failed in this local environment.
- The narrower MCP-focused rerun passed its unit coverage and only hit
missing local `test_stdio_server` binaries in filtered integration
cases.
2026-05-19 16:23:25 -07:00
Matthew Zeng 8335b56c33 Split plugin install discovery into list and request tools (#23372)
## Summary
- Add `list_available_plugins_to_install` as the inventory step for
plugin and connector install suggestions.
- Slim `request_plugin_install` so it only handles the actual
elicitation, instead of carrying the full discoverable list in its
prompt.
- Emit send-time telemetry when an install elicitation is dispatched,
including requested tool identity in the event payload.
- Emit install-result telemetry through `SessionTelemetry`, including
tool type, user response action, and completion status.
- Update registration and tests to cover the new two-step flow while
keeping the existing `tool_suggest` feature gate unchanged.

## Testing
- `just fmt`
- `cargo test -p codex-tools`
- `cargo test -p codex-core request_plugin_install`
- `cargo test -p codex-core list_available_plugins_to_install`
- `cargo test -p codex-core
install_suggestion_tools_can_be_registered_without_search_tool`
- `cargo test -p codex-otel
manager_records_plugin_install_suggestion_metric`
- `cargo test -p codex-otel
manager_records_plugin_install_elicitation_sent_metric`
- `just fix -p codex-core`
- `just fix -p codex-tools`
- `just fix -p codex-otel`
- `cargo check -p codex-core`
2026-05-19 14:45:37 -07:00
Matthew Zeng a66e0e9c4b Include plugin id in plugin MCP tool metadata (#23353)
Adding the id of the plugin that contains the MCP (if any) so we can
apply filters at plugin level.

## Summary
- carry the plugin owner into MCP runtime provenance
- attach `plugin_id` to outbound plugin-backed MCP tool-call `_meta`
- avoid misattributing user-configured MCP servers that shadow plugin
server names

## Testing
- `just fmt`
- `just fix -p codex-mcp`
- `just fix -p codex-core`
- `cargo test -p codex-mcp`
- `cargo test -p codex-core
plugin_mcp_tool_call_request_meta_includes_plugin_id`
- `cargo test -p codex-core
to_mcp_config_omits_plugin_id_when_user_server_shadows_plugin_mcp`
- `cargo test -p codex-core
rebuild_preserving_session_layers_refreshes_plugin_derived_mcp_config`
- `git diff --check`

## Notes
- Attempted `cargo test -p codex-core`; it aborted in
`agent::control::tests::resume_agent_from_rollout_skips_descendants_when_parent_resume_fails`
with a stack overflow before the full suite completed.
2026-05-18 15:33:33 -07:00
Matthew Zeng d8ddeb6869 Support explicit MCP OAuth client IDs (#22575)
## Why
Some MCP OAuth providers require a pre-registered public client ID and
cannot rely on dynamic client registration. Codex already supports MCP
OAuth, but it had no way to supply that client ID from config into the
PKCE flow.

## What changed
- add `oauth.client_id` under `[mcp_servers.<server>]` config, including
config editing and schema generation
- thread the configured client ID through CLI, app-server, plugin login,
and MCP skill dependency OAuth entrypoints
- configure RMCP authorization with the explicit client when present,
while preserving the existing dynamic-registration path when it is
absent
- add focused coverage for config parsing/serialization and OAuth URL
generation

## Verification
- `cargo test -p codex-config -p codex-rmcp-client -p codex-mcp -p
codex-core-plugins`
- `cargo test -p codex-core blocking_replace_mcp_servers_round_trips
--lib`
- `cargo test -p codex-core
replace_mcp_servers_streamable_http_serializes_oauth_resource --lib`
- `cargo test -p codex-core config_schema_matches_fixture --lib`

## Notes
Broader local package runs still hit unrelated pre-existing stack
overflows in:
- `codex-app-server::in_process_start_clamps_zero_channel_capacity`
-
`codex-core::resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale`
2026-05-14 11:52:43 -07:00
Matthew Zeng e15ecc9c35 Add production startup and TTFT telemetry (#22198)
## Why

While investigating `codex exec hi` startup latency, the useful
questions were not "is startup slow?" but "which durable bucket is slow
in production?"

The path we observed has a few distinct stages:

1. `thread/start` creates the session
2. startup prewarm builds the turn context, tools, and prompt
3. startup prewarm warms the websocket
4. the first real turn resolves the prewarm
5. the model produces the first token

Before this PR, production telemetry had some of the raw measurements
already:

- aggregate startup-prewarm duration / age-at-first-turn metrics
- TTFT as a metric
- websocket request telemetry

But there was no coherent production event stream for the startup
breakdown itself, and TTFT was metric-only. That made it hard to answer
the same latency questions from OpenTelemetry-backed logs without adding
one-off local instrumentation.

## What changed

Add durable production telemetry on the existing `SessionTelemetry`
path:

- new `codex.startup_phase` OTel log/trace events plus
`codex.startup.phase.duration_ms`
- new `codex.turn_ttft` OTel log/trace events while preserving the
existing TTFT metric

The startup phase event is emitted for the coarse buckets we actually
observed while running `exec hi`:

- `thread_start_create_thread`
- `startup_prewarm_total`
- `startup_prewarm_create_turn_context`
- `startup_prewarm_build_tools`
- `startup_prewarm_build_prompt`
- `startup_prewarm_websocket_warmup`
- `startup_prewarm_resolve`

These phases are intentionally low-cardinality so they remain safe as
production telemetry tags.

## Why this shape

This keeps the instrumentation on the same production path as the rest
of the session telemetry instead of adding a local debug-only trace
mode. It also avoids changing startup behavior:

- prewarm still runs
- no control flow changes
- no extra remote calls
- no user-visible behavior changes

One boundary is intentional: very early process bootstrap that happens
before a session exists is not included here, because this PR uses
session-scoped production telemetry. The expensive buckets we were
trying to understand after `thread/start` are now covered durably.

## Verification

- `cargo test -p codex-otel`
- `cargo test -p codex-core turn_timing`
- `cargo test -p codex-core
regular_turn_emits_turn_started_without_waiting_for_startup_prewarm`
- `cargo test -p codex-core
interrupting_regular_turn_waiting_on_startup_prewarm_emits_turn_aborted`
- `cargo test -p codex-app-server thread_start`
- `just fix -p codex-otel -p codex-core -p codex-app-server`

I also ran `cargo test -p codex-core`; it built successfully and then
hit an existing unrelated stack overflow in
`tools::handlers::multi_agents::tests::tool_handlers_cascade_close_and_resume_and_keep_explicitly_closed_subtrees_closed`.
2026-05-11 23:58:36 +00:00
Matthew Zeng 192481d1a1 [elicitation] Advertise new url elicitation capability when auth_elicitation is enabled. (#22188)
## Why

We've added support for auth elicitation behind the auth_elicitation
flag, but servers need to explicitly check the capability before it
decides to send elicitations in order to be backward compatible. This PR
adds the capability advertising conditioned on the flag.

## What changed

- Build `client_elicitation_capability` from the `AuthElicitation`
feature state.
- Thread that capability through MCP config, session startup, and
`McpConnectionManager` so RMCP initialization advertises the correct
elicitation support.
- Advertise both `form` and `url` elicitation when the feature is
enabled, and preserve the empty default capability when it is disabled.
- Add coverage for the feature-derived config shape and the advertised
initialization payload.

## Testing

- `cargo test -p codex-mcp`
- `cargo test -p codex-core
to_mcp_config_preserves_auth_elicitation_feature_from_config`
- `cargo test -p codex-core` *(currently fails outside this change in
`tools::handlers::multi_agents::tests::tool_handlers_cascade_close_and_resume_and_keep_explicitly_closed_subtrees_closed`
with a stack overflow after unrelated tests have started running)*
2026-05-11 12:23:55 -07:00
Matthew Zeng 2f3a2d7a86 Using cached connector directory for discoverable tools list (#21497)
## Summary

Startup tool construction currently depends on connector directory
metadata for `tool_suggest` discoverables. On a cold directory cache,
that can put slow connector-directory requests on the blocking path even
though the tools array only needs directory data for install
suggestions, not for the live connector MCP tools themselves.

This PR keeps the discoverables path off that cold network fetch:
- read connector directory metadata from cache only when building
discoverable tools
- persist connector directory metadata to
`~/.codex/cache/codex_app_directory/<hash>.json` and use it to hydrate
the in-memory cache on later runs before the normal refresh path updates
it
- use connector-directory-specific cache naming to distinguish this
metadata cache from the separate Codex Apps tools-spec cache

This reduces first-turn startup work without changing how live connector
MCP tools are sourced. Longer term, directory-backed install suggestions
should move to a search-based flow so they no longer need to be inlined
into the tools prompt at all.

## Testing

- `cargo test -p codex-connectors`
- `cargo test -p codex-chatgpt`
- `cargo test -p codex-core
request_plugin_install_is_available_without_search_tool_after_discovery_attempts`
- `cargo test -p codex-core
tool_suggest_uses_connector_id_fallback_when_directory_cache_is_empty`
2026-05-08 14:14:11 -07:00
Matthew Zeng f9a907aebe Support Codex Apps auth elicitations (#19193)
## Summary

- request URL-mode MCP elicitations when Codex Apps tool calls fail with
connector auth metadata
- route Codex Apps auth URL elicitations into the TUI app-link flow

## Test plan

- `just fmt`
- `cargo test -p codex-core mcp_tool_call::tests`
- `cargo test -p codex-mcp`
- `cargo test -p codex-tui bottom_pane::app_link_view::tests`
- `just fix -p codex-core`
- `just fix -p codex-mcp`
- `just fix -p codex-tui`

Also attempted broader local runs:

- `cargo test -p codex-core` fails in unrelated
config/request-permission/proxy-sensitive tests under the current Codex
Desktop environment.
- `cargo test -p codex-tui` fails in unrelated status
snapshots/trust-default tests because the ambient environment renders
workspace-write/network permission defaults.
2026-05-06 07:18:00 +00:00
Matthew Zeng 41505bcea2 [mcp] Return Accept early per feedback. (#21277)
- [x] Return Accept early when auto_deny is enabled per feedback.
2026-05-05 21:23:42 -07:00
Matthew Zeng 1b900bee8a Unify skip-review handling for approval_mode = "approve" (#20750)
## Summary
- Treat `approval_mode = "approve"` as skip-review across all permission
modes.
- Remove the mode-specific split in the MCP auto-approval gate so
approved tools bypass review consistently.
- Expand regression coverage in the shared MCP helper and the core
tool-call flow.

## Testing
- `just fmt`
- `cargo test -p codex-mcp`
- `cargo test -p codex-core
approve_mode_skips_arc_and_guardian_in_every_permission_mode`
- `git diff --check`
- Full `cargo test -p codex-core` was also attempted, but the suite hit
an unrelated pre-existing stack overflow in an existing multi-agent test
2026-05-04 10:30:47 -07:00
Matthew Zeng 83a4e3b66b [mcp-apps] Persist MCP Apps specific tool call end event. (#20853)
- [x] Persist a special type of MCP tool calls for triggering MCP App,
this type of mcp tool calls has 'mcpAppResourceUri` set. These events
are needed so that the Codex App can correctly render the MCP App after
resume.
2026-05-04 10:20:58 -07:00
Matthew Zeng f88701f5c8 [tool_suggest] More prompt polishes. (#20566)
Tool suggest still misfires when model needs tool_search, updating the
prompts to further disambiguate it:

- [x] rename it from `tool_suggest` to `request_plugin_install`
- [x] rephrase "suggestion" to "install" in the tool descriptions.
- [x] disambiguate "the tool" vs "the plugin/connector". 

Tested with the Codex App and verified it still works.
2026-05-02 04:22:12 +00:00
Matthew Zeng 70090c9ff7 [plugin] Add Canva to suggesteable list. (#20474)
- [x] Add Canva to suggesteable list.
2026-04-30 12:39:52 -07:00
Matthew Zeng ebe602d005 [plugins] Allow MSFT curated plugins in tool_suggest (#20304)
## Summary
- [x] Move the allowlist out of core crate
- [x] Add Teams, SharePoint, Outlook Email, and Outlook Calendar to the
tool_suggest discoverable plugin allowlist
- [x] Add focused coverage for Microsoft curated plugin discovery

## Testing
- just fmt
- cargo test -p codex-core-plugins
- cargo test -p codex-core
list_tool_suggest_discoverable_plugins_returns_
2026-04-29 19:45:52 -07:00
Matthew Zeng e20391e567 [mcp] Fix plugin MCP approval policy. (#19537)
Plugin MCP servers are loaded from plugin manifests rather than
top-level `[mcp_servers]`, so their tool approval preferences need to be
stored and applied through the owning plugin config. Without this,
choosing "Always allow" for a plugin MCP tool could write a preference
that was not reliably used on later tool calls.

## Summary
- Add plugin-scoped MCP policy config under
`plugins.<plugin>.mcp_servers`, including server enablement, tool
allow/deny lists, server defaults, and per-tool approval modes.
- Overlay plugin MCP policy onto manifest-provided server configs when
plugins are loaded.
- Route persistent "Always allow" writes for plugin MCP tools back to
the owning `plugins.<plugin>.mcp_servers.<server>.tools.<tool>` config
entry.
- Reload user config after persisting an approval and make the plugin
load cache config-aware so stale plugin MCP policy is not reused after
`config.toml` changes.
- Regenerate the config schema and add coverage for plugin MCP policy
loading, approval lookup, persistence, and stale-cache prevention.

## Testing
- `cargo test -p codex-config`
- `cargo test -p codex-core-plugins`
- `cargo test -p codex-core --lib plugin_mcp`
2026-04-29 15:40:03 -07:00
Matthew Zeng 8ce48f9968 [tool_suggest] Improve tool_suggest triggering conditions. (#20091)
## Summary
- Tighten `tool_suggest` guidance so it prefers explicit plugin install
requests, while still allowing a connector install when the relevant
plugin is already installed and a needed connector from that plugin is
missing.
- Tell the model not to call `tool_suggest` in parallel with other
tools.

## Testing
- `cargo test -p codex-tools tool_suggest`
- `cargo test -p codex-core tool_suggest`
2026-04-29 13:41:12 -07:00
Matthew Zeng ebdf3a878c Support disabling tool suggest for specific tools. (#20072)
## Summary
- Add `disable_tool_suggest` to app and plugin config, schema, and
TypeScript output
- Exclude disabled connectors and plugins from tool suggestion discovery
- Persist "never show again" tool-suggestion choices back into
`config.toml`
- Update config docs and add coverage for connector and plugin
suppression

## Testing
- Added and updated unit tests for config persistence and tool-suggest
filtering
- Not run (not requested)
2026-04-29 00:19:34 +00:00
Matthew Zeng dcd139b7c4 Add MCP app feature flag (#19884)
## Summary
- Add the `enable_mcp_apps` feature flag to the `codex-features`
registry
- Keep it under development and disabled by default

## Testing
- Unit tests for `codex-features` passed
- Formatting passed
2026-04-27 16:28:49 -07:00
Matthew Zeng 6e838a19fa Enable unavailable dummy tools by default (#19459)
## Summary
- Mark `unavailable_dummy_tools` as a stable feature and enable it by
default
- Update the feature registry test to match the new default state

## Testing
- `just fmt`
- `cargo test -p codex-features`
2026-04-25 08:46:57 +00:00
Matthew Zeng 8f0a92c1e5 Fix relative stdio MCP cwd fallback (#19031) 2026-04-22 17:52:17 -07:00
Matthew Zeng 1132ef887c Make MCP resource read threadless (#18292)
## Summary

Making thread id optional so that we can better cache resources for MCPs
for connectors since their resource templates is universal and not
particular to projects.

- Make `mcpServer/resource/read` accept an optional `threadId`
- Read resources from the current MCP config when no thread is supplied
- Keep the existing thread-scoped path when `threadId` is present
- Update the generated schemas, README, and integration coverage

## Testing
- `just write-app-server-schema`
- `just fmt`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-mcp`
- `cargo test -p codex-app-server --test all mcp_resource`
- `just fix -p codex-mcp`
- `just fix -p codex-app-server-protocol`
- `just fix -p codex-app-server`
2026-04-20 19:59:36 -07:00
Matthew Zeng bf6e7e12aa Use in-process app-server for unknown-thread MCP read test (#18196)
## Summary
- Switch the unknown-thread MCP resource read test from the stdio
subprocess to the in-process app-server path.
- Keep the assertion focused on the returned error message while
avoiding child-process teardown timing issues in nextest.

## Testing
- Not run (not requested)
2026-04-16 23:46:15 +00:00
Matthew Zeng 71174574ad Add server-level approval defaults for custom MCP servers (#17843)
## Summary
- Add `default_tools_approval_mode` support for custom MCP server
configs, matching the existing `codex_apps` behavior
- Apply approval precedence as per-tool override, then server default,
then `auto`
- Update config serialization, CLI display, schema generation, docs, and
tests

## Testing
- `cargo check -p codex-config`
- `cargo check -p codex-core`
- `just write-config-schema`
- `just fmt`
- `cargo test -p codex-config`
- Targeted `codex-core` tests for config parsing, config writes, and MCP
approval precedence
- `just fix -p codex-config -p codex-core`
2026-04-16 18:18:07 +00:00
Matthew Zeng 224dad41ac [codex][mcp] Add resource uri meta to tool call item. (#17831)
- [x] Add resource uri meta to tool call item so that the app-server
client can start prefetching resources immediately without loading mcp
server status.
2026-04-16 05:09:17 +00:00
Matthew Zeng 77fe33bf72 Update ToolSearch to be enabled by default (#17854)
## Summary
- Promote `Feature::ToolSearch` to `Stable` and enable it in the default
feature set
- Update feature tests and tool registry coverage to match the new
default
- Adjust the search-tool integration test to assert the default-on path
and explicit disable fallback

## Testing
- `just fmt`
- `cargo test -p codex-features`
- `cargo test -p codex-core --test all search_tool`
- `cargo test -p codex-tools`
2026-04-15 22:01:05 -07:00
Matthew Zeng 28b76d13fe [mcp] Add dummy tools for previously called but currently missing tools. (#17853)
- [x] Add dummy tools for previously called but currently missing tools.
Currently supporting MCP tools only.
2026-04-15 21:48:05 +00:00
Matthew Zeng b7139a7e8f [mcp] Support MCP Apps part 3 - Add mcp tool call support. (#17364)
- [x] Add a new app-server method so that MCP Apps can call their own
MCP server directly.
2026-04-11 04:39:19 +00:00
Matthew Zeng d7f99b0fa6 [mcp] Expand tool search to custom MCPs. (#16944)
- [x] Expand tool search to custom MCPs.
- [x] Rename several variables/fields to be more generic.

Updated tool & server name lifecycles:

**Raw Identity**

ToolInfo.server_name is raw MCP server name.
ToolInfo.tool.name is raw MCP tool name.
MCP calls route back to raw via parse_tool_name() returning
(tool.server_name, tool.tool.name).
mcpServerStatus/list now groups by raw server and keys tools by
Tool.name: mod.rs:599
App-server just forwards that grouped raw snapshot:
codex_message_processor.rs:5245

**Callable Names**

On list-tools, we create provisional callable_namespace / callable_name:
mcp_connection_manager.rs:1556
For non-app MCP, provisional callable name starts as raw tool name.
For codex-apps, provisional callable name is sanitized and strips
connector name/id prefix; namespace includes connector name.
Then qualify_tools() sanitizes callable namespace + name to ASCII alnum
/ _ only: mcp_tool_names.rs:128
Note: this is stricter than Responses API. Hyphen is currently replaced
with _ for code-mode compatibility.

**Collision Handling**

We do initially collapse example-server and example_server to the same
base.
Then qualify_tools() detects distinct raw namespace identities behind
the same sanitized namespace and appends a hash to the callable
namespace: mcp_tool_names.rs:137
Same idea for tool-name collisions: hash suffix goes on callable tool
name.
Final list_all_tools() map key is callable_namespace + callable_name:
mcp_connection_manager.rs:769

**Direct Model Tools**

Direct MCP tool declarations use the full qualified sanitized key as the
Responses function name.
The raw rmcp Tool is converted but renamed for model exposure.

**Tool Search / Deferred**

Tool search result namespace = final ToolInfo.callable_namespace:
tool_search.rs:85
Tool search result nested name = final ToolInfo.callable_name:
tool_search.rs:86
Deferred tool handler is registered as "{namespace}:{name}":
tool_registry_plan.rs:248
When a function call comes back, core recombines namespace + name, looks
up the full qualified key, and gets the raw server/tool for MCP
execution: codex.rs:4353

**Separate Legacy Snapshot**

collect_mcp_snapshot_from_manager_with_detail() still returns a map
keyed by qualified callable name.
mcpServerStatus/list no longer uses that; it uses
McpServerStatusSnapshot, which is raw-inventory shaped.
2026-04-09 13:34:52 -07:00
Matthew Zeng 7b6486a145 [mcp] Support server-driven elicitations (#17043)
- [x] Enables MCP elicitation for custom servers, not just Codex Apps
- [x] Adds an RMCP service wrapper to preserve elicitation _meta
- [x] Round-trips response _meta for persist/approval choices
- [x] Updates TUI empty-schema elicitations into message-only approval
prompts
2026-04-08 10:18:58 -07:00
Matthew Zeng 252d79f5eb [mcp] Support MCP Apps part 2 - Add meta to mcp tool call result. (#16465)
- [x] Add meta to mcp tool call result.
2026-04-07 11:10:21 -07:00
Matthew Zeng 5fe9ef06ce [mcp] Support MCP Apps part 1. (#16082)
- [x] Add `mcpResource/read` method to read mcp resource.
2026-04-06 19:17:14 -07:00
Matthew Zeng 756ba8baae Fix clippy warning (#16939)
- [x] Fix clippy warning
2026-04-06 14:08:55 -07:00
Matthew Zeng 3807807f91 [mcp] Increase MCP startup timeout. (#16080)
- [x] Increase MCP startup timeout to 30s, as the current 10s causes a
lot of local MCPs to timeout.
2026-03-28 19:58:00 -07:00
Matthew Zeng 5b71e5104f [mcp] Bypass read-only tool checks. (#16044)
- [x] Auto / unspecified approval mode: read-only tools now skip before
guardian routing.
- [x] Approve / always-allow mode: read-only tools still skip, now via
the shared early return.
- [x] Prompt mode: read-only tools no longer skip; they continue to
approval.
2026-03-27 15:22:04 -07:00
Matthew Zeng 3360f128f4 [plugins] Polish tool suggest prompts. (#15891)
- [x] Polish tool suggest prompts to distinguish between missing
connectors and discoverable plugins, and be very precise about the
triggering conditions.
2026-03-26 18:52:59 +00:00
Matthew Zeng 25134b592c [mcp] Fix legacy_tools (#15885)
- [x] Fix legacy_tools
2026-03-26 11:08:49 -07:00
Matthew Zeng c9214192c5 [plugins] Update the suggestable plugins list. (#15829)
- [x] Update the suggestable plugins list to be featured plugins.
2026-03-26 15:53:22 +00:00
Matthew Zeng 4b50446ffa [plugins] Flip flags on. (#15820)
- [x] Flip flags on.
2026-03-26 03:24:06 +00:00
Matthew Zeng 78799c1bcf [mcp] Improve custom MCP elicitation (#15800)
- [x] Support don't ask again for custom MCP tool calls.
- [x] Don't run arc in yolo mode.
- [x] Run arc for custom MCP tools in always allow mode.
2026-03-26 01:02:37 +00:00
Matthew Zeng 91337399fe [apps][tool_suggest] Remove tool_suggest's dependency on tool search. (#14856)
- [x] Remove tool_suggest's dependency on tool search.
2026-03-25 12:26:02 -07:00
Matthew Zeng e590fad50b [plugins] Add a flag for tool search. (#15722)
- [x] Add a flag for tool search.
2026-03-25 07:00:25 +00:00
Matthew Zeng 8c62829a2b [plugins] Flip on additional flags. (#15719)
- [x] Flip on additional flags.
2026-03-24 21:52:11 -07:00
Matthew Zeng 0bff38c54a [plugins] Flip the flags. (#15713)
- [x] Flip the `plugins` and `apps` flags.
2026-03-25 03:31:21 +00:00
Matthew Zeng 0b08d89304 [app-server] Add a method to override feature flags. (#15601)
- [x] Add a method to override feature flags globally and not just
thread level.
2026-03-25 02:27:00 +00:00
Matthew Zeng b32d921cd9 [plugins] Additional gating for tool suggest and apps. (#15573)
- [x] Additional gating for tool suggest and apps.
2026-03-24 15:10:00 -07:00
Matthew Zeng 19702e190e [apps] Improve app tools loading for TUI. (#15376)
- [x] Remove the app tools copy in TUI and reference the core tools
instead, this reduces tools/list calls from 4 to just 1.
2026-03-22 00:17:48 -07:00
Matthew Zeng 06e06ab173 [plugins] Fix plugin explicit mention context management. (#15372)
- [x] Fix plugin explicit mention context management.
2026-03-21 00:29:29 -07:00
Matthew Zeng dd88ed767b [apps] Use ARC for yolo mode. (#15273)
- [x] Use ARC for yolo mode.
2026-03-20 21:13:20 +00:00
Matthew Zeng 0a344e4fab [plugins] Install MCPs when calling plugin/install (#15195)
- [x] Auth MCPs when installing plugins.
2026-03-19 19:36:58 -07:00
Matthew Zeng 40a7d1d15b [plugins] Support configuration tool suggest allowlist. (#15022)
- [x] Support configuration tool suggest allowlist.

Supports both plugins and connectors.
2026-03-17 23:58:27 -07:00
Matthew Zeng 683c37ce75 [plugins] Support plugin installation elicitation. (#14896)
It now supports:

- Connectors that are from installed and enabled plugins that are not
installed yet
- Plugins that are on the allowlist that are not installed yet.
2026-03-17 13:19:28 -07:00
Matthew Zeng 029aab5563 fix(core): preserve tool_params for elicitations (#14769)
- [x] Preserve tool_params keys.
2026-03-15 23:15:52 -07:00
Matthew Zeng d4af6053e2 [apps] Improve search tool fallback. (#14732)
- [x] Bypass tool search and stuff tool specs directly into model
context when either a. Tool search is not available for the model or b.
There are not that many tools to search for.
2026-03-15 21:41:55 -07:00
Matthew Zeng 49edf311ac [apps] Add tool call meta. (#14647)
- [x] Add resource_uri and other things to _meta to shortcut resource
lookup and speed things up.
2026-03-14 22:24:13 -07:00
Matthew Zeng bc48b9289a Update tool search prompts (#14500)
- [x] Add mentions of connectors because model always think in connector
terms in its CoT.
- [x] Suppress list_mcp_resources in favor of tool search for available
apps.
2026-03-12 14:28:51 -07:00
Matthew Zeng 23e55d7668 [elicitation] User-friendly tool call messages. (#14403)
- [x] Add a curated set of tool call messages and human-readable tool
param names.
2026-03-12 00:35:21 -07:00
+15 ba5b94287e [apps] Add tool_suggest tool. (#14287)
- [x] Add tool_suggest tool.
- [x] Move chatgpt/src/connectors.rs and core/src/connectors.rs into a
dedicated mod so that we have all the logic and global cache in one
place.
- [x] Update TUI app link view to support rendering the installation
view for mcp elicitation.

---------

Co-authored-by: Shaqayeq <shaqayeq@openai.com>
Co-authored-by: Eric Traut <etraut@openai.com>
Co-authored-by: pakrym-oai <pakrym@openai.com>
Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
Co-authored-by: guinness-oai <guinness@openai.com>
Co-authored-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
Co-authored-by: Charlie Guo <cguo@openai.com>
Co-authored-by: Fouad Matin <fouad@openai.com>
Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
Co-authored-by: xl-openai <xl@openai.com>
Co-authored-by: alexsong-oai <alexsong@openai.com>
Co-authored-by: Owen Lin <owenlin0@gmail.com>
Co-authored-by: sdcoffey <stevendcoffey@gmail.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Won Park <won@openai.com>
Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
Co-authored-by: celia-oai <celia@openai.com>
Co-authored-by: gabec-openai <gabec@openai.com>
Co-authored-by: joeytrasatti-openai <joey.trasatti@openai.com>
Co-authored-by: Leo Shimonaka <leoshimo@openai.com>
Co-authored-by: Rasmus Rygaard <rasmus@openai.com>
Co-authored-by: maja-openai <163171781+maja-openai@users.noreply.github.com>
Co-authored-by: pash-openai <pash@openai.com>
Co-authored-by: Josh McKinney <joshka@openai.com>
2026-03-11 22:06:59 -07:00
f2d66fadd8 add(core): arc_monitor (#13936)
## Summary
- add ARC monitor support for MCP tool calls by serializing MCP approval
requests into the ARC action shape and sending the relevant
conversation/policy context to the `/api/codex/safety/arc` endpoint
- route ARC outcomes back into MCP approval flow so `ask-user` falls
back to a user prompt and `steer-model` blocks the tool call, with
guardian/ARC tests covering the new request shape
- update the TUI approval copy from “Approve Once” to “Allow” / “Allow
for this session” and refresh the related
  snapshots

---------

Co-authored-by: Fouad Matin <fouad@openai.com>
Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
2026-03-11 12:33:08 -07:00
Matthew Zeng 566e4cee4b [apps] Fix apps enablement condition. (#14011)
- [x] Fix apps enablement condition to check both the feature flag and
that the user is not an API key user.
2026-03-09 22:25:43 -07:00
Matthew Zeng a684a36091 [app-server] Support hot-reload user config when batch writing config. (#13839)
- [x] Support hot-reload user config when batch writing config.
2026-03-08 17:38:01 -07:00
Matthew Zeng a4a9536fd7 [elicitations] Support always allow option for mcp tool calls. (#13807)
- [x] Support always allow option for mcp tool calls, writes to
config.toml.
- [x] Fix config hot-reload after starting a new thread for TUI.
2026-03-08 01:46:40 +00:00
Matthew Zeng 98dca99db7 [elicitations] Switch to use MCP style elicitation payload for mcp tool approvals. (#13621)
- [x] Switch to use MCP style elicitation payload for mcp tool
approvals.
- [ ] TODO: Update the UI to support the full spec.
2026-03-06 01:50:26 -08:00
Matthew Zeng 3336639213 [apps] Fix the issue where apps is not enabled after codex resume. (#13533)
- [x] Fix the issue where apps is not enabled after codex resume.
2026-03-04 22:39:31 -08:00
Matthew Zeng 392fa7de50 [apps] Stablize app list updated event. (#13067)
Stablize app list updated event so that we only send 2 updates: 1 when
installed apps become available, one when all directory apps are
available. Previously it also updates when directory apps become
available before installed apps, which cuts off installed apps.
2026-02-27 15:23:24 -08:00
Matthew Zeng 6fe3dc2e22 [apps] Improve app/list with force_fetch=true (#12745)
- [x] Improve app/list with force_fetch=true, we now keep cached
snapshot until both install apps and directory apps load.
2026-02-27 03:54:03 +00:00
Matthew Zeng 36a2a9fdbb [apps] Bump MCP tool call timeout. (#12405)
- [x] Bump MCP tool call timeout.
2026-02-20 17:35:07 -08:00
Matthew Zeng 4ebdddaa34 [apps] Fix gateway url. (#12403)
- [x] Fix connectors gateway url.
2026-02-21 00:47:15 +00:00
Matthew Zeng 354e7fedd2 [apps] Enforce simple logo url format. (#12374)
- [x] Enforce simple logo url format when loading apps directory to save
bandwidth.
2026-02-20 22:05:55 +00:00
Matthew Zeng aa121a115e [apps] Implement apps configs. (#12086)
- [x] Implement apps configs.
2026-02-20 12:05:21 -08:00
Matthew Zeng 18bd6d2d71 [apps] Store apps tool cache in disk to reduce startup time. (#11822)
We now write MCP tools from installed apps to disk cache so that they
can be picked up instantly at startup. We still do a fresh fetch from
remote MCP server but it's non blocking unless there's a cache miss.

- [x] Store apps tool cache in disk to reduce startup time.
2026-02-19 22:06:51 -08:00
Matthew Zeng 18eb640a47 [apps] Update apps allowlist. (#12211)
- [x] Update apps allowlist.
2026-02-18 23:21:32 -08:00
Matthew Zeng 216fe7f2ef [apps] Temporary app block. (#12180)
- [x] Temporary app block.
2026-02-18 15:09:30 -08:00
Matthew Zeng 16fa195fce [apps] Expose more fields from apps listing endpoints. (#11706)
- [x] Expose app_metadata, branding, and labels in AppInfo.
2026-02-17 11:45:04 -08:00
Matthew Zeng 5b421bba34 [apps] Fix app mention syntax. (#11894)
- [x] Fix app mention syntax.
2026-02-16 22:01:49 +00:00
Matthew Zeng 8468871e2b [apps] Improve app listing filtering. (#11697)
- [x] If an installed app is not on the app listing, remove it from the
final list.
2026-02-13 11:54:16 -08:00
Matthew Zeng f93037f55d [apps] Fix app loading logic. (#11518)
When `app/list` is called with `force_refetch=True`, we should seed the
results with what is already cached instead of starting from an empty
list. Otherwise when we send app/list/updated events, the client will
first see an empty list of accessible apps and then get the updated one.
2026-02-13 03:55:10 +00:00
Matthew Zeng c37560069a [apps] Add is_enabled to app info. (#11417)
- [x] Add is_enabled to app info and the response of `app/list`.
- [x] Update TUI to have Enable/Disable button on the app detail page.
2026-02-13 00:30:52 +00:00
Matthew Zeng 62ef8b5ab2 [apps] Allow Apps SDK apps. (#11486)
- [x] Allow Apps SDK apps.
2026-02-11 19:18:28 -08:00
Matthew Zeng 48e415bdef [apps] Improve app installation flow. (#11249)
- [x] Add buttons to start the installation flow and verify installation
completes.
- [x] Hard refresh apps list when the /apps view opens.
2026-02-10 17:59:43 +00:00
Matthew Zeng 005e040f97 [apps] Add thread_id param to optionally load thread config for apps feature check. (#11279)
- [x] Add thread_id param to optionally load thread config for apps
feature check
2026-02-09 23:10:26 -08:00
Matthew Zeng d90df4761b [apps] Add gated instructions for Apps. (#10924)
- [x] Add gated instructions for Apps.
2026-02-09 14:48:09 -08:00
Matthew Zeng 45b7763c3f [apps] Improve app loading. (#10994)
There are two concepts of apps that we load in the harness:

- Directory apps, which is all the apps that the user can install.
- Accessible apps, which is what the user actually installed and can be
$ inserted and be used by the model. These are extracted from the tools
that are loaded through the gateway MCP.

Previously we wait for both sets of apps before returning the full apps
list. Which causes many issues because accessible apps won't be
available to the UI or the model if directory apps aren't loaded or
failed to load.

In this PR we are separating them so that accessible apps can be loaded
separately and are instantly available to be shown in the UI and to be
provided in model context. We also added an app-server event so that
clients can subscribe to also get accessible apps without being blocked
on the full app list.

- [x] Separate accessible apps and directory apps loading.
- [x] `app/list` request will also emit `app/list/updated` notifications
that app-server clients can subscribe. Which allows clients to get
accessible apps list to render in the $ menu without being blocked by
directory apps.
- [x] Cache both accessible and directory apps with 1 hour TTL to avoid
reloading them when creating new threads.
- [x] TUI improvements to redraw $ menu and /apps menu when app list is
updated.
2026-02-08 15:24:56 -08:00
Matthew Zeng 9f1009540b Upgrade rmcp to 0.14 (#10718)
- [x] Upgrade rmcp to 0.14
2026-02-08 15:07:53 -08:00
Matthew Zeng 729b016515 Add stage field for experimental flags. (#10793)
- [x] Add stage field for experimental flags.
2026-02-05 23:31:04 +00:00
Matthew Zeng 7e81f63698 [app-server] Add a method to list experimental features. (#10721)
- [x] Add a method to list experimental features.
2026-02-05 20:04:01 +00:00
Matthew Zeng acdbd8edc5 [apps] Cache MCP actions from apps. (#10662)
MCP actions take a long time to load for users with lots of apps
installed. Adding a cache for these actions with 1hr expiration, given
that they are almost always aren't going to change unless people install
another app, which means they also need to restart codex to pick it up.
2026-02-04 13:51:57 -08:00
Matthew Zeng 654fcb4962 [apps] Gateway MCP should be blocking. (#10289)
Make Apps Gateway MCP blocking since otherwise app mentions may not work
when apps are not loaded. Messages sent before apps become available
will be queued.

This only affects when `apps` feature is enabled.
2026-02-03 12:17:53 -08:00
Matthew Zeng 34f89b12d0 MCP tool call approval (simplified version) (#10200)
Add elicitation approval request for MCP tool call requests.
2026-01-29 23:40:32 -08:00
Matthew Zeng b9cd089d1f [connectors] Support connectors part 2 - slash command and tui (#9728)
- [x] Support `/apps` slash command to browse the apps in tui.
- [x] Support inserting apps to prompt using `$`.
- [x] Lots of simplification/renaming from connectors to apps.
2026-01-28 19:51:58 -08:00
Matthew Zeng 3bb8e69dd3 [skills] Auto install MCP dependencies when running skils with dependency specs. (#9982)
Auto install MCP dependencies when running skils with dependency specs.
2026-01-27 19:02:45 -08:00
Matthew Zeng 182000999c Raise welcome animation breakpoint to 37 rows (#9778)
### Motivation
- The large ASCII welcome animation can push onboarding content below
the fold on default-height terminals, making the CLI appear
unresponsive; raising the breakpoint prevents that.
- The existing test measured an arbitrary row count rather than
asserting the welcome line position relative to the animation frame,
which made the intent unclear.

### Description
- Increase `MIN_ANIMATION_HEIGHT` from `20` to `37` in
`codex-rs/tui/src/onboarding/welcome.rs` so the animation is skipped
unless there is enough vertical space.
- Replace the brittle measurement logic in the welcome render test with
a `row_containing` helper and assert the welcome row equals the frame
height plus the spacer line (`frame_lines + 1`).
- Add a regression test
`welcome_skips_animation_below_height_breakpoint` that verifies the
animation is not rendered when the viewport height is one row below the
breakpoint.

### Testing
- Ran formatting with `~/.cargo/bin/just fmt` which completed
successfully.
- Ran unit tests for the crate with `cargo test -p codex-tui --lib` and
they passed (unit test suite succeeded).
- Ran `cargo test -p codex-tui` which reported a failing integration
test in this environment because the test cannot locate the `codex`
binary, so full crate tests are blocked here (environment limitation).

------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_6973b0a710d4832c9ff36fac26eb1519)
2026-01-24 21:50:35 -08:00
Matthew Zeng a2c829a808 [connectors] Support connectors part 1 - App server & MCP (#9667)
In order to make Codex work with connectors, we add a built-in gateway
MCP that acts as a transparent proxy between the client and the
connectors. The gateway MCP collects actions that are accessible to the
user and sends them down to the user, when a connector action is chosen
to be called, the client invokes the action through the gateway MCP as
well.

 - [x] Add the system built-in gateway MCP to list and run connectors.
 - [x] Add the app server methods and protocol
2026-01-22 16:48:43 -08:00
Matthew Zeng 131590066e [device-auth] Add device code auth as a standalone option when headless environment is detected. (#9333) 2026-01-16 08:35:03 -08:00
Matthew Zeng e25d2ab3bf Fresh tooltips (#9130)
Fresh tooltips
2026-01-13 13:06:35 -08:00
Matthew Zeng 24d6e0114f [device-auth] When headless environment is detected, show device login flow instead. (#8756)
When headless environment is detected, show device login flow instead.
2026-01-08 21:48:30 -08:00
Matthew Zeng c29afc0cf3 [device-auth] Update login instruction for headless environments. (#8753)
We've seen reports that people who try to login on a remote/headless
machine will open the login link on their own machine and got errors.
Update the instructions to ask those users to use `codex login
--device-auth` instead.

<img width="1434" height="938" alt="CleanShot 2026-01-05 at 11 35 02@2x"
src="https://github.com/user-attachments/assets/2b209953-6a42-4eb0-8b55-bb0733f2e373"
/>
2026-01-05 13:46:42 -08:00