unslothai/unsloth · error · HTTPException
stdio MCP servers are disabled on this host
Error message
stdio MCP servers are disabled on this host
What it means
Raised as a 400 by the refresh endpoint when the stored server URL is a stdio:// target and stdio_mcp_enabled() reports stdio MCP disabled on the current host. Refresh reuses the stored address, so the endpoint re-applies the stdio gate: a stdio row that came from a desktop database must not be allowed to spawn a local process on a hosted/network host.
Source
Thrown at studio/backend/routes/mcp_servers.py:285
invalidate_tool_cache(server_id)
await asyncio.to_thread(close_stdio_sessions, old["url"], parse_server_headers(old))
@router.post("/{server_id}/refresh", response_model = McpServerProbeResult)
async def refresh_mcp_server_tools(
server_id: str,
current_subject: str = Depends(get_current_subject),
via_api_key: ViaApiKey = False,
):
server = mcp_servers_db.get_server(server_id)
if not server:
raise HTTPException(status_code = 404, detail = "MCP server not found")
# Refresh uses the stored address, so re-check the stdio gate here too: a
# stdio row from a desktop DB must not spawn on a hosted/network host.
if is_stdio(server["url"]):
require_ui_session_for_local_commands(via_api_key)
if not stdio_mcp_enabled():
raise HTTPException(
status_code = 400, detail = "stdio MCP servers are disabled on this host"
)
use_oauth = bool(server.get("use_oauth"))
try:
tools = await list_tools_async(
url = server["url"],
headers = parse_server_headers(server),
timeout = probe_timeout(server["url"], use_oauth),
use_oauth = use_oauth,
)
except Exception as exc: # noqa: BLE001 — surface transport+timeout errors to UI
logger.error(
"mcp_servers.refresh_failed",
server_id = server_id,
error = str(exc),
exc_info = True,
)View on GitHub (pinned to 203007d190)
Solutions
- Check the host's stdio MCP enablement setting/env flag and enable it if local process spawning is intended and safe on this host.
- If you are on a hosted/network host, delete the stdio server entry and re-add it as an HTTP/SSE MCP server instead.
- Refresh from a real UI session (not an API key) if the gate also requires an interactive session for local commands.
- Confirm is_stdio(url) classification — the URL scheme must genuinely be stdio for this branch to fire.
Defensive patterns
Strategy: validation
Validate before calling
const servers = await (await fetch('/api/mcp-servers')).json();
const srv = servers.find(s => s.id === id);
if (srv && srv.url.startsWith('stdio://')) {
const caps = await (await fetch('/api/mcp-servers/capabilities')).json(); // or host config flag
if (!caps.stdioEnabled) throw new Error('stdio MCP disabled on this host — use an HTTP MCP server');
} Try / catch
try {
await refreshMcpServer(id);
} catch (e) {
if (e.status === 400 && /stdio.*disabled/.test(e.detail)) markServerUnavailable(id);
else throw e;
} Prevention
- On hosted deployments, register stdio servers as HTTP/SSE endpoints instead.
- Never copy a desktop studio DB with stdio rows onto a hosted host.
- Surface the stdio-enabled flag in the UI so users see the limitation before adding stdio servers.
When it happens
Trigger: POST /api/mcp-servers/{id}/refresh for a server whose url starts with stdio:// while the host has stdio MCP disabled (hosted deployment, or the enabling env/config flag off), or the request arrives via an API key (via_api_key) without a UI session — require_ui_session_for_local_commands is checked first, but the 400 here is the disabled-flag branch.
Common situations: Copying a desktop studio DB (with stdio servers configured) to a hosted environment; disabling stdio servers via configuration after they were added; environment flag controlling stdio support not set on a server deployment.
Related errors
- Local commands aren't enabled on this server. To allow them,
- UNSLOTH_STUDIO_MCP_TOKEN is required when MCP is enabled
- Unsloth MCP bearer token must be a non-empty value
- Unsloth MCP bearer token must contain ASCII characters only
- command must not be empty
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/fe2db4b4312504d7.
Report an issue: GitHub.