Skip to content

API Server · Mac

Your Mac Is Now an Image Generation API

Start the API Server in Private Diffusion and your Mac answers image requests from Claude, from scripts, and from any app that speaks the OpenAI image API. Every image is made on your Mac, with no cloud relay in between.

  • Mac only
  • Beta

OpenAI-Compatible Image Generation API, Served From Your Mac

Code reaches it through the OpenAI image API, and Claude reaches it through MCP. Either way, the API Server runs the models you have already downloaded and hands back finished images.

OpenAI-Compatible

Point an OpenAI SDK at your Mac and call images.generate. Most image code written for OpenAI changes in two places: the base URL and the key.

Claude Connects Over MCP

Add Private Diffusion to Claude Code or Claude Desktop, then ask Claude for a picture. It calls the generate_image tool, and your Mac makes the image and hands it back.

Made on Your Mac

Prompts and images travel between your client and your Mac, with no cloud relay. Any device that can reach your Mac can send it requests, and it answers only those that carry your key.

Set It Up in Three Steps

  1. 1

    Download a Model

    Open Private Diffusion on your Mac and download at least one model. The server generates with the models you have, and the one active in Studio is its default.

  2. 2

    Start the API Server

    Click Start API Server in the API Server tab, or use the Server menu (⇧⌘A). To serve every time the app opens, turn on "Start the API server at launch" in Settings › API Server.

  3. 3

    Copy Your Address and Key

    Click Details in the API Server tab. It lists your Mac's addresses, your key, and ready-made commands for curl, Claude Code, and Claude Desktop with both filled in.

Know Before You Connect

  • The server speaks plain HTTP. Your key, prompts, and images cross the network unencrypted, so run it on networks you trust and stop it on public Wi-Fi.
  • Any device that can reach your Mac and holds the key can generate images.
  • Treat the key like a password. If it leaks, regenerate it in Settings › API Server. Clients using the old key stop working until you give them the new one.
  • Any web page you give the key to can call the server from your browser. Paste it only into tools you trust.
  • With "Start the API server at launch" turned on, your Mac serves on every network it joins. Turn it off on a laptop that travels.
  • While the server runs, Studio pauses, your Mac stays awake, and switching or deleting models waits until you stop it.
  • Images made over the API land in your gallery. Turn on Incognito Mode, or turn off Save API images to gallery, to keep them out.
  • Your Mac makes one image at a time. Up to 8 requests wait their turn, and the next one gets a queue_full error.

Generate Images From curl, Python, and JavaScript

Each example makes one picture and saves it as a file. Put your key in an environment variable named PD_API_KEY, and replace your-mac.local with your Mac's address from Details in the API Server tab.

8963 is the default port. If you changed it in Settings › API Server, use yours.

curl

Sends the prompt and decodes the returned image with jq.

curl
curl -sS http://your-mac.local:8963/v1/images/generations \
  -H "Authorization: Bearer $PD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "a lighthouse at dusk, oil painting", "size": "1024x1024"}' \
  | jq -r '.data[0].b64_json // error(.error.message)' | base64 --decode > lighthouse.png

Python (OpenAI SDK)

Uses the official openai package. Fields the OpenAI API does not define, such as seed, go in extra_body. The SDK retries a full queue twice by default, then raises the error.

Python
import base64
import os

from openai import OpenAI

client = OpenAI(
    base_url="http://your-mac.local:8963/v1",
    api_key=os.environ["PD_API_KEY"],
)

result = client.images.generate(
    prompt="a lighthouse at dusk, oil painting",
    size="1024x1024",
    extra_body={"seed": 42},
)

with open("lighthouse.png", "wb") as f:
    f.write(base64.b64decode(result.data[0].b64_json))

JavaScript (OpenAI SDK, Node.js)

Runs in Node.js with the openai package, which sends extra fields such as seed as they are. Never run it in a web page, where anyone could read the key.

JavaScript
import { writeFileSync } from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "http://your-mac.local:8963/v1",
  apiKey: process.env.PD_API_KEY,
});

const result = await client.images.generate({
  prompt: "a lighthouse at dusk, oil painting",
  size: "1024x1024",
  seed: 42,
});

writeFileSync("lighthouse.png", Buffer.from(result.data[0].b64_json, "base64"));

Claude Image Generation Over MCP: Claude Code and Claude Desktop

Private Diffusion speaks the Model Context Protocol at /mcp. Connect Claude once, then ask for images in plain language.

Claude Code

With PD_API_KEY set as above, run this once in your terminal to add the server to Claude Code.

Terminal
claude mcp add --transport http private-diffusion http://your-mac.local:8963/mcp \
  --header "Authorization: Bearer $PD_API_KEY"

Do not add --scope project. It writes your key into a .mcp.json file meant to be shared.

Claude Desktop

Claude Desktop reaches the server through mcp-remote, a small bridge that runs on Node.js. In Claude Desktop, open Settings › Developer › Edit Config, add this entry, replace pd-your-key with your key, and restart Claude.

claude_desktop_config.json
{
  "mcpServers": {
    "private-diffusion": {
      "command": "npx",
      "args": [
        "-y",
        "[email protected]",
        "http://your-mac.local:8963/mcp",
        "--allow-http",
        "--transport",
        "http-only",
        "--header",
        "Authorization:${PRIVATE_DIFFUSION_AUTH}"
      ],
      "env": {
        "PRIVATE_DIFFUSION_AUTH": "Bearer pd-your-key"
      }
    }
  }
}

Needs Node.js. The bridge version is pinned.

MCP Tools

MCP Tools
ToolWhat it does
generate_imageMakes one to 4 images from a prompt. Takes the HTTP fields except quality and streaming, and returns jpeg with compression set to 85 unless you ask for PNG. An explicit model that is not ready is an error, not a fallback.
list_modelsLists the models ready on this Mac with the sizes, steps, and upscale factors each accepts here.
get_image_chunkUsed by MCP clients that display full-size images. You never call it yourself.

Authentication

Every request to /v1/* and /mcp carries your key in the Authorization: Bearer pd-… header. The app creates the key the first time the server starts. Reveal or regenerate it in Settings › API Server.

A missing or wrong key returns 401 with the code invalid_api_key.

Endpoints: /v1/images/generations, /v1/models, and /mcp

POST /v1/images/generations

Generates images from a text prompt. Requests and responses follow the OpenAI image API, with a few fields of its own.

Request parameters
ParameterValuesDefaultNotes
promptstringRequiredWhat to draw. Must not be empty.
modelstringActive modelA model id from the table below. An id that is unknown, not downloaded, or not supported on this Mac falls back to the active model, and the response's model names the one that ran.
n1–41How many images. Each uses the next seed.
size"auto" | "WxH""auto"Snaps to the nearest size the model supports, by shape first and then area. "auto" picks 1024×1024 when the model allows it. Extra large sizes need a Mac with more memory.
quality"auto" | "low" | "medium" | "high""auto"Only "high" changes the result, trading speed for detail.
output_format"png" | "jpeg""png"The image file format.
output_compression0–100100Compression for JPEG output. 100 compresses least.
seedintegerRandomSet it to repeat a result.
negative_promptstringNoneWhat to keep out of the image. Some models only; the rest return 400.
stepsintegerModel defaultMust sit inside the model's range. Fixed-step models accept only their own value.
upscale1.5 | 2 | 4NoneEnlarges the image after it is made. The model must offer the factor and its upscaler must be downloaded, or the request returns 400. On Macs with less memory, 4 becomes 2.
streambooleanfalseSends the result as server-sent events, with optional previews.
partial_images0–30How many previews to stream before the final image. Used only with stream.

Response

Images come back as base64 in b64_json, never as a URL, each with its seed and whether it carries a watermark. model names the model that ran.

JSON
{
  "created": 1767225600,
  "model": "zit",
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAA…",
      "seed": 42,
      "watermarked": false,
      "sensitive": false
    }
  ]
}

Streaming Partial Images

Set stream to true and the server replies with server-sent events. Each frame names its event and carries a JSON object.

Streaming Partial Images
EventData
image_generation.partial_imagetype, b64_json, partial_image_index, created_at, watermarked

A preview while the image forms. The index restarts at 0 for each image.

image_generation.completedtype, b64_json, seed, watermarked, sensitive, created_at

The finished image with its seed. One per image when you ask for more than one.

errorerror

Something failed after the stream opened. Errors before that arrive as a normal JSON response.

The stream closes after the last image. There is no separate done event.

GET /v1/models

Lists the models that are downloaded, ready, and supported on this Mac. Send one of their ids as model.

Which Models Work Over the API

Every Private Diffusion model works over the API once it is downloaded and your Mac supports it. Send the id from the second column as model.

Which Models Work Over the API
ModelIdNegative promptStepsUpscale
AnimaanimaNo8-12, default 82×
Flux.2 Klein 4BkleinYes41.5×, 2×
Mage Flow Turbomage-flow-turboNo41.5×, 2×
Krea 2 Turbokrea2-turboNo82×
Kroma TurbokromaYes8-12, default 102×
Z-Image-TurbozitYes92×, 4×
Juggernaut Z Fastjuggernaut-zYes82×, 4×
ERNIE Image Turboernie-turboNo81.5×, 2×
Chroma1-FlashchromaYes122×, 4×
Boogu Image TurbobooguNo42×, 4×

Krea 2 Turbo always runs 8 steps over the API, even when Studio is set to its faster 4-step mode.

Sizes and upscale factors depend on your Mac's memory. The list_models MCP tool reports what your Mac accepts.

Errors and Limits

Errors follow the OpenAI shape: a JSON object with a message, a type, the parameter at fault, and a code.

JSON
{
  "error": {
    "message": "steps must be between 8 and 12 for Kroma Turbo.",
    "type": "invalid_request_error",
    "param": "steps",
    "code": null
  }
}

Errors and Limits
StatusType and codeWhen
400invalid_request_errorA field is missing or out of range, or the body is not valid JSON. When one field is at fault, param names it.
401invalid_request_error · invalid_api_keyThe key is missing or wrong.
404invalid_request_error · not_foundThe path or method does not exist.
405—A request other than POST was sent to /mcp.
413invalid_request_error · request_too_largeThe body is larger than 2 MiB.
429rate_limit_error · queue_fullThe queue already holds 8 requests. Try again shortly.
500server_error · generation_failed · internal_errorGeneration failed on the Mac.
503server_error · server_stopping · runtime_unavailable · model_unavailableThe server is stopping, the engine needs a moment, or no model is active. Retry after the seconds in Retry-After.
  • Request bodies up to 2 MiB.
  • One to 4 images per request.
  • One image at a time, with up to 8 waiting.
  • Every 503 carries Retry-After of 10 seconds.

FAQ

  • Connect Claude Code or Claude Desktop to Private Diffusion over MCP with the address and key from Details in the app's API Server tab. Then ask Claude for a picture. Claude calls Private Diffusion, which makes the image on your Mac and hands it back.

  • Yes, for generating images. Point an OpenAI SDK at your Mac's address with your key, and the image generation call works as it does with OpenAI. The differences: images come back as base64, there is no editing or image input, and you get extra fields such as a seed and a negative prompt.

  • Yes. Any device that can reach your Mac can use it with your key. Use the address from Details in the app's API Server tab.

  • No. The server uses plain HTTP, so use it on networks you trust, keep the key private, and regenerate it if it leaks.

  • Every model you have downloaded on your Mac. Each keeps its own rules for steps, negative prompts, and upscaling, listed in the table on this page.

  • Your Mac makes one image at a time. Up to 8 requests wait in line, and the next one gets a 429 error until the line moves. The OpenAI SDKs retry that error twice by default before giving up.

  • No. The API Server is part of Private Diffusion for Mac. On iPhone and iPad, you generate images in the app itself.