{"record":{"id":"9dafce540b4c8bb7","repo":"HKUDS/DeepTutor","slug":"mcp-no-transport","errorCode":"mcp.no_transport","errorMessage":"Provide an http(s) URL for the server","messagePattern":"Provide an http\\(s\\) URL for the server","errorType":"error_code","errorClass":"UserMcpError","httpStatus":400,"severity":"error","filePath":"deeptutor/services/mcp/user_config.py","lineNumber":185,"sourceCode":"    *,\n    validate_url: bool = False,\n) -> None:\n    if not _SERVER_NAME_RE.match(name):\n        raise UserMcpError(\"mcp.invalid_name\", f\"Invalid server name {name!r}\")\n    if name.startswith(_RESERVED_NAME_PREFIXES):\n        raise UserMcpError(\n            \"mcp.name_reserved\",\n            f\"{name!r} starts with a reserved tool-name prefix\",\n        )\n    transport = cfg.resolved_type()\n    if transport == \"stdio\" or cfg.command:\n        raise UserMcpError(\n            \"mcp.stdio_not_allowed\",\n            \"A server you configure yourself must be a remote URL: a stdio \"\n            \"server runs a command on the host and stays administrator-only.\",\n        )\n    if transport not in (\"sse\", \"streamableHttp\"):\n        raise UserMcpError(\"mcp.no_transport\", \"Provide an http(s) URL for the server\")\n    if validate_url:\n        ok, error = validate_mcp_url(cfg.url, strict=True)\n        if not ok:\n            raise UserMcpError(\"mcp.blocked_url\", error)\n\n\ndef _read_raw(owner_id: str) -> MCPConfig:\n    \"\"\"The file as stored, *without* the connectability filtering.\n\n    Writes must preserve entries this deployment refuses to connect (a stdio\n    entry left over from a hand edit), or saving one server would silently\n    delete another.\n    \"\"\"\n    path = user_mcp_path(owner_id)\n    if not path.exists():\n        return MCPConfig()\n    try:\n        return MCPConfig.model_validate(json.loads(path.read_text(encoding=\"utf-8\")))","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/mcp/user_config.py#L167-L203","documentation":"After excluding stdio, the user-configured server's transport must be one of the remote types 'sse' or 'streamableHttp'. Any other resolved transport (or an empty/unrecognized type) means no usable remote URL was supplied, so the config is rejected.","triggerScenarios":"Saving or loading a user MCP server whose resolved_type() returns something other than 'stdio' but also not 'sse' or 'streamableHttp' — e.g. type is None, misspelled ('http' instead of 'streamableHttp'), or unset with no URL to infer from.","commonSituations":"Omitting the type field and the URL inference logic can't classify it; typos in the transport field like 'streamable_http' or 'HTTP'; schema drift after upgrading the config format.","solutions":["Set type explicitly to 'sse' or 'streamableHttp' (most modern servers use streamableHttp)","Provide a proper http(s) URL so the transport can be inferred correctly","Validate the config against the current MCP config schema after upgrading DeepTutor"],"exampleFix":"# before\ncfg = McpServerConfig(url=\"https://mcp.example.com/mcp\", type=\"http\")\n# after\ncfg = McpServerConfig(url=\"https://mcp.example.com/mcp\", type=\"streamableHttp\")","handlingStrategy":"validation","validationCode":"ALLOWED_TRANSPORTS = {\"sse\", \"streamableHttp\"}\n\ndef has_valid_transport(cfg) -> bool:\n    return cfg.resolved_type() in ALLOWED_TRANSPORTS","typeGuard":null,"tryCatchPattern":"try:\n    await save_user_server(user_id, name, cfg)\nexcept UserMcpError as e:\n    if e.code == \"mcp.no_transport\":\n        cfg.type = \"streamableHttp\"  # sensible default for http(s) URLs\n        await save_user_server(user_id, name, cfg)\n    else:\n        raise","preventionTips":["Always set type explicitly when constructing server configs","Restrict the transport field in forms to a dropdown of sse/streamableHttp"],"tags":["mcp","transport","url","config-validation"],"backgroundTag":"unsupported-transport-type","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}