API surface alignment¶
An audit of this server against NovelAI’s published API documentation, with
live verification against the real endpoints. Re-run it whenever a
generation request starts failing with a validation error, when NovelAI
announces an API change, or before a release that touches nai/.
What the official docs actually are¶
URL |
What it serves |
|---|---|
|
Swagger UI. Its inline config points at |
|
The real spec: Swagger 2.0, 27 paths, 57 definitions, titled “Omegalaser API”. |
|
Byte-identical copy of the same spec. |
|
Swagger UI whose |
|
“Observability API” (error tracking), unrelated to image generation. |
|
Product guides (194 pages). They describe features and UI settings, not endpoints or field names; they never mention a |
Fetch the spec with the project’s own browser-fingerprinted client (Cloudflare blocks plain clients):
from novelai_image_mcp.nai.http import create_http_client
async with create_http_client(timeout=60) as client:
spec = (await client.get("https://image.novelai.net/docs/doc.json")).json()
The spec is not a field whitelist¶
image.RequestParameters omits fields this client sends and the API accepts —
characterPrompts, autoSmea, ucPresetId, qualityPresetId (V5),
normalize_reference_strength_multiple, inpaintImg2ImgStrength,
legacy_uc, parameter-level use_coords — and it types model,
sampler and noise_schedule as plain strings with no enumeration. Treat
the spec as authoritative for which paths exist and response shapes,
and treat the live API as authoritative for which fields work.
Path inventory (27 documented)¶
Verified 2026-10-10 with a real account (Anlas before/after recorded).
Documented path |
This server |
Live result |
|---|---|---|
|
V3 / Furry ZIP path ( |
200 (ZIP) with |
|
V4 / V4.5 / V5 msgpack path |
200 ( |
|
|
200, |
|
|
200 only for V5 models on this host; the old |
|
|
200 for |
|
|
200 (binary vibe file, base64-encoded by the client) |
|
|
200 |
|
|
200 |
|
— |
200 (email/verification/ban status) |
|
— |
200 (priority refill) |
|
— |
401 with a persistent token |
|
— |
401 with a persistent token |
|
— |
text generation; out of scope for this image server |
|
— |
OpenAI-compatible text API; |
|
— |
account/product endpoints; mutations and private data are never called by this audit |
|
|
Not in this spec. Live 200 on |
Findings that changed this codebase¶
/ai/upscalemoved and is V5-only. The endpoint is onimage.novelai.net, takes{image, model, declared_blur_sigma}, and rejects every V3/V4/V4.5 model with “model … doesn’t support standalone upscaling”. The previous implementation posted{image, width, height, scale}toapi.novelai.net/ai/upscale, which now returns 404 — the tool was broken. Fixed byupscale(): it posts to the image host, sends the documented body, defaults the model toNOVELAI_UPSCALE_MODEL(nai-diffusion-5-full), and refuses anything but a 4× step (the API exposes no factor).suggest_tagsreturns{tag, count, confidence}, not the{description, text, count}shape the docs claimed.schemas.TagSuggestionnow mirrors the wire fields (withextra="allow"so upstream additions survive)./ai/generate-image(ZIP) 500s for V4/V4.5 models — those models must use/ai/generate-image-stream. The client already routes by model family (is_v4_model()), so no change was needed.
Unverified on purpose¶
emotionDirector tool: the request 500s on a synthetic image with no face; the other fivereq_typevalues return 200. Needs a portrait to confirm.Anything that mutates account state (
/user/consent,subscription/bind,create-persistent-token,objects/*deletes) — out of scope by design./user/giftkeysand/user/clientsettingsreturn 401 for persistent tokens; documenting the shape would require a session token.
See also¶
Architecture — how
nai/maps to the APIConfiguration — the endpoint and model settings