litellm/tests/test_litellm/proxy/_experimental/mcp_server
tin-berri c370503091
Some checks are pending
GitHub Actions Security Analysis / zizmor (push) Waiting to run
fix(mcp): gate OAuth authorize/token/register/discovery on auth_type=oauth2 (#31736)
* fix(mcp): gate OAuth authorize/token/register/discovery on auth_type=oauth2

A non-oauth2 MCP server (notably auth_type=none, access-group gated) has no
client_id and no authorization URL, yet the gateway OAuth endpoints did not
check auth_type. authorize() raised "client_id is required" before the
auth_type was ever examined, and the .well-known discovery builders always
advertised authorization_servers / authorization_endpoint / token_endpoint /
registration_endpoint, so spec-compliant MCP clients were pointed at an OAuth
flow that can never succeed.

Add an auth_type != oauth2 guard to the authorize, token, register,
protected-resource and authorization-server paths (covering the internal UI
OAuth endpoints too). The discovery guard sits after the OAuth pass-through
branch so genuine pass-through servers keep proxying their upstream metadata.
oauth2 servers are unaffected.

* fix(mcp): accurate non-oauth2 message; 404 unknown discovery names to close enumeration oracle

Address review feedback on the auth_type gate.

The 400 message no longer claims access is governed by access groups, which is
only true for auth_type=none; it now states that the gateway runs the OAuth
client_id/authorize/token/register flow only for oauth2 servers and that the
server is reached using its configured auth_type, which is accurate for every
non-oauth2 type (api_key, oauth2_token_exchange, etc.).

The discovery gate previously 404'd a named non-oauth2 server but still returned
200 metadata for an unknown name, which both serves a broken document for a typo
and lets an unauthenticated caller enumerate non-OAuth server names by comparing
404 vs 200. A named discovery request now returns 200 only when it resolves to an
oauth2 server; unknown (or hidden) and non-oauth2 names return the same 404. Root
discovery and pass-through servers are unaffected.

* Apply suggestions from code review

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-07-02 10:24:12 -07:00
..
auth fix(mcp): support client_secret_basic for upstream OAuth token endpoints (#31635) 2026-06-29 20:41:23 -07:00
guardrail_translation fix(tests): Add missing mocks for MCP IP filtering and updated APIs (#20652) 2026-02-07 11:30:49 -08:00
outbound_credentials fix(mcp): support client_secret_basic for upstream OAuth token endpoints (#31635) 2026-06-29 20:41:23 -07:00
test_byok_oauth_endpoints.py feat(mcp): allow native MCP OAuth support for cursor (#28327) 2026-05-20 15:28:44 -07:00
test_callback_oauth_error_responses.py Litellm oss staging 250526 (#28770) 2026-05-26 11:57:39 -07:00
test_db_credentials.py fix(mcp): support client_secret_basic for upstream OAuth token endpoints (#31635) 2026-06-29 20:41:23 -07:00
test_discoverable_endpoints.py fix(mcp): gate OAuth authorize/token/register/discovery on auth_type=oauth2 (#31736) 2026-07-02 10:24:12 -07:00
test_is_tool_name_prefixed.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_jwt_mcp_enforcement.py fix(mcp): resolve team.access_group_ids → MCP servers (#28997) 2026-05-27 12:36:50 -07:00
test_jwt_mcp_simple.py fix(mcp): resolve team.access_group_ids → MCP servers (#28997) 2026-05-27 12:36:50 -07:00
test_mcp_cost_calculator.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_mcp_custom_fields.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_mcp_debug.py chore: litellm oss staging (#30968) 2026-06-23 07:31:44 -07:00
test_mcp_discovery.py fix(mcp): default Linear MCP registry entry to streamable HTTP (#30396) 2026-06-13 14:45:47 -07:00
test_mcp_elicitation_handler.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_env_vars.py fix(mcp): drop orphaned per-user credential rows when an MCP server is deleted (#30141) 2026-06-10 15:56:58 -07:00
test_mcp_header_alias_utils.py feat(mcp): Add tool call and tool list support via UI for Oauth mcps (#28454) 2026-05-22 09:04:04 -07:00
test_mcp_hook_extra_headers.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_metadata_preservation.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_mcp_oauth_passthrough.py [internal copy of #28008] Support MCP OAuth passthrough and issuer-scoped JWT auth (#28356) 2026-06-02 12:22:04 -07:00
test_mcp_oauth_passthrough_cold_start.py [internal copy of #28008] Support MCP OAuth passthrough and issuer-scoped JWT auth (#28356) 2026-06-02 12:22:04 -07:00
test_mcp_oauth_passthrough_tools.py fix(mcp): stop one unauthenticated server from emptying the aggregate tools/list (#31684) 2026-06-30 11:58:47 -07:00
test_mcp_partial_update.py fix(mcp): clear allowed_tools and tool overrides on MCP server edit (#29411) 2026-06-01 21:28:29 -07:00
test_mcp_sampling_completion_flow.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_model_access.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_model_resolution.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_priority_selection.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_request_builder.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_response_conversion.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_sampling_tool_conversion.py Litellm oss staging 040626 (#29671) 2026-06-04 11:07:20 -07:00
test_mcp_server.py fix(mcp): roll up MCP tool spend to user counters and usage UI (#31576) 2026-07-02 08:16:39 -07:00
test_mcp_server_identity_env.py chore: litellm oss 170626 (#30637) 2026-06-17 21:11:12 -07:00
test_mcp_server_manager.py fix(mcp): byom visibility, preview UX, and admin settings gating (#31809) 2026-07-02 01:04:22 -07:00
test_mcp_session_logging.py Add MCP semantic conventions to otelv2 (#29468) 2026-06-02 11:45:36 -07:00
test_mcp_sigv4_auth.py feat(mcp): per-server env vars with global + per-user scopes (#28917) 2026-06-05 20:15:11 -07:00
test_mcp_stale_session.py feat(mcp): migrate authorization_code MCP to the v2 resolver (single-replica) [1/2] (#31473) 2026-06-26 21:19:57 -07:00
test_mcp_tool_search.py fix(mcp): roll up MCP tool spend to user counters and usage UI (#31576) 2026-07-02 08:16:39 -07:00
test_mcp_toolset_scope.py fix(mcp): resolve toolset tools by the server's known prefix (#31254) 2026-06-24 20:50:16 -07:00
test_oauth2_token_cache.py fix(mcp): support client_secret_basic for upstream OAuth token endpoints (#31635) 2026-06-29 20:41:23 -07:00
test_openapi_to_mcp_generator.py fix(mcp): forward extra_headers for OpenAPI MCP tools (#27383) 2026-05-09 15:10:54 -04:00
test_openapi_tool_auth.py fix(mcp): use canonical proxy_logging_obj, deny when MCP server is unresolvable 2026-05-01 22:28:46 +00:00
test_rest_endpoints.py fix(mcp): roll up MCP tool spend to user counters and usage UI (#31576) 2026-07-02 08:16:39 -07:00
test_semantic_tool_filter.py chore: litellm oss staging (#30968) 2026-06-23 07:31:44 -07:00
test_short_mcp_tool_prefix.py fix(mcp): resolve toolset tools by the server's known prefix (#31254) 2026-06-24 20:50:16 -07:00
test_ui_session_utils.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00