{"record":{"id":"dba7fd9fc978a90f","repo":"HKUDS/Vibe-Trading","slug":"oauth-mcp-servers-require-an-https-url","errorCode":null,"errorMessage":"OAuth MCP servers require an https url","messagePattern":"OAuth MCP servers require an https url","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/config/schema.py","lineNumber":410,"sourceCode":"                raise ValueError(\"stdio MCP servers do not accept auth (OAuth is HTTP-only)\")\n            return self\n\n        if not self.url.strip():\n            raise ValueError(f\"{transport} MCP servers require a url\")\n        if self.command.strip() or self.args or self.env:\n            raise ValueError(f\"{transport} MCP servers do not accept command/args/env\")\n\n        if self.auth is not None:\n            # The OAuth provider owns the runtime Authorization header; a\n            # hand-set static header alongside it is always a config error.\n            if self.headers:\n                raise ValueError(\n                    \"MCP servers using auth must not also set static headers \"\n                    \"(the OAuth provider owns the Authorization header)\"\n                )\n            # A refresh token must never traverse cleartext.\n            if not self.url.strip().lower().startswith(\"https://\"):\n                raise ValueError(\"OAuth MCP servers require an https url\")\n        return self\n\n\nclass MCPServerConfigOverride(ConfigBase):\n    \"\"\"Partial MCP server override used for runtime config layering.\"\"\"\n\n    type: Literal[\"stdio\", \"sse\", \"streamableHttp\"] | None = None\n    command: str | None = None\n    args: list[str] | None = None\n    env: dict[str, str] | None = None\n    url: str | None = None\n    headers: dict[str, str] | None = None\n    auth: MCPOAuthConfig | None = None\n    tool_timeout: float | None = Field(default=None, ge=0.1)\n    init_timeout: float | None = Field(default=None, ge=0.1)\n    enabled_tools: list[str] | None = None\n\n","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/config/schema.py#L392-L428","documentation":"Raised by validate_transport_config when a server with an auth (OAuth) block uses a url that does not start with https://. OAuth refresh tokens must never travel over cleartext, so http:// endpoints are rejected outright.","triggerScenarios":"An auth-configured server with url starting with http:// or any non-https scheme; local development against http://localhost with real OAuth credentials.","commonSituations":"Local dev against a non-TLS proxy; typo dropping the 's' in https; on-prem servers without TLS where OAuth was enabled anyway.","solutions":["Switch the url to https:// (terminate TLS at a proxy if the backend is plain HTTP).","For local testing without OAuth, remove the auth block — plain http is then permitted.","For local OAuth testing, use a self-signed cert with https and trust it appropriately."],"exampleFix":"# before\nurl: http://localhost:8080/mcp\nauth: {client_id: abc}\n\n# after\nurl: https://localhost:8443/mcp\nauth: {client_id: abc}","handlingStrategy":"validation","validationCode":"def auth_url_is_https(entry: dict) -> bool:\n    if entry.get('auth') is not None:\n        return str(entry.get('url', '')).strip().lower().startswith('https://')\n    return True","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Terminate TLS at a reverse proxy for local OAuth testing","Never point OAuth-configured servers at http:// endpoints"],"tags":["mcp","oauth","https","security","config"],"backgroundTag":"insecure-transport-rejected","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}