Support `resources/subscribe` for MCP resources as a client (resource notification subscriptions)
What variant of Codex are you using?
CLI, Desktop App, IDE Extensions
What feature would you like to see?
Feature: Codex should support subscribing to MCP resources (resources/subscribe) as an MCP client
Problem
Codex currently implements listing and reading MCP resources as a client (resources/list, resources/read, and resources/templates/list) but does not support subscribing to resource notifications via resources/subscribe or resources/unsubscribe or handling notifications/resources/updated and related events as a client.
This means:
- Resource caches in Codex can get stale with no way to keep them up to date when MCP servers change or publish new resources.
- Live update scenarios relying on the MCP spec for resource change invalidation (see MCP spec "Server Resources" section) aren't functional -- even though the underlying SDK provides the wire format.
- There's no extension point for users to auto-inject dynamic context into
messages[]without modifying codex-rs source. MCP resource subscriptions would naturally fill this gap.
Current state
(This was AI-assisted.)
| MCP Capability | Codex Support | Location |
|---|---|---|
| resources/list | ✅ via list_mcp_resources tool | mcp_resource.rs, mcp_connection_manager.rs |
| resources/read | ✅ via read_mcp_resource tool | mcp_resource.rs |
| resources/templates/list | ✅ via list_mcp_resource_templates tool | mcp_resource.rs |
| resources/subscribe | ❌ Not implemented | -- |
| resources/unsubscribe | ❌ Not implemented | -- |
| notifications/resources/updated | ⚠️ Received but only logged | logging_client_handler.rs:71-77 |
| notifications/resources/list_changed | ⚠️ Received but only logged | logging_client_handler.rs:79-81 |
Implementation plan
(This was AI-assisted.)
Phase 1: Wire up subscription lifecycle
- Give
LoggingClientHandler(or a replacement) an event channel soon_resource_updatedandon_resource_list_changedforward events toMcpConnectionManagerinstead of just logging them. - Add
resources/subscribeandresources/unsubscribeclient methods onMcpConnectionManagerusing the existing rmcp wire types (SubscribeRequestParams,UnsubscribeRequestParams). - During
McpConnectionManager::new(), after a server reachesReady, check if it advertisescapabilities.resources.subscribe == true. If so, enumerate resources viaresources/listand subscribe to all of them.
Phase 2: Resource cache invalidation
- Add a per-server resource cache (
HashMap<String, HashMap<String, CachedResource>>) toMcpConnectionManager. Populate on first list/read, invalidate entries onResourceEvent::Updated. - On
ResourceEvent::ListChanged, re-issueresources/list, diff against the cached list, subscribe to new resources, unsubscribe from removed ones.
Phase 3: Auto-inject into messages[]
This is the key payoff -- subscriptions become an extension point for the model context pipeline:
- Add an
mcp_resource_contextfield toTurnContextItem(URI -> content snapshot). - Populate it in
make_turn_context()/to_turn_context_item()from the cached subscribed resources. - Add a
build_mcp_resource_update_item()diff function incontext_manager/updates.rsalongside the existingbuild_permissions_update_item,build_collaboration_mode_update_item, etc. Wire it intobuild_settings_update_items(). - Optionally, on mid-turn
ResourceEvent::Updated, queue updated content viaqueue_response_items_for_next_turn()for immediate injection.
Phase 4: Configuration
Allow users to control subscription behavior in config.toml:
[mcp_resources]
auto_subscribe = true # subscribe to all resources from all servers
auto_inject = true # inject subscribed resource content into model context
max_inject_size = 8192 # cap total injected resource content (bytes)
References
- Original acceptance criteria for resource support in #4956 asked for cache updating via notifications.
- Current stub code only logs resource notification events, notifies nothing, and never subscribes.
- See MCP spec: https://modelcontextprotocol.io/specification/2025-11-25/server/resources#subscribing-to-resource-updates
Impact
- Enables Codex agents to keep MCP resource state in sync with underlying MCP servers
- Creates a first-class extension point for injecting dynamic context into the model -- users can write an MCP server that exposes a resource, and Codex will auto-inject updates into
messages[]without any source changes - Reduces stale data risk and aligns Codex with MCP spec and other major clients
- Fixes a gap identified in the closure of #4956 / PR #5239 -- subscription support was scoped out despite being part of the original design
Additional information
The initial implementation in #5239 and tracking in #4956 covered listing/reading resources, but not subscribing or notification flow in the client. See those as context for demand and scope. Current state: Codex logs resource notifications but does not act on them, and never issues subscribe/unsubscribe requests as a client.
This is about the Codex client role, not MCP server implementation.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗