Skip to main content
Glama

dsh-zimage-mcp

Zero-dependency MCP (stdio) server that wraps the Hugging Face Space mrfakename/Z-Image-Turbo (Alibaba Tongyi Z-Image turbo text-to-image, running on ZeroGPU A10G) and exposes it as agent-friendly tools. Built for the DeepSeek Harness (DSH) MCP bridge, but works with any MCP client (Claude Desktop, Cursor, …).

prompt ──▶ mcp__zimage__generate_image ──▶ Z-Image-Turbo Space (Gradio REST)
                    │
                    ├─ downloads the PNG locally (default Documents/DSH/zimage-output)
                    └─ returns JSON: savedPath + url + seedUsed + elapsedMs

Why a wrapper (and not the Space's own MCP endpoint)?

The Space is Gradio ≥5, so it already exposes https://mrfakename-z-image-turbo.hf.space/gradio_api/mcp. Pointing a client there works, but:

Space's built-in MCP

this server

Tool result

image inline as base64 content (hundreds of KB into the model context)

trimmed JSON: local file path, temporary URL, seed

Where the image lives

Space /tmp/gradio (garbage-collected)

your disk (survives cleanup)

ZeroGPU errors

raw

relayed with actionable hints (quota / sleeping space)

Token handling

none

HF_TOKEN (env or ~/.dsh/.credentials.yaml) for higher quota

Dependencies

—

zero (plain Node ≥18, newline-delimited JSON-RPC over stdio)

Related MCP server: Z-Image Studio

Tools

generate_image

arg

type

default

notes

prompt

string

required

natural language; EN/JA/ZH all work (≤4000 chars)

width

int 512–2048

1024

Space slider bounds

height

int 512–2048

1024

steps

int 1–20

9

turbo model: 6–12 is plenty

seed

int

0

used when randomizeSeed:false

randomizeSeed

bool

true

false = reproducible with seed

save

bool

true

download result locally

outPath

string

auto

absolute path override

Returns {ok, savedPath, url, seedUsed, width, height, steps, elapsedMs, bytes, note}. Typical wall time 10–40 s (ZeroGPU queue dependent). Point an image-reading tool (or a multimodal model) at savedPath to inspect the result.

space_status

{stage, hardware, sdk, likes, note} — RUNNING / SLEEPING / PAUSED diagnosis.

save_image

{url, outPath?} → {savedPath, bytes} — persist a generation URL before the Space cleans up /tmp/gradio.

DSH registration

In ~/.dsh/profiles/web/cordis.patch.yml (requires host restart, or HMR hot-swap of the mcp-client entry):

- insert:
    - id: mcp-zimage
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: zimage
        transport: stdio
        command: 'C:\Program Files\nodejs\node.exe'
        args:
          - 'C:\Users\motch\Documents\DSH\dsh-zimage-mcp\zimage-mcp.mjs'
        env:
          HF_TOKEN: !!js process.env.HF_TOKEN || ''
        failOnStartupError: false
        toolCallTimeoutMs: 600000

Tools appear as mcp__zimage__generate_image, mcp__zimage__space_status, mcp__zimage__save_image. toolCallTimeoutMs must exceed the Space's worst queue wait; 10 min is a safe ceiling.

ZeroGPU quota

Generation is billed against ZeroGPU quota:

  • Anonymous (per IP): tiny — a few short generations per window; when exhausted the Space returns You have exceeded your ZeroGPU quota (Ns requested vs. Ns left). The tool relays this verbatim; wait for the window to reset and retry.

  • With a free HF token (HF_TOKEN): substantially more GPU-seconds. Create one at https://huggingface.co/settings/tokens (read is enough), then either set the HF_TOKEN Windows/host environment variable or put HF_TOKEN: hf_xxx in ~/.dsh/.credentials.yaml — the server picks it up (env first, credentials file as fallback; the placeholder unused is ignored). No restart of this server is needed between calls, but a new server process re-reads both.

Configuration (env)

var

default

meaning

HF_TOKEN

(auto)

Bearer token for the Space API; empty → anonymous

ZIMAGE_TIMEOUT_MS

570000

per-generation SSE timeout

ZIMAGE_OUTPUT_DIR

%USERPROFILE%\Documents\DSH\zimage-output

default save directory

How it talks to the Space

Plain Gradio REST, no gradio_client dependency:

POST /gradio_api/call/generate_image   {"data":[prompt,h,w,steps,seed,randomize]} → {"event_id": …}
GET  /gradio_api/call/generate_image/<event_id>   (text/event-stream)
     event: progress|process_starts|heartbeat … until
     event: complete  data=[[{url,path,orig_name,mime_type}, seedUsed]]
     event: error     data=[{"error": "You have exceeded your ZeroGPU quota …"}]

Slider bounds (verified 2026-09-01): width/height 512–2048, steps 1–20, defaults 1024/1024/9.

Test

node test/server-test.mjs --skip-live   # protocol round-trips only
node test/server-test.mjs               # + one real 512x512/4-step generation

All assertions passing 2026-09-01 (protocol 5/5; live suite validated end-to-end against the running Space).

License

MIT — see LICENSE.

Related MCP Connectors

Related MCP Servers