unslothai/unsloth · critical · RuntimeError
UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled
Error message
UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled
What it means
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.
Source
Thrown at studio/backend/main.py:808
# Swagger UI and ReDoc are re-registered below on these same paths, against vendored
# assets instead of a CDN. FastAPI's built-ins point at cdn.jsdelivr.net, and this origin
# holds the auth tokens, so nothing third-party may execute here.
docs_url = None,
redoc_url = None,
swagger_ui_oauth2_redirect_url = None,
)
# The MCP surface is opt-in: it can start GPU jobs and write model artifacts.
if os.environ.get("UNSLOTH_STUDIO_ENABLE_MCP") == "1":
from fastmcp.utilities.lifespan import combine_lifespans
from mcp_server import BearerTokenMiddleware, create_studio_mcp
_studio_mcp_app = create_studio_mcp().http_app(path = "/")
_studio_mcp_lifespan = _studio_mcp_app.lifespan
_mcp_token = os.environ.get("UNSLOTH_STUDIO_MCP_TOKEN")
if not _mcp_token:
raise RuntimeError("UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled")
_studio_mcp_app = BearerTokenMiddleware(_studio_mcp_app, _mcp_token)
app.router.lifespan_context = combine_lifespans(lifespan, _studio_mcp_lifespan)
app.mount("/mcp", _studio_mcp_app)
from loggers.config import LogConfig
from loggers.handlers import LoggingMiddleware
logger = LogConfig.setup_logging(
service_name = "unsloth-studio-backend",
env = os.getenv("ENVIRONMENT_TYPE", "production"),
)
app.add_middleware(LoggingMiddleware)
class ResearchPortMiddleware:
"""Capture the bound port without replacing the ASGI receive channel."""
View on GitHub (pinned to 203007d190)
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.
Example fix
# before export UNSLOTH_STUDIO_ENABLE_MCP=1 # backend exits: token required # after export UNSLOTH_STUDIO_ENABLE_MCP=1 export UNSLOTH_STUDIO_MCP_TOKEN="$(openssl rand -hex 32)"
Defensive patterns
Strategy: validation
Validate before calling
import os
def mcp_config_valid() -> bool:
enabled = os.environ.get("UNSLOTH_STUDIO_ENABLE_MCP") == "1"
token = os.environ.get("UNSLOTH_STUDIO_MCP_TOKEN", "")
return not enabled or bool(token and token.strip() and token.isascii()) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unsloth MCP bearer token must be a non-empty value
- Unsloth MCP bearer token must contain ASCII characters only
- Error: Invalid UNSLOTH_CPU_THREADS value {_raw!r}: {exc}
- Local commands aren't enabled on this server. To allow them,
- stdio MCP servers are disabled on this host
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/c3f4cca1d2fdc76e.
Report an issue: GitHub.