Skip to content

[Draft][WIP] studio: import MCP servers from a config file#5943

Draft
rolandtannous wants to merge 3 commits into
mainfrom
feature/mcp-config-file
Draft

[Draft][WIP] studio: import MCP servers from a config file#5943
rolandtannous wants to merge 3 commits into
mainfrom
feature/mcp-config-file

Conversation

@rolandtannous
Copy link
Copy Markdown

@rolandtannous rolandtannous commented Jun 2, 2026

Summary

Addresses #5936. Adds the ability to import MCP servers from a standard mcpServers JSON 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 by UNSLOTH_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 existing url/headers_json storage overload, validation, and stdio gate.

What's included

Backend

  • core/inference/mcp_client.pyjoin_stdio_command(parts), the round-trip-safe inverse of parse_stdio_command (subprocess.list2cmdline on win32, shlex.join on posix).
  • core/inference/mcp_config_import.py (new)parse_mcp_config(config) -> (entries, errors). Accepts mcpServers (primary) and servers (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.pyMcpServerImportRequest, McpServerImportResult.
  • routes/mcp_servers.pyPOST /api/mcp/servers/import, reusing _validate_url (same stdio gate — stdio entries error when the gate is off; http still imports), _normalize_headers, and create_server. Dedups by url so re-importing is idempotent; never 400s the whole batch.

Frontend

  • chat/api/mcp-servers-api.tsimportMcpServers(config) + McpServerImportResult.
  • chat/chat-mcp-servers-dialog.tsx — an "Import config" file-upload button with a N added, M skipped, K errors summary toast.

Cross-platform

The only platform-sensitive point is the command join/split round-trip, handled by join_stdio_commandparse_stdio_command. Tests cover both posix and win32 using #5936's literal Windows fixtures (absolute .exe paths with spaces, backslash drive args like D:\, O:\).

Testing

Ongoing

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +331 to +337
let config: unknown;
try {
config = JSON.parse(await file.text());
} catch {
toast.error("Invalid JSON file");
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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;
    }

@oobabooga
Copy link
Copy Markdown
Contributor

I have tried loading all these mcp.jsons with the PR code and can confirm they all load successfully:

https://github.com/akv2011/MCP_Automated_Siri_cursor_control/blob/main/mcp.json
https://github.com/bcdennis/reference-mcp-config/blob/main/mcp.json
https://github.com/bwisitero/strands-agentcore-sample-code/blob/main/.claude/mcp.json
https://github.com/cowprotocol/services/blob/main/.mcp.json
https://github.com/diegoahenao/financial-data-platform-claude-code/blob/dev/.mcp.json
https://github.com/fuww/top200-rs/blob/main/.mcp.json
https://github.com/gazolla/JCli/blob/main/config/mcp/mcp.json
https://github.com/InnerAnimal/meaux-mono/blob/main/mcp.json
https://github.com/javdl/nixos-config/blob/main/.mcp.json
https://github.com/mallcumek/rcponorka.cz/blob/master/.mcp.json
https://github.com/mattietea/config/blob/main/.mcp.json
https://github.com/Tencent-RTC/mcp/blob/main/mcp.json
https://github.com/y-miyazaki/absc/blob/main/.vscode/mcp.json
https://github.com/2sem/talktrans/blob/main/.cursor/mcp.json
https://github.com/aanno/ai-enhanced-app-dev/blob/main/mcp-python/.mcp.json
https://github.com/aganesy/QFAI/blob/main/packages/qfai/assets/mcp-templates/brave-search/.mcp.json
https://github.com/aloewright/baby-rex/blob/main/mcp/mcp.json
https://github.com/Amka78/owl-of-athena/blob/master/.vscode/mcp.json

Some include HTTP servers and these are imported too. None contain request headers, but I confirmed separately that this example with a header works:

{
  "mcpServers": {
    "remote-with-auth": {
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "Bearer sk-test-123",
        "X-API-Key": "abc"
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants