Skip to content

Commit 823d490

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 7abeff6 commit 823d490

2 files changed

Lines changed: 30 additions & 32 deletions

File tree

studio/backend/mcp_server.py

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ async def _send_unauthorized(send: Any, scope_type: str) -> None:
6262
def _dump(value: Any) -> Any:
6363
"""Convert Pydantic responses to plain JSON values for MCP clients."""
6464
if hasattr(value, "model_dump"):
65-
return value.model_dump(mode="json")
65+
return value.model_dump(mode = "json")
6666
return value
6767

6868

6969
def create_studio_mcp() -> FastMCP:
7070
"""Create the Studio MCP server and register the high-value tools."""
7171
mcp = FastMCP(
7272
"Unsloth Studio",
73-
instructions=(
73+
instructions = (
7474
"Use read tools to inspect the local Studio state before starting GPU work. "
7575
"Training and export tools can consume substantial VRAM and write files. "
7676
"Never expose tokens or local paths from tool results unless the user asks."
@@ -87,9 +87,9 @@ async def studio_status() -> dict[str, Any]:
8787
from utils.hardware import get_gpu_utilization
8888

8989
training, export, inference = await _gather_status(
90-
get_training_status(current_subject="mcp"),
91-
get_export_status(current_subject="mcp"),
92-
get_inference_status(current_subject="mcp"),
90+
get_training_status(current_subject = "mcp"),
91+
get_export_status(current_subject = "mcp"),
92+
get_inference_status(current_subject = "mcp"),
9393
)
9494
return {
9595
"training": _dump(training),
@@ -102,15 +102,13 @@ async def studio_status() -> dict[str, Any]:
102102
async def list_local_models(models_dir: str = "./models") -> dict[str, Any]:
103103
"""List local and cached models available to Studio."""
104104
from routes.models import list_local_models as list_models
105-
106-
return _dump(await list_models(models_dir=models_dir, current_subject="mcp"))
105+
return _dump(await list_models(models_dir = models_dir, current_subject = "mcp"))
107106

108107
@mcp.tool
109108
async def get_training_status() -> dict[str, Any]:
110109
"""Read the active training job, phase, progress, and recent metrics."""
111110
from routes.training import get_training_status as get_status
112-
113-
return _dump(await get_status(current_subject="mcp"))
111+
return _dump(await get_status(current_subject = "mcp"))
114112

115113
@mcp.tool
116114
async def start_training(config: dict[str, Any]) -> dict[str, Any]:
@@ -123,43 +121,43 @@ async def start_training(config: dict[str, Any]) -> dict[str, Any]:
123121
from routes.training import start_training as start
124122

125123
request = TrainingStartRequest.model_validate(config)
126-
return _dump(await start(request, current_subject="mcp"))
124+
return _dump(await start(request, current_subject = "mcp"))
127125

128126
@mcp.tool
129127
async def stop_training(save: bool = True) -> dict[str, Any]:
130128
"""Ask the active training process to stop at its next safe checkpoint."""
131129
from routes.training import TrainingStopRequest, stop_training as stop
132-
133-
return _dump(await stop(TrainingStopRequest(save=save), current_subject="mcp"))
130+
return _dump(await stop(TrainingStopRequest(save = save), current_subject = "mcp"))
134131

135132
@mcp.tool
136133
async def list_training_runs(limit: int = 50, offset: int = 0) -> dict[str, Any]:
137134
"""List completed and stopped training runs, newest first."""
138135
from routes.training_history import list_training_runs as list_runs
139-
140-
return _dump(await list_runs(limit=limit, offset=offset, current_subject="mcp"))
136+
return _dump(await list_runs(limit = limit, offset = offset, current_subject = "mcp"))
141137

142138
@mcp.tool
143139
def validate_recipe(recipe: dict[str, Any]) -> dict[str, Any]:
144140
"""Validate a Data Recipe with the same validator used by Studio."""
145141
from models.data_recipe import RecipePayload
146142
from routes.data_recipe.validate import validate
147143

148-
return _dump(validate(RecipePayload(recipe=recipe)))
144+
return _dump(validate(RecipePayload(recipe = recipe)))
149145

150146
@mcp.tool
151147
def get_recipe_job_status(job_id: str) -> dict[str, Any]:
152148
"""Read the status of a Data Recipe job."""
153149
from routes.data_recipe.jobs import job_status
154-
155150
return _dump(job_status(job_id))
156151

157152
@mcp.tool
158-
def get_recipe_job_dataset(job_id: str, limit: int = 20, offset: int = 0) -> dict[str, Any]:
153+
def get_recipe_job_dataset(
154+
job_id: str,
155+
limit: int = 20,
156+
offset: int = 0,
157+
) -> dict[str, Any]:
159158
"""Read a bounded page of generated Data Recipe rows."""
160159
from routes.data_recipe.jobs import job_dataset
161-
162-
return _dump(job_dataset(job_id, limit=limit, offset=offset))
160+
return _dump(job_dataset(job_id, limit = limit, offset = offset))
163161

164162
@mcp.tool
165163
async def load_checkpoint(
@@ -173,12 +171,12 @@ async def load_checkpoint(
173171
from routes.export import load_checkpoint as load
174172

175173
request = LoadCheckpointRequest(
176-
checkpoint_path=checkpoint_path,
177-
max_seq_length=max_seq_length,
178-
load_in_4bit=load_in_4bit,
179-
trust_remote_code=trust_remote_code,
174+
checkpoint_path = checkpoint_path,
175+
max_seq_length = max_seq_length,
176+
load_in_4bit = load_in_4bit,
177+
trust_remote_code = trust_remote_code,
180178
)
181-
return _dump(await load(request, current_subject="mcp"))
179+
return _dump(await load(request, current_subject = "mcp"))
182180

183181
@mcp.tool
184182
async def export_gguf(
@@ -192,12 +190,12 @@ async def export_gguf(
192190
from routes.export import export_gguf as export
193191

194192
request = ExportGGUFRequest(
195-
save_directory=save_directory,
196-
quantization_method=quantization_method,
197-
push_to_hub=push_to_hub,
198-
repo_id=repo_id,
193+
save_directory = save_directory,
194+
quantization_method = quantization_method,
195+
push_to_hub = push_to_hub,
196+
repo_id = repo_id,
199197
)
200-
return _dump(await export(request, current_subject="mcp"))
198+
return _dump(await export(request, current_subject = "mcp"))
201199

202200
return mcp
203201

@@ -206,7 +204,7 @@ async def _gather_status(*coroutines: Any) -> tuple[Any, ...]:
206204
"""Gather independent status calls without letting one optional backend fail all state."""
207205
import asyncio
208206

209-
results = await asyncio.gather(*coroutines, return_exceptions=True)
207+
results = await asyncio.gather(*coroutines, return_exceptions = True)
210208
return tuple(
211209
{"error": str(result)} if isinstance(result, Exception) else result for result in results
212-
)
210+
)

studio/backend/tests/test_mcp_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ async def send(message):
7474
)
7575
)
7676

77-
assert events == [{"type": "websocket.close", "code": 4401}]
77+
assert events == [{"type": "websocket.close", "code": 4401}]

0 commit comments

Comments
 (0)