codex mcp login ignores oauth_resource when MCP URL has query parameters
What version of Codex CLI is running?
codex-cli 0.147.0
What platform is your computer?
Darwin 25.5.0 arm64
What issue are you seeing?
codex mcp login <server> appears to validate OAuth protected-resource metadata against the configured MCP url including query parameters, rather than against the configured canonical oauth_resource.
This breaks OAuth login for remote Streamable HTTP MCP servers that use query parameters on the MCP endpoint for server-side tool filtering, while advertising the protected resource as the canonical base MCP endpoint.
Sanitized config shape:
[mcp_servers.private_filtered]
url = "https://mcp.example.com/mcp?toolCategories=group_a&tools=tool_a,tool_b"
oauth_resource = "https://mcp.example.com/mcp"
Running login with that configured URL fails before the browser authorization flow completes:
Error: Metadata error: Protected resource metadata resource mismatch: reference 'https://mcp.example.com/mcp?toolCategories=group_a&tools=tool_a,tool_b', permitted 'https://mcp.example.com/mcp'
Using a one-time config override to remove the query string from url allows login to complete successfully:
codex mcp -c 'mcp_servers.private_filtered.url="https://mcp.example.com/mcp"' login private_filtered
After successful login, the filtered URL remains the desired persistent configuration for normal MCP use, because the query string is how the server documents tool filtering.
What steps can reproduce the bug?
- Configure a remote Streamable HTTP MCP server whose endpoint accepts query parameters for server-side tool filtering.
- Have the server's protected-resource metadata advertise the canonical base MCP resource, e.g.
https://mcp.example.com/mcp. - Configure Codex with a filtered MCP URL and an explicit canonical OAuth resource:
``toml``
[mcp_servers.private_filtered]
url = "https://mcp.example.com/mcp?toolCategories=group_a&tools=tool_a,tool_b"
oauth_resource = "https://mcp.example.com/mcp"
- Run:
``sh``
codex mcp login private_filtered
- Observe that login fails with a protected-resource metadata mismatch where the
referenceis the full filtered URL and the permitted resource is the base URL.
- Retry with a one-time override:
``sh``
codex mcp -c 'mcp_servers.private_filtered.url="https://mcp.example.com/mcp"' login private_filtered
- Observe that login succeeds.
What is the expected behavior?
When oauth_resource is configured, codex mcp login should use that canonical resource for protected-resource metadata validation and OAuth resource handling, even if the MCP url includes query parameters used by the server for tool filtering.
The filtered url should remain usable for runtime MCP initialization/tool discovery, while oauth_resource should represent the OAuth protected resource / RFC 8707 resource value.
What actually happened?
codex mcp login used the full configured url, including query parameters, as the protected-resource metadata reference. This caused a mismatch against the server-advertised base resource, despite oauth_resource being configured to the base resource.
Additional information
This appears to be a regression: the same filtered MCP URL configuration worked before a recent Codex update, and only login now needs the base-URL override.
This is different from refresh-token resource issues: the failure happens during codex mcp login, before credentials are stored.
Workaround:
codex mcp -c 'mcp_servers.private_filtered.url="https://mcp.example.com/mcp"' login private_filtered
The workaround is not ideal because the persistent config should keep the server-side query filtering in url for normal MCP usage.
2 Comments
Additional sanitized evidence after restarting Codex:
This is not limited to
codex mcp login. Runtime MCP startup also fails with the same protected-resource metadata mismatch when the persistenturlcontains query parameters andoauth_resourceis set to the canonical base resource.Sanitized startup error shape:
So the current workaround is broader than just login:
This avoids startup failure, but it means users cannot keep server-side tool filtering query parameters in the persistent MCP URL on Codex CLI 0.147.0, even when the canonical OAuth resource is configured explicitly.
same here