novelai_image_mcp.tools

The 11 MCP tool functions. Each tool is async and returns a list of MCP content blocks (Image + text path). Dependencies — the NovelAIClient, the NovelAISettings and the per-request routing context — arrive as Depends(...) providers (deps.py), so they are resolved per request and never appear in the tool’s input schema.

See also

Tools reference for narrative docs covering every parameter, default, and example for each tool.

novelai_image_mcp.tools.generate

MCP tools: text-to-image, image-to-image, and inpainting.

async novelai_image_mcp.tools.generate.generate_image(prompt, negative_prompt='', model=None, width=None, height=None, steps=None, scale=None, sampler=None, seed=0, n_samples=1, quality=True, uc_preset=0, cfg_rescale=0.0, smea=None, smea_dynamic=None, auto_smea=False, straight_alpha=False, prefer_brownian=True, noise_schedule=NoiseSchedule.KARRAS, character_prompts=None, references=None, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), app=Depends(get_app_context))[source]

Generate one or more images from a text prompt (text-to-image).

Supports NovelAI V3 / V4 / V4.5 / V5 models. Pass references as a list of base64-encoded PNG/JPEG strings to apply vibe transfer (V4/V4.5 only - V5 does not support vibe transfer yet and rejects it). V5 models additionally accept English/Japanese natural-language prompts and the straight_alpha flag for true transparency (pair it with prompt tags such as transparent background or has alpha). character_prompts enables multi-character composition with per-character prompts and center coordinates (x, y in 0.1-0.9). Dimensions are rounded up to the nearest multiple of 64.

Parameters:
Return type:

list[Any]

async novelai_image_mcp.tools.generate.image_to_image(prompt, image, negative_prompt='', model=None, strength=0.3, noise=0.0, width=None, height=None, steps=None, scale=None, sampler=None, seed=0, n_samples=1, quality=True, uc_preset=0, noise_schedule=NoiseSchedule.KARRAS, cfg_rescale=0.0, extra_noise_seed=None, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), app=Depends(get_app_context))[source]

Generate a new image conditioned on an input image (image-to-image).

image is a base64-encoded PNG/JPEG. strength (0.01-0.99) controls how far the result diverges from the input; noise (0-0.99) adds extra variation. The model must match the input image domain.

Parameters:
  • prompt (str)

  • image (str)

  • negative_prompt (str)

  • model (Model | None)

  • strength (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=0.99)])])

  • noise (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.0), Le(le=0.99)])])

  • width (int | None)

  • height (int | None)

  • steps (int | None)

  • scale (float | None)

  • sampler (Sampler | None)

  • seed (int)

  • n_samples (Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=8)])])

  • quality (bool)

  • uc_preset (Literal[0, 1, 2, 3])

  • noise_schedule (NoiseSchedule)

  • cfg_rescale (float)

  • extra_noise_seed (int | None)

  • routing (RoutingContext)

  • route_scoped_output (bool)

  • app (AppContext)

Return type:

list[Any]

async novelai_image_mcp.tools.generate.inpaint(prompt, image, mask, negative_prompt='', model=None, strength=0.3, noise=0.0, width=None, height=None, steps=None, scale=None, sampler=None, seed=0, n_samples=1, quality=True, uc_preset=0, noise_schedule=NoiseSchedule.KARRAS, cfg_rescale=0.0, extra_noise_seed=None, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), app=Depends(get_app_context))[source]

Inpaint (locally redraw) a region of an image.

image and mask are base64-encoded PNG/JPEG; the mask marks the region to regenerate (non-transparent pixels are redrawn). Requires an inpainting model such as nai-diffusion-4-5-full-inpainting or nai-diffusion-5-full-inpainting.

Parameters:
  • prompt (str)

  • image (str)

  • mask (str)

  • negative_prompt (str)

  • model (Model | None)

  • strength (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=0.99)])])

  • noise (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.0), Le(le=0.99)])])

  • width (int | None)

  • height (int | None)

  • steps (int | None)

  • scale (float | None)

  • sampler (Sampler | None)

  • seed (int)

  • n_samples (Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=8)])])

  • quality (bool)

  • uc_preset (Literal[0, 1, 2, 3])

  • noise_schedule (NoiseSchedule)

  • cfg_rescale (float)

  • extra_noise_seed (int | None)

  • routing (RoutingContext)

  • route_scoped_output (bool)

  • app (AppContext)

Return type:

list[Any]

novelai_image_mcp.tools.enhance

MCP tools: upscale, Director tools, and ControlNet annotation.

async novelai_image_mcp.tools.enhance.annotate_image(image, model, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), app=Depends(get_app_context))[source]

Annotate an image with a ControlNet preprocessor.

image is a base64-encoded PNG/JPEG. model is one of: hed (palette swap), midas (form lock / depth), fake_scribble (scribbler), mlsd (building control), uniformer (landscaper). The returned image is the annotation (e.g. a line-art map) suitable for use as a ControlNet condition in a subsequent generation.

Parameters:
Return type:

list[Any]

async novelai_image_mcp.tools.enhance.director_tool(tool, image, prompt='', defry=0, emotion=None, emotion_level=EmotionLevel.NORMAL, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), features=Depends(get_effective_features), app=Depends(get_app_context))[source]

Apply a NovelAI Director tool to an image.

tool is one of: lineart, sketch, bg-removal, declutter, colorize, emotion. image is a base64-encoded PNG/JPEG. The emotion tool additionally requires an emotion name (e.g. happy, sad) and accepts an emotion_level (0-5, where 0 is normal intensity and 5 is weakest). prompt guides colorize and emotion; defry (0-10) sharpens line art.

emotion and emotion_level are experimental: they are served only to requests that opt in through the insiders header (X-MCP-Insiders: experimental-tools=true). Without that opt-in, passing either one fails with a ToolError; a non-default emotion_level alone counts as passing it. Both parameters stay visible in this tool’s schema either way, because a tool schema is published when the server starts and cannot vary per request.

Parameters:
Return type:

list[Any]

async novelai_image_mcp.tools.enhance.upscale_image(image, factor=4, routing=Depends(get_routing_context), route_scoped_output=Depends(get_route_scoped_output), app=Depends(get_app_context))[source]

Upscale an image 4x using NovelAI’s standalone upscaler.

image is a base64-encoded PNG/JPEG. NovelAI’s standalone upscaler offers a single 4x step — the API exposes no scaling factor — so factor only accepts 4. The upscaler runs on the V5 model configured by NOVELAI_UPSCALE_MODEL (default nai-diffusion-5-full) and consumes Anlas based on the source resolution.

Parameters:
Return type:

list[Any]

novelai_image_mcp.tools.tags

MCP tools: prompt-tag suggestion and vibe encoding.

async novelai_image_mcp.tools.tags.encode_vibe(reference, information_extracted=1.0, model=Model.V4_5, client=Depends(get_client))[source]

Encode a reference image into a NovelAI vibe token.

reference is a base64-encoded PNG/JPEG to encode. information_extracted (0.01-1.0) controls how strongly the vibe captures the reference’s identity (lower = more stylistic, higher = more literal). model must be a V4/V4.5 model (vibes are not supported on V3, and V5 does not support vibe transfer yet). Returns a base64 vibe token suitable for the references parameter of generate_image.

Parameters:
  • reference (str)

  • information_extracted (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=1.0)])])

  • model (Model)

  • client (NovelAIClient)

Return type:

str

async novelai_image_mcp.tools.tags.suggest_tags(prompt, model=Model.V4_5, language='en', client=Depends(get_client))[source]

Suggest NovelAI tags that complete or refine a prompt.

prompt is the partial prompt text to complete. model selects the tagger vocabulary (default nai-diffusion-4-5-full). language is the ISO 639-1 code for the response language (e.g. en, ja). Returns tag suggestions carrying the tag string, its training-set occurrence count and the tagger’s confidence.

Parameters:
Return type:

list[TagSuggestion]

novelai_image_mcp.tools.account

MCP tools: account queries and Anlas cost estimation.

async novelai_image_mcp.tools.account.estimate_anlas_cost(width, height, steps, n_samples=1, model=Model.V4_5, action=Action.GENERATE, strength=None, smea=None, smea_dynamic=None, auto_smea=False, opus=False)[source]

Estimate the Anlas cost of a generation without calling the API.

Mirrors NovelAI’s public web-client cost formula. action is one of generate, img2img, infill (inpaint). For img2img, strength (0.01-0.99) scales the cost proportionally. smea / smea_dynamic / auto_smea apply the SMEA multiplier. opus grants a free sample when the request is within Opus limits. Returns {"anlas": <cost>, "opus_free_sample": <bool>}.

This is a pure price calculation. It needs no image or mask, and it does not verify that the combination is runnable – an infill estimate with a non-inpainting model still returns a price. The generation tools enforce those requirements.

Note: on V5 models, Opus free generations are capped by NovelAI’s refillable “battery” usage limit (normal resolution, <=28 steps); once exhausted the API silently bills Anlas instead of erroring. The subscription response does not expose how much of that battery is left, so this estimate always reports the paid cost.

Parameters:
  • width (int)

  • height (int)

  • steps (int)

  • n_samples (Annotated[int, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=1), Le(le=8)])])

  • model (Model)

  • action (Action)

  • strength (Annotated[float, FieldInfo(annotation=NoneType, required=True, metadata=[Ge(ge=0.01), Le(le=0.99)])] | None)

  • smea (bool | None)

  • smea_dynamic (bool | None)

  • auto_smea (bool)

  • opus (bool)

Return type:

AnlasEstimate

async novelai_image_mcp.tools.account.get_subscription(client=Depends(get_client))[source]

Return the account subscription details and Anlas balance.

The shape mirrors NovelAI’s /user/subscription response. The keys observed on a live account are tier (0 = free, 1 = starter, …), active, expiresAt, accountType, isGracePeriod, isNewCustomer, isPaypal, paymentProcessor, paymentProcessorData, perks (maxPriorityActions, startPriority, contextTokens, unlimitedMaxPriority, moduleTrainingSteps) and trainingStepsLeft (fixedTrainingStepsLeft, purchasedTrainingSteps). Use this to inspect the active plan before a generation.

Parameters:

client (NovelAIClient)

Return type:

dict[str, Any]

async novelai_image_mcp.tools.account.get_user_data(client=Depends(get_client))[source]

Return the authenticated account’s user data.

Includes email, accountChain (registration source), and the priority epoch. Useful to confirm which account the server is authenticated as before issuing generation commands.

Parameters:

client (NovelAIClient)

Return type:

dict[str, Any]

novelai_image_mcp.tools (registration entry point)

MCP tool registration.

Importing this package imports every tool module; each module decorates the shared server instance imported from ..server as a side effect of import, so there is no registration function to call. server.py imports this package at the bottom of the module, after mcp exists.