{"record":{"id":"314d691db50975c2","repo":"HKUDS/DeepTutor","slug":"error","errorCode":null,"errorMessage":"{error}","messagePattern":"\\{error\\}","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"deeptutor/api/routers/mcp_settings.py","lineNumber":132,"sourceCode":"    await manager.reload()\n    return {\n        \"servers\": {key: value.model_dump(mode=\"json\") for key, value in updated.servers.items()},\n        \"status\": manager.status(),\n    }\n\n\n@router.post(\"/test\")\nasync def test_mcp_server(cfg: MCPServerConfig) -> dict[str, Any]:\n    transport = cfg.resolved_type()\n    if transport is None:\n        raise HTTPException(\n            status_code=400,\n            detail=t(\"mcp.configure_before_testing\"),\n        )\n    if transport in {\"sse\", \"streamableHttp\"}:\n        ok, error = validate_mcp_url(cfg.url)\n        if not ok:\n            raise HTTPException(status_code=400, detail=error)\n    return await probe_server(cfg)\n","sourceCodeStart":114,"sourceCodeEnd":134,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/api/routers/mcp_settings.py#L114-L134","documentation":"Raised by POST /test when the server config declares an SSE/streamableHttp transport but its url fails validate_mcp_url; unlike the save-path equivalent, the raw validation error string is returned directly as the 400 detail (no i18n wrapper).","triggerScenarios":"POST /mcp/test with a body containing a url like '127.0.0.1:9000/sse' (missing scheme) or another malformed/unsupported URL, with the transport resolved to sse or streamableHttp.","commonSituations":"Quickly testing a locally-running MCP server and forgetting the http:// prefix; copy-paste of endpoints from logs or docs with truncated URLs; testing before checking how the config was saved.","solutions":["Correct the URL to a full form like http://127.0.0.1:9000/sse and re-test","Read the returned error string — it comes straight from validate_mcp_url and states the precise problem","Confirm the server you meant to test actually exposes an SSE/streamable-HTTP endpoint at that URL"],"exampleFix":"// before\nawait api.post('/mcp/test', { name: 'local', url: 'localhost:9000/sse' });\n\n// after\nawait api.post('/mcp/test', { name: 'local', url: 'http://localhost:9000/sse' });","handlingStrategy":"validation","validationCode":"function isHttpUrl(s: string): boolean {\n  try {\n    const u = new URL(s);\n    return u.protocol === 'http:' || u.protocol === 'https:';\n  } catch {\n    return false;\n  }\n}\nif (cfg.url && !isHttpUrl(cfg.url)) throw new Error(`Invalid MCP url: ${cfg.url}`);\nawait api.post('/mcp/test', cfg);","typeGuard":"function isHttpUrl(s: string): s is string {\n  return /^https?:\\/\\/.+/.test(s);\n}","tryCatchPattern":"try {\n  await api.post('/mcp/test', cfg);\n} catch (e) {\n  if (e.status === 400 && typeof e.detail === 'string' && /url/i.test(e.detail)) {\n    // e.detail is the raw validator message; fix the url and re-test\n  }\n}","preventionTips":["Autocomplete/prepend http:// or https:// in url input fields","Validate the URL client-side before invoking /test"],"tags":["mcp","url","test","validation"],"backgroundTag":"invalid-url-scheme","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}