Skip to content

Studio: add stdio MCP server support#5863

Merged
danielhanchen merged 2 commits into
unslothai:mainfrom
oobabooga:stdio-mcp-servers
May 31, 2026
Merged

Studio: add stdio MCP server support#5863
danielhanchen merged 2 commits into
unslothai:mainfrom
oobabooga:stdio-mcp-servers

Conversation

@oobabooga
Copy link
Copy Markdown
Contributor

Remote (HTTP) MCP support was added in #5750; stdio (local) servers are the other transport. The official reference servers (filesystem, git, fetch, memory) and most community ones run locally as a subprocess via npx/uvx, not over HTTP.

This PR adds stdio MCP support by accepting a local command in place of a URL in the MCP Servers dialog.

How to use

Example:

  1. Go to MCP Servers -> Manage -> Add server.
  2. In "URL or command", enter the command, e.g. npx -y @modelcontextprotocol/server-filesystem /tmp (the directory must exist).
  3. (Optional) Add environment variables in the editor below: e.g. name API_KEY, value sk-...
  4. Test connection, then Add server.
  5. Toggle "Use MCP Servers" on.
  6. Ask the model What files are in /tmp? (calls list_directory), or Write a file /tmp/notes.txt containing "hello" (calls write_file).
example

The command's runtime must be installed and on PATH. The example above needs npx, a uvx server needs uv, a python3 -m server needs Python, etc.

Policy (gating)

stdio servers run an arbitrary local subprocess as the backend user, so they are gated by deployment, not by login:

  • Enabled automatically in the desktop app (the backend is the user's own machine).
  • Off everywhere else: manual local runs, Colab, any network (0.0.0.0) bind. Set UNSLOTH_STUDIO_ALLOW_STDIO_MCP=1 to override. The flag is process-wide with no bind check, so it grants every user who can log into the backend the ability to run commands on the machine. Only enable it when you trust everyone with access.

When disabled, stdio servers cannot be created, tested, refreshed, discovered, or executed (enforced at all five points). A DB carried from a desktop install won't spawn anything on a hosted instance.

Implementation

Reuses the existing HTTP MCP path to keep the change small. A non-HTTP address is treated as a stdio command. The command rides the existing url field and env vars ride the headers_json column. No new DB column, no migration, no new model or route. 5 files changed, transport built with fastmcp's StdioTransport. The HTTP path is untouched.

@oobabooga oobabooga requested a review from rolandtannous as a code owner May 29, 2026 16:04
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.

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 adds support for local stdio Model Context Protocol (MCP) servers alongside remote HTTP servers, restricted by a security gate (UNSLOTH_STUDIO_ALLOW_STDIO_MCP) that is enabled by default on the desktop app. Key feedback includes fixing a validation bug in the frontend that rejects local commands containing '://' in their arguments, stripping preserved quotes from parsed command tokens on Windows to prevent subprocess execution failures, and defensively handling empty command lists in the client initialization to avoid an IndexError.

Comment thread studio/frontend/src/features/chat/chat-mcp-servers-dialog.tsx
Comment thread studio/backend/core/inference/mcp_client.py Outdated
Comment thread studio/backend/core/inference/mcp_client.py
Copy link
Copy Markdown
Member

@danielhanchen danielhanchen left a comment

Choose a reason for hiding this comment

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

Tested locally: the stdio gate holds at create, test, refresh, discovery and execute, a real stdio server (npx filesystem) works end to end, and the live Studio UI checks out. CI is green. Approving.

@danielhanchen danielhanchen merged commit ff00fdd into unslothai:main May 31, 2026
29 checks passed
@Datta0
Copy link
Copy Markdown
Collaborator

Datta0 commented Jun 1, 2026

image

I see the request goes through but returns 400

@oobabooga
Copy link
Copy Markdown
Contributor Author

@Datta0 This happened because stdio MCP is disabled by default except on the desktop app. To enable it on the webui, start it with UNSLOTH_STUDIO_ALLOW_STDIO_MCP=1.

The error message was unclear/misleading, I have improved that here: #5928

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.

3 participants