studio/MCP.md
Rama main · réplica de lectura del repositorio original.
# MCP in Unsloth Studio
## Connect Blender MCP
Blender MCP is **disabled by default**. Unsloth Studio downloads a pinned, checksum-verified
runtime on first enable/test and caches it on the backend machine. No commands,
Git or pip installs are needed. Subsequent starts use the cache without internet.
The Blender add-on is installed separately. No MCP archive or source is shipped
in Unsloth Studio's Python package or desktop build.
1. Open **Manage MCP servers → Blender**, approve the execution warning and choose
**Enable Blender MCP**. Use a tool-capable model with MCP enabled for the chat.
2. Open **Setup help → Download Blender add-on** for
[Blender's official page](https://www.blender.org/lab/mcp-server/).
3. In Blender 5.1+, enable **Preferences → System → Network → Allow Online Access**.
Drag the website's install button into Blender twice: first to add the Blender
Lab repository, then to install MCP. Alternatively, search **MCP** in
**Get Extensions** after adding the repository.
4. Enable and start the add-on bridge, keep Blender open, then **Test connection**.
A green dot means Blender is connected; amber means only the MCP server is connected.
Setup help stays in the same Blender entry. Advanced settings configure the bridge
port (default `9876`) and optional Blender executable. This port is not an HTTP URL.
The bridge uses loopback on the **Unsloth Studio backend machine**, not a remote browser.
Unsloth Studio does not install or launch Blender during setup. Approved tools can run
Python, write files and launch background Blender. Existing tool permissions apply;
external model providers receive tool results. Keep the unauthenticated bridge local.
The downloaded runtime excludes the large API/manual reference corpus and its three
offline documentation tools. The official source is
https://projects.blender.org/lab/blender_mcp (GPL-3.0-or-later).
The pinned revision and SHA-256 are in `backend/integrations/blender/runtime.py`.
Downloads are staged and verified before activation; failures leave the server
disabled and can be retried with **Enable Blender MCP**. Merely opening the dialog
or launching Unsloth Studio does not download anything.
## Large tool catalogs
A server can expose dozens of tools with long descriptions and deeply nested
parameter schemas: Notion's catalog alone is about 65,000 tokens. Every tool is
listed in full while the catalog takes at most a tenth of the loaded local model's
context window. External providers always get the full listing.
Past that, Unsloth searches tools the way Claude Code and Codex do. The model gets
`mcp_tool_search`, whose description names every tool with a one-line summary,
instead of the schemas. A search ranks the catalog with the SQLite FTS5 BM25 index
and rank fusion the knowledge base uses (tool names and descriptions searched
separately) and loads the best matches, exact names always; the model then calls
them with their full schemas. A tool the model calls by name loads the same way.
Up front, the listing also carries a tool a `tool_choice` forces, the tools mapped
to take an attached image, and, within a third of the window, the tools the chat
ran on earlier turns (so the prompt prefix the model server caches holds) and up
to five tools ranked against the user's message. Tools a turn loads stay within
half of the window, the oldest leaving first; a tool too large for that is refused
with a message naming it.
## Unsloth Decisions MCP
When the Decision API is on (**Settings → API**), the chat's MCP menu lists
**Unsloth Decisions**. Enable it and a tool-capable chat model can call `decide`,
which asks the local Laya model the same typed questions `POST /v1/systemone`
answers (`noul`, `choice` and `score`), with the model chosen in Settings.
Other MCP clients reach the same tool at `http://127.0.0.1:8888/mcp/decisions/`
(use the actual Unsloth port). It takes the credentials `/v1/systemone` takes, so
send an Unsloth API key as `Authorization: Bearer sk-unsloth-...`.
<a id="studios-own-mcp-server"></a>
## Unsloth Studio's own MCP server
Unsloth Studio has its own MCP server at `/mcp/`. Coding agents such as Claude Code and
Codex can use it to load models, chat, generate images, audio and video,
transcribe, train and export. Every tool goes through Unsloth Studio's own routes as
your API key, so it sees what that key may see and nothing more.
### Turn it on
The server is off by default. While it is off, `/mcp/` answers 404. The Unsloth
Studio owner turns it on in Settings > Agents with **Allow agent connections**.
Starting Unsloth Studio with `UNSLOTH_STUDIO_ENABLE_MCP=1` also turns it on and
locks the switch, which then reads "Set by UNSLOTH_STUDIO_ENABLE_MCP."
The endpoint is `http://127.0.0.1:8888/mcp/` on the default port. Always use
the trailing slash. Use your own address and port when they differ, for example
the LAN address or the Cloudflare tunnel URL.
### Authentication
Every request needs an Unsloth Studio API key: `Authorization: Bearer sk-unsloth-…`.
Create one in **Settings → API**. Unsloth Studio refuses everything else with 401:
- no key, an empty key, or a placeholder key such as `not-needed`, even when
keyless API access is on;
- a signed-in session token;
- a revoked or expired key;
- the keys Unsloth Studio mints for its own recipe and Deep Research workflows.
A managed account's key works too. Its tools act for that account only.
Unsloth Studio does not offer OAuth. The OAuth discovery paths answer 404, so clients
that probe them fall back to the key.
A browser page from another site gets 403 `Origin not allowed for Unsloth Studio MCP`.
This also blocks browser-based MCP inspectors. Command-line agents send no
Origin and are not affected.
### Breaking changes
The static `UNSLOTH_STUDIO_MCP_TOKEN` is retired. A request that sends it gets
401 with this detail:
```
The MCP static token is no longer supported; use an Unsloth Studio API key (sk-unsloth-…)
```
If the variable is still set, Unsloth Studio logs one warning at startup. Unsloth Studio no
longer refuses to start when the token is missing.
The tools changed:
| Old tool | New tool |
|---|---|
| `list_local_models` | `list_models` |
| `get_training_status` | `studio_status` |
| `stop_training` | `cancel` with `kind="training"` |
| `validate_recipe` | `run_recipe` with `mode="validate"` |
| `get_recipe_job_status`, `get_recipe_job_dataset` | `get_job` with `kind="recipe"` |
| `load_checkpoint` and `export_gguf` | `export_model` |
`studio_status` and `start_training` keep their names, but now run as your key.
### Set up an agent
#### One command
`unsloth mcp add` writes the agent's MCP entry for you. It supports
`claude-code`, `codex`, `cursor` and `generic`:
```bash
unsloth mcp add claude-code
unsloth mcp add codex --url http://192.168.1.20:8888
unsloth mcp add cursor --dry-run
```
- The entry names the `UNSLOTH_API_KEY` environment variable, never the key
itself, and the command never prints a key. Pick another variable with `--env-var`.
- It finds a running Unsloth Studio on this computer, or takes `--url`.
- `--dry-run` prints the entry it would write and writes nothing. Running it
again changes nothing.
- A config file it creates is readable by you only (mode 0600).
- `codex` also sets `tool_timeout_sec = 300`.
- `generic` prints a JSON entry to paste into any other agent's config.
Then check the connection:
```bash
unsloth doctor --mcp
```
It checks that Unsloth Studio answers, that your key works, and that the MCP
server is on. It also warns when an agent's tool timeout is under 240 s, because
long tools such as `load_model` can wait that long.
#### By hand
Each one reads the key from the `UNSLOTH_API_KEY` environment variable, so set
it before you start the agent. Replace `http://127.0.0.1:8888` with your own
address.
**Claude Code** (macOS or Linux):
```bash
claude mcp add --transport http --scope user unsloth-studio http://127.0.0.1:8888/mcp/ --header 'Authorization: Bearer ${UNSLOTH_API_KEY}'
```
**Claude Code** (Windows PowerShell):
```powershell
claude mcp add --transport http --scope user unsloth-studio http://127.0.0.1:8888/mcp/ --header 'Authorization: Bearer ${UNSLOTH_API_KEY}'
```
**OpenAI Codex**:
```bash
codex mcp add unsloth-studio --url http://127.0.0.1:8888/mcp/ --bearer-token-env-var UNSLOTH_API_KEY
```
Then set `tool_timeout_sec = 300` under `[mcp_servers.unsloth-studio]` in
`~/.codex/config.toml`.
**Long calls.** A long chat reply, a song or a first model download can take
minutes, so raise your client's tool timeout above 240 s. For Codex that is
`tool_timeout_sec = 300` above. For Claude Code, start it with
`MCP_TOOL_TIMEOUT=300000 claude` (the value is in milliseconds).
**OpenCode**, in `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"unsloth-studio": {
"type": "remote",
"url": "http://127.0.0.1:8888/mcp/",
"oauth": false,
"headers": {
"Authorization": "Bearer {env:UNSLOTH_API_KEY}"
}
}
}
}
```
**Hermes Agent**, in `~/.hermes/config.yaml`, then run `/reload-mcp` in Hermes:
```yaml
mcp_servers:
unsloth_studio:
url: "http://127.0.0.1:8888/mcp/"
headers:
Authorization: "Bearer ${UNSLOTH_API_KEY}"
```
**OpenClaw**, in `~/.openclaw/openclaw.json`:
```json
{
"mcp": {
"servers": {
"unsloth-studio": {
"url": "http://127.0.0.1:8888/mcp/",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer ${UNSLOTH_API_KEY}"
}
}
}
}
}
```
**Mistral Vibe**, in `~/.vibe/config.toml`:
```toml
[[mcp_servers]]
name = "unsloth_studio"
transport = "streamable-http"
url = "http://127.0.0.1:8888/mcp/"
[mcp_servers.auth]
type = "static"
api_key_env = "UNSLOTH_API_KEY"
api_key_header = "Authorization"
api_key_format = "Bearer {token}"
```
**DeepSeek Harness**, appended to `~/.dsh/cordis.patch.yml`:
```yaml
- insert:
- id: mcp-unsloth-studio
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: unsloth-studio
transport: streamable-http
url: "http://127.0.0.1:8888/mcp/"
headers:
Authorization: !!js '`Bearer ${process.env.UNSLOTH_API_KEY}`'
```
### Tools
| Tool | What it does |
|---|---|
| `studio_status` | What is loaded, loading and running: chat, image, video, speech-to-text and embedding models, training, export and GPUs. |
| `list_models` | Models Unsloth Studio can serve, by kind or by Audio page `workflow`. With `model`, its training defaults. With `source="catalog"`, the image, video and audio models it can download, with their size and whether they fit on the GPU now. |
| `load_model` | Load a chat, image, video or speech-to-text model, downloading it first if needed. Reports progress, waits up to `wait_s` (240 s by default) and lists what it unloaded. |
| `unload_model` | Unload a model, or every chat, speech, image, video and speech-to-text model with `kind="all"`. The embedding model stays. |
| `plan_load` | Preview a load without loading anything: GGUF variants and sizes, bytes to download, and the models it would unload. |
| `download_model` | Download a model ahead of time without loading it. Follow it with `get_job`; `load_model` waits for it. |
| `chat` | Ask the loaded model, with optional images, thinking controls and a `response_format`. Reports progress and returns a `cancel_id`. |
| `embed` | Embed up to 2048 texts, or rank them against a `query` and return the `top_k` best matches. |
| `system_one` | Ask the Decision API typed questions. The Decision API must be on. |
| `generate_image` | Text to image, image to image, inpaint, edit, reference, outpaint and upscale, one image or a batch of seeds or prompts. Left out, steps and guidance follow the loaded model. |
| `generate_audio` | Clone, speak, edit, convert, music and separate, on the loaded model or a named `model`. |
| `transcribe` | Speech to text, or translation to English; `speakers` labels who speaks, and `expected_text` adds a match score. |
| `analyze_audio` | A clip's duration, loudness, true peak, clipping and speech span, plus a match score against `expected_text`. |
| `generate_video` | Start a video, with a seed, frame count, last frame and image or audio references. One renders at a time. Poll it with `get_job`. |
| `get_job` | The state of a video, recipe, export, training or load job. With `wait_s` it waits for the job to finish or move on. |
| `list_media` | Earlier images, audio clips, videos, transcripts and saved voices, a page at a time. |
| `voices` | List, save, rename and delete saved voices. |
| `run_recipe` | Validate, preview or run a Data Recipe. |
| `datasets` | List, check, upload, download and follow training datasets, and upload image datasets for image LoRA training. |
| `start_training` | Start LLM, text-to-speech or image LoRA training. Follow it with `get_job`. |
| `list_training_runs` | Past runs and their checkpoints, by name. |
| `export_model` | Export a checkpoint to GGUF, merged weights, a LoRA adapter or the base model. |
| `cancel` | Stop running work of a given kind; the kinds are listed in the tool's schema. |
Long work keeps running in Unsloth Studio when a tool call times out.
Follow every long job with `get_job(kind=…, id=…, wait_s=…)`: it checks every 2 s and returns once the job finishes, its status changes (for an export or a training run, also its phase), or `wait_s` runs out.
`wait_s` is at most 240; 50 stays under Codex's 60 s default tool timeout, and longer waits need a longer client timeout.
`load_model` waits up to `wait_s` too (240 s when unset), then returns `status: "loading"` and a `job_id` for `get_job(kind="load")`.
Stop work with `cancel`.
Unsloth Studio runs one export at a time, so `export_model` is refused while another export runs, and cancelling an export job stops only that job's own step.
### Choose tools
Every tool is on by default, including tools added by a later update. The
Unsloth Studio owner turns single tools off in Settings > Agents with **Choose tools**.
The choice covers the whole installation and every API key. A tool that is off
is left out of `tools/list`, and a call to it fails with
`[tool_disabled] <tool> is turned off in Unsloth Studio. The owner can turn it on in Settings > Agents.`
A prompt is hidden while a tool it reads (`studio_status` or `list_models`) is
off. The forced switch from `UNSLOTH_STUDIO_ENABLE_MCP=1` does not lock the tool
choices.
Agents read the tool list when they connect, so an agent that is already
connected keeps showing a tool you turned off until it reconnects. Its calls to
that tool are refused at once.
### Media and files
Generated images, audio and videos are saved to Unsloth Studio's galleries, the same as
in the UI. Tools return each item's id, its `url` and a `download_url`. The
`download_url` works without the API key for about an hour. It is bound to your
account and stops working when Unsloth Studio restarts, so call `list_media` for a
fresh one. The `url` needs the same `Authorization: Bearer` key.
`return_media` sets what else comes back. For images and video it defaults to
`"inline"`: small images inline, large ones as a preview plus a link, and a video
as a thumbnail plus a link. `"preview"` sends a small image of `preview_px` pixels
(1024 by default), and `"link"` sends no media at all. Audio defaults to `"link"`.
Pass `"inline"` to get a short clip itself. The MP4 is never sent inline.
`list_media` pages through earlier images, audio clips, videos, transcripts and
saved voices; pass its `next_cursor` back to get the next page. `voices` saves a
voice from a clip, so `generate_audio` can reuse it as `reference={"voice_id": ...}`.
A gallery video is an input too: `{"video_id": ..., "frame": "last"}` for an
image, or `{"video_id": ..., "start_s": ..., "end_s": ...}` for its sound.
Media inputs can be an Unsloth Studio id, inline data, or a file path. **A file path
works only when the agent runs on the Unsloth Studio computer** and connects over
loopback. From any other computer, send the data or an Unsloth Studio id instead.
An MCP request is limited to 4 MiB, so inline data has to fit in that. Send
larger media as an Unsloth Studio id, or as a path from the Unsloth Studio computer. A remote
agent can upload a large audio file, up to 200 MiB, to `POST /v1/audio/inputs` with its API key
and pass the returned `id` as `input_id`. The route takes the file's raw bytes as
the request body with a `Content-Length`, not a multipart form or JSON, and an
optional `name` query parameter:
```bash
curl -X POST "http://127.0.0.1:8888/v1/audio/inputs?name=meeting.mp3" \
-H "Authorization: Bearer $UNSLOTH_API_KEY" \
--data-binary @meeting.mp3
```
`transcribe` sends files up to 25 MB directly. Larger files, and audio given by
id, are uploaded to Unsloth Studio first, and their transcript is saved to Audio
history. Translation needs a file under 25 MB. Transcribing from a URL or a
YouTube link is not supported. `timestamps` needs a speech-to-text model that
times segments, such as Qwen3-ASR (audio.cpp) or Parakeet-TDT; other models
refuse it, and translation never has timestamps.
`studio_status` lists the loaded audio model's `audio_options`, such as its
built-in voices. Pass them to `generate_audio` in `options`. A voice or other
listed value is matched without regard to case, and a value the model does not
list is refused.
Tool results never contain paths on the Unsloth Studio computer. Checkpoints are named
`<run folder>` or `<run folder>/checkpoint-N`. Exports are named relative to
Unsloth Studio's exports folder, and `export_model` takes only a relative
`save_directory`.
### Prompts
The server also offers two prompts, which Claude Code shows as slash commands:
`make_short_film` and `build_dataset_and_train`. Each one reads what is loaded
and which catalog models fit on the GPU right now, then lays out the tool calls
for the job.
### Known limits
- An API key cannot unload a chat model that was loaded from a local folder.
Unsloth Studio shows such a model to API keys under an opaque reference, and the
unload route does not resolve it. Unload it in the Unsloth Studio UI.
- Unsloth Studio runs one Data Recipe job at a time, and a recipe job id is not tied to
an account. Anyone with a key who knows the id can read that job's status.
- Models can be unloaded between calls when an idle timeout is set. Tools then
say to load the model again.