[Draft][WIP] studio: import MCP servers from a config file#5943
[Draft][WIP] studio: import MCP servers from a config file#5943rolandtannous wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to bulk-import Model Context Protocol (MCP) servers from standard JSON configuration files (such as those from Claude Desktop, Cursor, Cline, or VS Code). On the backend, it adds a parsing utility, request/response models, a new /import API endpoint, and corresponding unit tests. On the frontend, it adds API client support and an 'Import config' button to the MCP servers dialog. Feedback suggests adding defensive validation on the frontend to ensure the parsed JSON is a non-null object before sending it to the backend.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| let config: unknown; | ||
| try { | ||
| config = JSON.parse(await file.text()); | ||
| } catch { | ||
| toast.error("Invalid JSON file"); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Defensively validate that the parsed JSON config is a non-null object and not an array before sending it to the backend. This prevents unnecessary API requests and provides a more specific, immediate error message to the user if they upload an invalid JSON structure.
let config: unknown;
try {
config = JSON.parse(await file.text());
} catch {
toast.error("Invalid JSON file");
return;
}
if (!config || typeof config !== "object" || Array.isArray(config)) {
toast.error("Invalid config format: must be a JSON object");
return;
}
|
I have tried loading all these mcp.jsons with the PR code and can confirm they all load successfully: Some include HTTP servers and these are imported too. None contain request headers, but I confirmed separately that this example with a header works: |
Summary
Addresses #5936. Adds the ability to import MCP servers from a standard
mcpServersJSON config file — the same format used by Claude Desktop, Cursor, Cline, and VS Code — into Unsloth Studio.Native stdio MCP support already landed in #5863 (the backend spawns local processes via fastmcp's
StdioTransport, gated byUNSLOTH_STUDIO_ALLOW_STDIO_MCP=1), so no supergateway bridge is needed to run a stdio server. The remaining gap from #5936 was the "register each URL manually in the UI" friction: there was no way to bulk-import the standard config. This PR closes that gap with no DB schema change — it reuses the existingurl/headers_jsonstorage overload, validation, and stdio gate.What's included
Backend
core/inference/mcp_client.py—join_stdio_command(parts), the round-trip-safe inverse ofparse_stdio_command(subprocess.list2cmdlineon win32,shlex.joinon posix).core/inference/mcp_config_import.py(new) —parse_mcp_config(config) -> (entries, errors). AcceptsmcpServers(primary) andservers(VS Code alias); supports stdio (command+args+env) and remote (url+headers); a single bad entry becomes a reported error rather than sinking the batch. stdlib-only.models/mcp_servers.py—McpServerImportRequest,McpServerImportResult.routes/mcp_servers.py—POST /api/mcp/servers/import, reusing_validate_url(same stdio gate — stdio entries error when the gate is off; http still imports),_normalize_headers, andcreate_server. Dedups by url so re-importing is idempotent; never 400s the whole batch.Frontend
chat/api/mcp-servers-api.ts—importMcpServers(config)+McpServerImportResult.chat/chat-mcp-servers-dialog.tsx— an "Import config" file-upload button with aN added, M skipped, K errorssummary toast.Cross-platform
The only platform-sensitive point is the command join/split round-trip, handled by
join_stdio_command↔parse_stdio_command. Tests cover both posix and win32 using #5936's literal Windows fixtures (absolute.exepaths with spaces, backslash drive args likeD:\,O:\).Testing
Ongoing