{"record":{"id":"c3f4cca1d2fdc76e","repo":"unslothai/unsloth","slug":"unsloth-studio-mcp-token-is-required-when-mcp-is-e","errorCode":null,"errorMessage":"UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled","messagePattern":"UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"studio/backend/main.py","lineNumber":808,"sourceCode":"    # Swagger UI and ReDoc are re-registered below on these same paths, against vendored\n    # assets instead of a CDN. FastAPI's built-ins point at cdn.jsdelivr.net, and this origin\n    # holds the auth tokens, so nothing third-party may execute here.\n    docs_url = None,\n    redoc_url = None,\n    swagger_ui_oauth2_redirect_url = None,\n)\n\n# The MCP surface is opt-in: it can start GPU jobs and write model artifacts.\nif os.environ.get(\"UNSLOTH_STUDIO_ENABLE_MCP\") == \"1\":\n    from fastmcp.utilities.lifespan import combine_lifespans\n\n    from mcp_server import BearerTokenMiddleware, create_studio_mcp\n\n    _studio_mcp_app = create_studio_mcp().http_app(path = \"/\")\n    _studio_mcp_lifespan = _studio_mcp_app.lifespan\n    _mcp_token = os.environ.get(\"UNSLOTH_STUDIO_MCP_TOKEN\")\n    if not _mcp_token:\n        raise RuntimeError(\"UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled\")\n    _studio_mcp_app = BearerTokenMiddleware(_studio_mcp_app, _mcp_token)\n    app.router.lifespan_context = combine_lifespans(lifespan, _studio_mcp_lifespan)\n    app.mount(\"/mcp\", _studio_mcp_app)\n\nfrom loggers.config import LogConfig\nfrom loggers.handlers import LoggingMiddleware\n\nlogger = LogConfig.setup_logging(\n    service_name = \"unsloth-studio-backend\",\n    env = os.getenv(\"ENVIRONMENT_TYPE\", \"production\"),\n)\n\napp.add_middleware(LoggingMiddleware)\n\n\nclass ResearchPortMiddleware:\n    \"\"\"Capture the bound port without replacing the ASGI receive channel.\"\"\"\n","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/main.py#L790-L826","documentation":"Raised at app assembly time when UNSLOTH_STUDIO_ENABLE_MCP=1 but UNSLOTH_STUDIO_MCP_TOKEN is unset or empty. The MCP surface can start GPU jobs and write model artifacts, so the backend refuses to mount it unauthenticated rather than shipping an open endpoint.","triggerScenarios":"Enabling the MCP server with UNSLOTH_STUDIO_ENABLE_MCP=1 while forgetting to set UNSLOTH_STUDIO_MCP_TOKEN, or setting it to an empty string ('UNSLOTH_STUDIO_MCP_TOKEN='), in the process environment before main.py builds the FastAPI app.","commonSituations":"Following MCP setup docs that mention the enable flag but not the token; deploying with a secrets file that failed to load so the env var is missing; CI pipelines enabling MCP for testing without credentials.","solutions":["Generate a strong secret (e.g. openssl rand -hex 32) and export it as UNSLOTH_STUDIO_MCP_TOKEN before starting the backend.","If MCP is not intended, unset UNSLOTH_STUDIO_ENABLE_MCP (anything other than '1' disables it) instead of supplying a token.","If using a secret manager, verify the variable actually lands in the process env (printenv UNSLOTH_STUDIO_MCP_TOKEN in the same context that launches the app).","Restart the backend after setting both variables."],"exampleFix":"# before\nexport UNSLOTH_STUDIO_ENABLE_MCP=1\n# backend exits: token required\n# after\nexport UNSLOTH_STUDIO_ENABLE_MCP=1\nexport UNSLOTH_STUDIO_MCP_TOKEN=\"$(openssl rand -hex 32)\"","handlingStrategy":"validation","validationCode":"import os\n\ndef mcp_config_valid() -> bool:\n    enabled = os.environ.get(\"UNSLOTH_STUDIO_ENABLE_MCP\") == \"1\"\n    token = os.environ.get(\"UNSLOTH_STUDIO_MCP_TOKEN\", \"\")\n    return not enabled or bool(token and token.strip() and token.isascii())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat UNSLOTH_STUDIO_ENABLE_MCP and UNSLOTH_STUDIO_MCP_TOKEN as a paired setting in config templates.","Fail deployment preflight if MCP is enabled without a non-empty ASCII token.","Generate tokens with 'openssl rand -hex 32' — never reuse or hand-type them."],"tags":["mcp","auth","env","security","startup"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}