Skip to main content
Glama

sdcraft-mcp

An MCP server for local image generation and editing via stable-diffusion.cpp (sd-server).

A thin supervisor plus an asynchronous client: generation goes through the native async API of sd-server (/sdcpp/v1, jobs with a job_id), while the server itself is a managed resource — started lazily, stopped automatically when idle, and never spawned twice on the same port.

Features

  • Asynchronous jobs. Submitting returns a job_id; status/result is fetched via get_job. Client timeouts no longer get in the way.

  • sd-server supervisor: lazy autostart, readiness checks, single-instance guard (pidfile + port owner), idle-kill, shutdown on exit.

  • Model profiles with supports flags (img2img / inpaint / edit / controlnet) — the config is the source of truth.

  • Clear refusals: an unsupported operation returns a message listing the profiles that can do it.

  • Hard wait cap (wait_seconds <= ~30s): a call never blocks longer than the MCP client timeout and instead honestly returns a job_id.

Related MCP server: Universe Imagine MCP

Requirements

  • Node.js 18+ (uses the global fetch).

  • An sd-server build from stable-diffusion.cpp (Windows/Linux/macOS).

  • Model files: a diffusion GGUF (plus a separate VAE and text encoder if the profile needs them).

Build

npm install
npm run build

The entry point is build/index.js.

Configuration

The main file is sdcraft.config.json (the path can be overridden with the SDCRAFT_CONFIG environment variable). Paths inside are machine-specific — adjust them for your setup.

{
  "binPath":  "/path/to/sd-server",       // sd-server executable
  "workDir":  "/path/to/sdcpp/bin",
  "modelsDir":"/path/to/models",          // where the GGUF files live
  "assetsDir":"/path/to/assets",          // VAE etc.
  "outputDir":"/path/to/output",          // where PNGs are saved
  "logDir":   "/path/to/logs",
  "host": "127.0.0.1",
  "port": 8080,
  "idleMode": "stop",
  "idleTimeoutSec": 600,
  "commonArgs": ["--vae-tiling"],
  "active": "z-image-turbo",
  "profiles": {
    "z-image-turbo": {
      "args": {
        "--diffusion-model": "diffusion-model-GGUF/diffusion-model-Q4_K.gguf",
        "--vae": "vae.safetensors",
        "--llm": "text-encoder-GGUF/text-encoder-Q4_K_M.gguf"
      },
      "defaults": { "steps": 9, "cfg_scale": 1, "sampler": "euler", "width": 1024, "height": 1024 },
      "supports": { "img2img": true, "inpaint": true, "edit": false, "controlnet": false }
    }
  }
}

Path resolution: an absolute path is used as-is, otherwise the value is looked up in modelsDir, then in assetsDir.

OpenCode Integration

{
  "mcp": {
    "sdcraft": {
      "type": "local",
      "command": ["node", "path/to/sdcraft-mcp/build/index.js"],
      "environment": { "SDCRAFT_CONFIG": "path/to/sdcraft-mcp/sdcraft.config.json" }
    }
  }
}

Tools (13)

Tool

Purpose

server_status

whether the server runs, profile/model, port, uptime

start_server(profile?) / stop_server() / restart_server(profile?)

lifecycle control

set_profile(name)

switch the active profile (restarts the server)

list_profiles

profiles: model, defaults, supports

capabilities

live server capabilities: samplers/schedulers/limits/features

generate_image(prompt, negative_prompt?, steps?, cfg_scale?, width?, height?, sampler?, seed?, profile?, wait_seconds?)

txt2img

edit_image(init_image?|ref_images?, prompt, mask?, strength?, ...)

img2img / inpaint / edit

upscale_image(image, upscaler?, repeats?)

upscale (needs an ESRGAN model on the server)

get_job(job_id, wait_seconds?)

status/progress/result (saves the PNG)

cancel_job(job_id) / list_jobs()

cancel / list jobs for the session

Behavior

  • generate_image/edit_image wait up to wait_seconds (default 20, capped at ~30): if done, they return the PNG path; otherwise a job_id for get_job.

  • Only generate_image, edit_image, and capabilities start the server lazily. Service tools (server_status, get_job, cancel_job, list_jobs) do not wake it.

  • On engine failure or an unreachable server, tools report it explicitly (pointing to server_status/restart_server) instead of returning a bare error.

  • The default size comes from the profile defaults; for img2img pass width/height explicitly if you want to keep the source size.

Files

  • src/config.ts — config loading and sd-server argument building.

  • src/client.ts — HTTP client for sd-server (/sdcpp/v1, /sdapi/v1).

  • src/supervisor.ts — process lifecycle.

  • src/store.ts — jobs and image saving.

  • src/index.ts — MCP server and tools.

License

MIT

Available Tools

13 tools
cancel_jobB

Cancel a job (queued or running). Does NOT start the server.

Inputs: job_id (required).

capabilitiesB

Live server capabilities: model, samplers/schedulers, defaults, limits, upscale availability.

Inputs: no named parameters.

edit_imageB

Edit/transform an image: init_image (img2img/inpaint) or ref_images (edit). Asynchronous, like generate_image (waits <= ~30s, otherwise job_id).

Inputs: prompt (required), mask, seed, steps, +10 more.

generate_imageB

Asynchronous prompt generation. Waits up to wait_seconds (default 20, capped at ~30s); if done returns the PNG path, otherwise a job_id for get_job.

Inputs: prompt (required), seed, steps, width, +8 more.

get_jobA

Job status/progress/result (waits <= ~30s). Saves the PNG on completion. Does NOT start the server.

Inputs: job_id (required), wait_seconds.

list_jobsC

Jobs known to this MCP in this session.

Inputs: no named parameters.

list_profilesB

List profiles: model, defaults, supported operations.

Inputs: no named parameters.

restart_serverB

Force-restart sd-server (stop+start). Optionally on another profile.

Inputs: profile.

server_statusB

sd-server state: running, managed, profile/model, port, uptime, queue.

Inputs: no named parameters.

set_profileB

Set the active profile (model) — restarts the server if it is running.

Inputs: name (required).

start_serverB

Start sd-server (optionally with the given profile). Lazy autostart also happens on demand.

Inputs: profile.

stop_serverA

Stop sd-server (frees VRAM/RAM). Stops only the instance started by this MCP.

Inputs: no named parameters.

upscale_imageB

Upscale an image via RGB ESRGAN (requires an upscale model configured on the server).

Inputs: image (required), repeats, upscaler.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 13 tools

    Disambiguation4/5

    Generation verbs (generate/edit/upscale) and job tools (get/cancel/list) are clearly distinct. The only mild overlaps are capabilities vs list_profiles vs server_status, and start vs restart, but descriptions resolve them.

    Naming Consistency4/5

    Most tools follow verb_noun (stop_server, get_job, generate_image, set_profile), with a few noun-first outliers (server_status, capabilities) and inconsistent verb+object for upscale_image vs edit_image. Readable and mostly predictable.

    Tool Count5/5

    13 tools is well-scoped for a local SD server wrapper, covering lifecycle, jobs, and generation without redundancy. Each tool earns its place.

    Completeness4/5

    Covers server lifecycle, profiles, capabilities, job management, and image generation/editing/upscaling. Minor gaps like job cleanup/deletion or explicit model listing beyond profiles, but core workflows are complete.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers