diff --git a/reme/components/service/http_service.py b/reme/components/service/http_service.py index 029db215..fd64e780 100644 --- a/reme/components/service/http_service.py +++ b/reme/components/service/http_service.py @@ -205,7 +205,7 @@ class HttpService(BaseService): ) if "//" in path or any(segment in {".", ".."} for segment in path.split("/")): raise ValueError("mcp_path must use non-empty literal path segments") - if any(char in path for char in "{}?#\\") or any( + if any(char in path for char in "{}?#%\\") or any( char.isspace() or ord(char) < 32 or ord(char) == 127 for char in path ): raise ValueError("mcp_path must be a literal URL path without route, query, or fragment syntax") diff --git a/tests/unit/test_http_web_workspace.py b/tests/unit/test_http_web_workspace.py index 4d6fc994..2df1f762 100644 --- a/tests/unit/test_http_web_workspace.py +++ b/tests/unit/test_http_web_workspace.py @@ -194,6 +194,9 @@ def test_http_service_rejects_invalid_or_conflicting_mcp_paths() -> None: "/{rest:path}", "/mcp?mode=test", "/mcp#fragment", + "/mcp%2Fv2", + "/mcp%20v2", + "/mcp%252Fv2", "/mcp path", "/mcp//nested", "/mcp/../nested",