odysseus-dev/odysseus · error · HTTPException
url is required for HTTP transport
Error message
url is required for HTTP transport
What it means
Same registration endpoint as the SSE check: transport="http" (streamable HTTP transport) requires a url. The validation runs after require_admin, so it also implies you are authenticated as an admin; a missing url yields 400 before the server record is created.
Source
Thrown at routes/mcp/mcp_routes.py:182
args: str = Form("[]"),
env: str = Form("{}"),
url: str = Form(None),
oauth_file: str = Form(None),
oauth_config: str = Form(None),
):
"""Add a new MCP server config and attempt connection. Admin-only:
registering a stdio server is equivalent to executing arbitrary
binaries on the host."""
require_admin(request)
server_id = str(uuid.uuid4())[:8]
# Validate
if transport == "stdio" and not command:
raise HTTPException(400, "command is required for stdio transport")
if transport == "sse" and not url:
raise HTTPException(400, "url is required for SSE transport")
if transport == "http" and not url:
raise HTTPException(400, "url is required for HTTP transport")
# Parse JSON fields
try:
parsed_args = json.loads(args) if args else []
except json.JSONDecodeError:
parsed_args = []
try:
parsed_env = json.loads(env) if env else {}
except json.JSONDecodeError:
parsed_env = {}
if not isinstance(parsed_env, dict):
parsed_env = {}
# Parse OAuth config
parsed_oauth_config = None
if oauth_config:
try:
parsed_oauth_config = _sanitize_mcp_oauth_config(json.loads(oauth_config))View on GitHub (pinned to f9235ebbf1)
Solutions
- Send url as a form field, e.g. url="https://mcp.example.com/mcp" with transport="http".
- Double-check the form field name is exactly 'url' and the request is multipart/form-data or application/x-www-form-urlencoded.
- Test the URL with curl first — a reachable endpoint avoids a follow-up connect failure after registration.
Example fix
# before
data = {"transport": "http"}
# after
data = {"transport": "http", "url": "https://mcp.example.com/mcp"} Defensive patterns
Strategy: validation
Validate before calling
def http_config_valid(data: dict) -> bool:
return data.get("transport") != "http" or bool(data.get("url")) Try / catch
Catch the 400 and correct the form payload; the endpoint is transactional — no partial server is created.
Prevention
- Use one shared request-builder that enforces per-transport required fields.
- Smoke-test the URL's reachability before registering.
When it happens
Trigger: POST with transport="http" and no url form field; url present but empty string; sending the url in a JSON body while the endpoint expects Form fields.
Common situations: Newer streamable-HTTP MCP server registered with the wrong field name; client switched transport dropdown to http without filling the endpoint; env-specific URL not templated into the request.
Related errors
- url is required for SSE transport
- Email account not found for selector {account!r}. Available
- command is required for stdio transport
- disabled must be a list of tool names
- Server has no OAuth config
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/cec5147b0f5cfacd.
Report an issue: GitHub.