From 3392cd0e98d5c9fdb22846e6ba627085d6b250ef Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:44:19 +0000 Subject: [PATCH] fix(mcp): URL-encode server_id in env-var setup deep link --- litellm/proxy/_experimental/mcp_server/utils.py | 3 ++- .../_experimental/mcp_server/test_mcp_env_vars.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/_experimental/mcp_server/utils.py b/litellm/proxy/_experimental/mcp_server/utils.py index dcaa77261cb..97cfa74ea45 100644 --- a/litellm/proxy/_experimental/mcp_server/utils.py +++ b/litellm/proxy/_experimental/mcp_server/utils.py @@ -20,6 +20,7 @@ from typing import ( import hashlib import importlib import os +from urllib.parse import quote # Constants LITELLM_MCP_SERVER_NAME = "litellm-mcp-server" @@ -501,7 +502,7 @@ def interpolate_headers( def build_env_var_setup_url(server_id: str) -> str: """The frontend URL where a user can fill in their per-user env vars.""" base = os.environ.get("PROXY_BASE_URL", "").rstrip("/") - path = f"/ui/?page=mcp-servers&fill_env_vars={server_id}" + path = f"/ui/?page=mcp-servers&fill_env_vars={quote(server_id, safe='')}" return f"{base}{path}" if base else path diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_env_vars.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_env_vars.py index ffed81d7aa9..d48beeb9069 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_env_vars.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_env_vars.py @@ -106,6 +106,17 @@ def test_build_env_var_setup_url_prepends_proxy_base_url(monkeypatch): assert "fill_env_vars=abc-123" in url +def test_build_env_var_setup_url_encodes_unsafe_server_id(monkeypatch): + from urllib.parse import parse_qs, urlsplit + + monkeypatch.delenv("PROXY_BASE_URL", raising=False) + server_id = "a&b=c #d/e" + url = _u("build_env_var_setup_url")(server_id) + assert "a&b=c #d/e" not in url + parsed = parse_qs(urlsplit(url).query) + assert parsed["fill_env_vars"] == [server_id] + + def test_missing_user_env_vars_error_message_is_friendly(): with pytest.raises(_u("MCPMissingUserEnvVarsError")) as exc_info: raise _u("MCPMissingUserEnvVarsError")(