novelai_image_mcp.nai — NovelAI HTTP client¶
The nai/ subpackage is the NovelAI HTTP client. It is MCP-agnostic —
it can be used standalone from any async Python code, independent of the
MCP server.
Submodules¶
novelai_image_mcp.nai.client¶
The high-level async client. Wraps the wire-format encoder
(payload.build_generation_payload) and response decoder
(response.parse_messagepack_images) over a shared
httpx.AsyncClient.
Complete NovelAI HTTP client built on a shared httpx async session.
A long-lived httpx.AsyncClient is owned by the instance (or supplied by the
MCP lifespan) and used for all NovelAI API traffic. Covers generation, Director,
utility, and account business logic.
- exception novelai_image_mcp.nai.client.MissingNovelAITokenError[source]¶
Bases:
NovelAIAuthenticationErrorNo usable NovelAI credential is configured.
- class novelai_image_mcp.nai.client.NovelAIClient(credentials, *, http_client=None, image_base_url='https://image.novelai.net', account_base_url='https://api.novelai.net', timeout=120.0, vibe_cache_entries=64)[source]¶
Bases:
objectProject-owned client for generation, tools, utilities, and account APIs.
- Parameters:
credentials (NovelAICredentials)
http_client (httpx.AsyncClient | None)
image_base_url (str)
account_base_url (str)
timeout (float)
vibe_cache_entries (int)
- async aclose()[source]¶
Close the underlying HTTP session when owned by this client.
- Return type:
None
- async generate(request)[source]¶
- Parameters:
request (GenerationRequest)
- Return type:
tuple[NovelAIImage, …]
- async stream_generation(request)[source]¶
Yield V4/V4.5 events as the active driver produces HTTP chunks.
- Parameters:
request (GenerationRequest)
- Return type:
- async director(tool, image, *, prompt='', defry=0, emotion=None, emotion_level=EmotionLevel.NORMAL)[source]¶
- Parameters:
tool (DirectorTool)
image (bytes)
prompt (str)
defry (int)
emotion (Emotion | None)
emotion_level (EmotionLevel)
- Return type:
- async annotate(image, model)[source]¶
- Parameters:
image (bytes)
model (ControlNetModel)
- Return type:
- exception novelai_image_mcp.nai.client.NovelAIError[source]¶
Bases:
ExceptionBase class for NovelAI failures.
- exception novelai_image_mcp.nai.client.NovelAIProviderError[source]¶
Bases:
NovelAIErrorNovelAI rejected or failed the request.
- exception novelai_image_mcp.nai.client.NovelAIResponseError[source]¶
Bases:
NovelAIErrorNovelAI returned malformed or unsupported data.
- exception novelai_image_mcp.nai.client.NovelAITimeoutError[source]¶
Bases:
NovelAIErrorA request exceeded its timeout.
- exception novelai_image_mcp.nai.client.NovelAITransportError[source]¶
Bases:
NovelAIErrorThe request could not reach NovelAI.
- async novelai_image_mcp.nai.client.generate_image_from_plan(plan, *, client, n_samples=1, quality=True, uc_preset=0, noise_schedule='karras', cfg_rescale=0.0, dynamic_thresholding=False, auto_smea=False, prefer_brownian=True)[source]¶
Generate a single image from a high-level plan (used by the sync CLI).
The caller supplies the configured client plus the generation defaults (read from settings, not from a global config).
novelai_image_mcp.nai.constants¶
Enums for the NovelAI API surface: Action, Model, Sampler,
DirectorTool, Emotion, EmotionLevel, ControlNetModel, Endpoint,
NoiseSchedule. Plus the predicates is_v4_model and is_inpaint_model.
NovelAI protocol constants and model capability helpers.
- class novelai_image_mcp.nai.constants.IntEnum(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
-
Enum where members are also (and must be) ints
- class novelai_image_mcp.nai.constants.StrEnum(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
-
Enum where members are also (and must be) strings
- __new_member__(*values)¶
values must already be of type str
- class novelai_image_mcp.nai.constants.Endpoint(*values)[source]¶
Bases:
StrEnum- LOGIN = '/user/login'¶
- USER_DATA = '/user/data'¶
- SUBSCRIPTION = '/user/subscription'¶
- IMAGE = '/ai/generate-image'¶
- IMAGE_STREAM = '/ai/generate-image-stream'¶
- DIRECTOR = '/ai/augment-image'¶
- ENCODE_VIBE = '/ai/encode-vibe'¶
- UPSCALE = '/ai/upscale'¶
- ANNOTATE = '/ai/annotate-image'¶
- SUGGEST_TAGS = '/ai/generate-image/suggest-tags'¶
- class novelai_image_mcp.nai.constants.Model(*values)[source]¶
Bases:
StrEnum- V3 = 'nai-diffusion-3'¶
- V3_INPAINT = 'nai-diffusion-3-inpainting'¶
- FURRY = 'nai-diffusion-furry-3'¶
- FURRY_INPAINT = 'nai-diffusion-furry-3-inpainting'¶
- V4 = 'nai-diffusion-4-full'¶
- V4_INPAINT = 'nai-diffusion-4-full-inpainting'¶
- V4_CURATED = 'nai-diffusion-4-curated-preview'¶
- V4_CURATED_INPAINT = 'nai-diffusion-4-curated-inpainting'¶
- V4_5 = 'nai-diffusion-4-5-full'¶
- V4_5_INPAINT = 'nai-diffusion-4-5-full-inpainting'¶
- V4_5_CURATED = 'nai-diffusion-4-5-curated'¶
- V4_5_CURATED_INPAINT = 'nai-diffusion-4-5-curated-inpainting'¶
- class novelai_image_mcp.nai.constants.Action(*values)[source]¶
Bases:
StrEnum- GENERATE = 'generate'¶
- IMG2IMG = 'img2img'¶
- INPAINT = 'infill'¶
- class novelai_image_mcp.nai.constants.Sampler(*values)[source]¶
Bases:
StrEnum- EULER = 'k_euler'¶
- EULER_ANCESTRAL = 'k_euler_ancestral'¶
- DPM_2S_ANCESTRAL = 'k_dpmpp_2s_ancestral'¶
- DPM_2M = 'k_dpmpp_2m'¶
- DPM_2M_SDE = 'k_dpmpp_2m_sde'¶
- DPM_SDE = 'k_dpmpp_sde'¶
- DDIM = 'ddim_v3'¶
- class novelai_image_mcp.nai.constants.NoiseSchedule(*values)[source]¶
Bases:
StrEnum- NATIVE = 'native'¶
- KARRAS = 'karras'¶
- EXPONENTIAL = 'exponential'¶
- POLYEXPONENTIAL = 'polyexponential'¶
- class novelai_image_mcp.nai.constants.ControlNetModel(*values)[source]¶
Bases:
StrEnum- PALETTE_SWAP = 'hed'¶
- FORM_LOCK = 'midas'¶
- SCRIBBLER = 'fake_scribble'¶
- BUILDING_CONTROL = 'mlsd'¶
- LANDSCAPER = 'uniformer'¶
- class novelai_image_mcp.nai.constants.DirectorTool(*values)[source]¶
Bases:
StrEnum- LINE_ART = 'lineart'¶
- SKETCH = 'sketch'¶
- BACKGROUND_REMOVAL = 'bg-removal'¶
- DECLUTTER = 'declutter'¶
- COLORIZE = 'colorize'¶
- EMOTION = 'emotion'¶
- class novelai_image_mcp.nai.constants.Emotion(*values)[source]¶
Bases:
StrEnum- NEUTRAL = 'neutral'¶
- HAPPY = 'happy'¶
- SAD = 'sad'¶
- ANGRY = 'angry'¶
- SCARED = 'scared'¶
- SURPRISED = 'surprised'¶
- TIRED = 'tired'¶
- EXCITED = 'excited'¶
- NERVOUS = 'nervous'¶
- THINKING = 'thinking'¶
- CONFUSED = 'confused'¶
- SHY = 'shy'¶
- DISGUSTED = 'disgusted'¶
- SMUG = 'smug'¶
- BORED = 'bored'¶
- LAUGHING = 'laughing'¶
- IRRITATED = 'irritated'¶
- AROUSED = 'aroused'¶
- EMBARRASSED = 'embarrassed'¶
- WORRIED = 'worried'¶
- LOVE = 'love'¶
- DETERMINED = 'determined'¶
- HURT = 'hurt'¶
- PLAYFUL = 'playful'¶
- class novelai_image_mcp.nai.constants.EmotionLevel(*values)[source]¶
Bases:
IntEnum- NORMAL = 0¶
- SLIGHTLY_WEAK = 1¶
- WEAK = 2¶
- EVEN_WEAKER = 3¶
- VERY_WEAK = 4¶
- WEAKEST = 5¶
novelai_image_mcp.nai.models¶
Pydantic models for the wire format: GenerationRequest,
CharacterPrompt, NovelAIGenerationPlan.
Pure value objects shared by the NovelAI generation pipeline.
- novelai_image_mcp.nai.models.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)[source]¶
Add dunder methods based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.
- class novelai_image_mcp.nai.models.Action(*values)[source]¶
Bases:
StrEnum- GENERATE = 'generate'¶
- IMG2IMG = 'img2img'¶
- INPAINT = 'infill'¶
- class novelai_image_mcp.nai.models.Model(*values)[source]¶
Bases:
StrEnum- V3 = 'nai-diffusion-3'¶
- V3_INPAINT = 'nai-diffusion-3-inpainting'¶
- FURRY = 'nai-diffusion-furry-3'¶
- FURRY_INPAINT = 'nai-diffusion-furry-3-inpainting'¶
- V4 = 'nai-diffusion-4-full'¶
- V4_INPAINT = 'nai-diffusion-4-full-inpainting'¶
- V4_CURATED = 'nai-diffusion-4-curated-preview'¶
- V4_CURATED_INPAINT = 'nai-diffusion-4-curated-inpainting'¶
- V4_5 = 'nai-diffusion-4-5-full'¶
- V4_5_INPAINT = 'nai-diffusion-4-5-full-inpainting'¶
- V4_5_CURATED = 'nai-diffusion-4-5-curated'¶
- V4_5_CURATED_INPAINT = 'nai-diffusion-4-5-curated-inpainting'¶
- class novelai_image_mcp.nai.models.NoiseSchedule(*values)[source]¶
Bases:
StrEnum- NATIVE = 'native'¶
- KARRAS = 'karras'¶
- EXPONENTIAL = 'exponential'¶
- POLYEXPONENTIAL = 'polyexponential'¶
- class novelai_image_mcp.nai.models.Sampler(*values)[source]¶
Bases:
StrEnum- EULER = 'k_euler'¶
- EULER_ANCESTRAL = 'k_euler_ancestral'¶
- DPM_2S_ANCESTRAL = 'k_dpmpp_2s_ancestral'¶
- DPM_2M = 'k_dpmpp_2m'¶
- DPM_2M_SDE = 'k_dpmpp_2m_sde'¶
- DPM_SDE = 'k_dpmpp_sde'¶
- DDIM = 'ddim_v3'¶
- novelai_image_mcp.nai.models.normalize_tags(values)[source]¶
Trim tags and remove case-insensitive duplicates while preserving order.
- novelai_image_mcp.nai.models.normalize_negative_prompt(value)[source]¶
Split comma/newline negative prompt text into normalized tags.
- class novelai_image_mcp.nai.models.CharacterIntent(description: 'str', tags: 'tuple[str, ...]', negative_tags: 'tuple[str, ...]', center: 'PositionCoord')[source]¶
Bases:
object- Parameters:
- center: PositionCoord¶
- class novelai_image_mcp.nai.models.GenerationHints(width: 'int | None' = None, height: 'int | None' = None, steps: 'int | None' = None, scale: 'float | None' = None, sampler: 'str | None' = None, seed: 'int | None' = None, negative_tags: 'tuple[str, ...]' = ())[source]¶
Bases:
object- Parameters:
- class novelai_image_mcp.nai.models.PromptIntent(source_language: 'str', english_description: 'str', base_tags: 'tuple[str, ...]', generation: 'GenerationHints', characters: 'tuple[CharacterIntent, ...]', search_required: 'bool', search_query: 'str | None', search_reason: 'str | None')[source]¶
Bases:
object- Parameters:
source_language (str)
english_description (str)
generation (GenerationHints)
characters (tuple[CharacterIntent, ...])
search_required (bool)
search_query (str | None)
search_reason (str | None)
- generation: GenerationHints¶
- characters: tuple[CharacterIntent, ...]¶
- class novelai_image_mcp.nai.models.VisualResearch(facts: 'tuple[str, ...]', sources: 'tuple[str, ...]')[source]¶
Bases:
object
- class novelai_image_mcp.nai.models.TipoRequest(description: 'str', tags: 'tuple[str, ...]', visual_facts: 'tuple[str, ...]', seed: 'int')[source]¶
Bases:
object
- class novelai_image_mcp.nai.models.TipoPrompt(natural_language: 'str', tags: 'tuple[str, ...]')[source]¶
Bases:
object
- class novelai_image_mcp.nai.models.GenerationOverrides(width: 'int | None' = None, height: 'int | None' = None, steps: 'int | None' = None, scale: 'float | None' = None, sampler: 'str | None' = None, seed: 'int | None' = None, negative_prompt: 'str | None' = None)[source]¶
Bases:
object- Parameters:
- class novelai_image_mcp.nai.models.NovelAIGenerationPlan(prompt: 'str', negative_prompt: 'str', width: 'int', height: 'int', steps: 'int', scale: 'float', sampler: 'str', seed: 'int', base_caption: 'str', char_captions: 'tuple[dict[str, object], ...]', character_prompts: 'tuple[dict[str, object], ...]', use_coords: 'bool')[source]¶
Bases:
object- Parameters:
- class novelai_image_mcp.nai.models.CharacterPrompt(prompt: 'str', negative_prompt: 'str' = '', x: 'float' = 0.5, y: 'float' = 0.5, enabled: 'bool' = True)[source]¶
Bases:
object
- class novelai_image_mcp.nai.models.GenerationRequest(prompt, base_caption=None, model=Model.V4_5, action=Action.GENERATE, negative_prompt='', width=832, height=1216, n_samples=1, steps=28, scale=5.0, sampler=Sampler.EULER_ANCESTRAL, seed=0, extra_noise_seed=None, noise_schedule=NoiseSchedule.KARRAS, quality=True, uc_preset=0, dynamic_thresholding=False, cfg_rescale=0.0, smea=None, smea_dynamic=None, auto_smea=False, image=None, mask=None, strength=None, noise=None, add_original_image=True, controlnet_strength=1.0, controlnet_condition=None, controlnet_model=None, references=(), reference_information=(), reference_strengths=(), character_prompts=(), use_coords=False, use_order=True, legacy_uc=False, normalize_reference_strengths=True, deliberate_euler_ancestral_bug=False, prefer_brownian=True, skip_cfg_above_sigma=None, legacy=False, legacy_v3_extend=False, inpaint_img2img_strength=None)[source]¶
Bases:
objectComplete NovelAI generation request independent of the chat planner.
- Parameters:
prompt (str)
base_caption (str | None)
model (Model)
action (Action)
negative_prompt (str)
width (int)
height (int)
n_samples (int)
steps (int)
scale (float)
seed (int)
extra_noise_seed (int | None)
noise_schedule (NoiseSchedule | str)
quality (bool)
uc_preset (int)
dynamic_thresholding (bool)
cfg_rescale (float)
smea (bool | None)
smea_dynamic (bool | None)
auto_smea (bool)
image (str | None)
mask (str | None)
strength (float | None)
noise (float | None)
add_original_image (bool)
controlnet_strength (float)
controlnet_condition (str | None)
controlnet_model (str | None)
character_prompts (tuple[CharacterPrompt, ...])
use_coords (bool)
use_order (bool)
legacy_uc (bool)
normalize_reference_strengths (bool)
deliberate_euler_ancestral_bug (bool)
prefer_brownian (bool)
skip_cfg_above_sigma (int | None)
legacy (bool)
legacy_v3_extend (bool)
inpaint_img2img_strength (int | None)
- noise_schedule: NoiseSchedule | str¶
- character_prompts: tuple[CharacterPrompt, ...]¶
novelai_image_mcp.nai.auth¶
Argon2id access-key derivation + per-request tracking headers.
NovelAI credential validation and access-key derivation.
- novelai_image_mcp.nai.auth.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)[source]¶
Add dunder methods based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.
- class novelai_image_mcp.nai.auth.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])¶
Bases:
dateThe year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints.
- astimezone()¶
tz -> convert to local time in new timezone tz
- classmethod combine()¶
date, time -> datetime with same date and time fields
- ctime()¶
Return ctime() style string.
- date()¶
Return date object with same year, month and day.
- dst()¶
Return self.tzinfo.dst(self).
- fold¶
- classmethod fromisoformat(object, /)¶
string -> datetime from a string in most ISO 8601 formats
- classmethod fromtimestamp()¶
timestamp[, tz] -> tz’s local time from POSIX timestamp.
- hour¶
- isoformat()¶
[sep] -> string in ISO 8601 format, YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM]. sep is used to separate the year from the time, and defaults to ‘T’. The optional argument timespec specifies the number of additional terms of the time to include. Valid options are ‘auto’, ‘hours’, ‘minutes’, ‘seconds’, ‘milliseconds’ and ‘microseconds’.
- max = datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)¶
- microsecond¶
- min = datetime.datetime(1, 1, 1, 0, 0)¶
- minute¶
- classmethod now(tz=None)¶
Returns new datetime object representing current time local to tz.
- tz
Timezone object.
If no tz is specified, uses local timezone.
- replace()¶
Return datetime with new specified fields.
- resolution = datetime.timedelta(microseconds=1)¶
- second¶
- classmethod strptime()¶
string, format -> new datetime parsed from a string (like time.strptime()).
- time()¶
Return time object with same time but with tzinfo=None.
- timestamp()¶
Return POSIX timestamp as float.
- timetuple()¶
Return time tuple, compatible with time.localtime().
- timetz()¶
Return time object with same time and tzinfo.
- tzinfo¶
- tzname()¶
Return self.tzinfo.tzname(self).
- classmethod utcfromtimestamp()¶
Construct a naive UTC datetime from a POSIX timestamp.
- classmethod utcnow()¶
Return a new datetime representing UTC day and time.
- utcoffset()¶
Return self.tzinfo.utcoffset(self).
- utctimetuple()¶
Return UTC time tuple, compatible with time.localtime().
- class novelai_image_mcp.nai.auth.blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True, string=None)¶
Bases:
objectReturn a new BLAKE2b hash object.
- MAX_DIGEST_SIZE = 64¶
- MAX_KEY_SIZE = 64¶
- PERSON_SIZE = 16¶
- SALT_SIZE = 16¶
- block_size¶
- copy()¶
Return a copy of the hash object.
- digest()¶
Return the digest value as a bytes object.
- digest_size¶
- hexdigest()¶
Return the digest value as a string of hexadecimal digits.
- name¶
- update(data, /)¶
Update this hash object’s state with the provided bytes-like object.
- class novelai_image_mcp.nai.auth.NovelAICredentials(token: 'str | None' = None, username: 'str | None' = None, password: 'str | None' = None)[source]¶
Bases:
object
- novelai_image_mcp.nai.auth.derive_access_key(credentials)[source]¶
Derive the 64-character NovelAI login key from username/password.
- Parameters:
credentials (NovelAICredentials)
- Return type:
novelai_image_mcp.nai.payload¶
build_generation_payload — wire-format encoder (MessagePack-compatible).
NovelAI V4.5 wire payload mapping.
- class novelai_image_mcp.nai.payload.GenerationRequest(prompt, base_caption=None, model=Model.V4_5, action=Action.GENERATE, negative_prompt='', width=832, height=1216, n_samples=1, steps=28, scale=5.0, sampler=Sampler.EULER_ANCESTRAL, seed=0, extra_noise_seed=None, noise_schedule=NoiseSchedule.KARRAS, quality=True, uc_preset=0, dynamic_thresholding=False, cfg_rescale=0.0, smea=None, smea_dynamic=None, auto_smea=False, image=None, mask=None, strength=None, noise=None, add_original_image=True, controlnet_strength=1.0, controlnet_condition=None, controlnet_model=None, references=(), reference_information=(), reference_strengths=(), character_prompts=(), use_coords=False, use_order=True, legacy_uc=False, normalize_reference_strengths=True, deliberate_euler_ancestral_bug=False, prefer_brownian=True, skip_cfg_above_sigma=None, legacy=False, legacy_v3_extend=False, inpaint_img2img_strength=None)[source]¶
Bases:
objectComplete NovelAI generation request independent of the chat planner.
- Parameters:
prompt (str)
base_caption (str | None)
model (Model)
action (Action)
negative_prompt (str)
width (int)
height (int)
n_samples (int)
steps (int)
scale (float)
seed (int)
extra_noise_seed (int | None)
noise_schedule (NoiseSchedule | str)
quality (bool)
uc_preset (int)
dynamic_thresholding (bool)
cfg_rescale (float)
smea (bool | None)
smea_dynamic (bool | None)
auto_smea (bool)
image (str | None)
mask (str | None)
strength (float | None)
noise (float | None)
add_original_image (bool)
controlnet_strength (float)
controlnet_condition (str | None)
controlnet_model (str | None)
character_prompts (tuple[CharacterPrompt, ...])
use_coords (bool)
use_order (bool)
legacy_uc (bool)
normalize_reference_strengths (bool)
deliberate_euler_ancestral_bug (bool)
prefer_brownian (bool)
skip_cfg_above_sigma (int | None)
legacy (bool)
legacy_v3_extend (bool)
inpaint_img2img_strength (int | None)
- noise_schedule: NoiseSchedule | str¶
- character_prompts: tuple[CharacterPrompt, ...]¶
- class novelai_image_mcp.nai.payload.NovelAIGenerationPlan(prompt: 'str', negative_prompt: 'str', width: 'int', height: 'int', steps: 'int', scale: 'float', sampler: 'str', seed: 'int', base_caption: 'str', char_captions: 'tuple[dict[str, object], ...]', character_prompts: 'tuple[dict[str, object], ...]', use_coords: 'bool')[source]¶
Bases:
object- Parameters:
- novelai_image_mcp.nai.payload.build_payload(plan, *, model)[source]¶
Map an already-resolved plan to NovelAI’s V4.5 request shape.
- Parameters:
plan (NovelAIGenerationPlan)
model (str)
- Return type:
novelai_image_mcp.nai.response¶
Response parsing: NovelAIImage, parse_messagepack_images,
parse_zip_images, check_status, GenerationEvent.
NovelAI HTTP, ZIP, and MessagePack response parsing.
- novelai_image_mcp.nai.response.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)[source]¶
Add dunder methods based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.
- class novelai_image_mcp.nai.response.Any(*args, **kwargs)[source]¶
Bases:
objectSpecial type indicating an unconstrained type.
Any is assignable to every type.
Any assumed to have all methods and attributes.
All values are assignable to Any.
Note that all the above statements are true from the point of view of static type checkers. At runtime, Any cannot be used with instance checks.
- novelai_image_mcp.nai.response.cast(typ, val)[source]¶
Cast a value to a type.
This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don’t check anything (we want this to be as fast as possible).
- class novelai_image_mcp.nai.response.NovelAIImage(filename: 'str', data: 'bytes')[source]¶
Bases:
object
- class novelai_image_mcp.nai.response.GenerationEvent(event_type: 'str', sample_index: 'int', step_index: 'int', generation_id: 'str', sigma: 'float', image: 'NovelAIImage')[source]¶
Bases:
object- Parameters:
- image: NovelAIImage¶
- novelai_image_mcp.nai.response.check_status(status_code, content)[source]¶
Raise the domain error associated with an HTTP status.
- novelai_image_mcp.nai.response.parse_zip_images(content)[source]¶
- Parameters:
content (bytes)
- Return type:
tuple[NovelAIImage, …]
- class novelai_image_mcp.nai.response.MessagePackStreamParser[source]¶
Bases:
objectIncrementally parse NovelAI’s big-endian length-prefixed MessagePack.
- feed(chunk)[source]¶
- Parameters:
chunk (bytes)
- Return type:
tuple[GenerationEvent, …]
- novelai_image_mcp.nai.response.parse_messagepack_events(content)[source]¶
- Parameters:
content (bytes)
- Return type:
tuple[GenerationEvent, …]
- novelai_image_mcp.nai.response.parse_messagepack_images(content)[source]¶
- Parameters:
content (bytes)
- Return type:
tuple[NovelAIImage, …]
Note
The exception classes listed above are imported into response for
raising in check_status; they are documented under their defining
module, novelai_image_mcp.nai.exceptions (see the next subsection).
novelai_image_mcp.nai.exceptions¶
Domain exception hierarchy:
Typed NovelAI domain failures.
- exception novelai_image_mcp.nai.exceptions.NovelAIError[source]¶
Bases:
ExceptionBase class for NovelAI failures.
- exception novelai_image_mcp.nai.exceptions.NovelAIProviderError[source]¶
Bases:
NovelAIErrorNovelAI rejected or failed the request.
- exception novelai_image_mcp.nai.exceptions.NovelAIValidationError[source]¶
Bases:
NovelAIProviderErrorThe request is invalid.
- exception novelai_image_mcp.nai.exceptions.NovelAIAuthenticationError[source]¶
Bases:
NovelAIProviderErrorCredentials are missing, invalid, or expired.
- exception novelai_image_mcp.nai.exceptions.NovelAIInsufficientCreditsError[source]¶
Bases:
NovelAIProviderErrorThe account has insufficient Anlas or no subscription.
- exception novelai_image_mcp.nai.exceptions.NovelAIConcurrencyError[source]¶
Bases:
NovelAIProviderErrorThe account hit a concurrency or rate limit.
- exception novelai_image_mcp.nai.exceptions.NovelAITimeoutError[source]¶
Bases:
NovelAIErrorA request exceeded its timeout.
- exception novelai_image_mcp.nai.exceptions.NovelAITransportError[source]¶
Bases:
NovelAIErrorThe request could not reach NovelAI.
- exception novelai_image_mcp.nai.exceptions.NovelAIResponseError[source]¶
Bases:
NovelAIErrorNovelAI returned malformed or unsupported data.
- exception novelai_image_mcp.nai.exceptions.NovelAIImageError[source]¶
Bases:
NovelAIErrorAn input or output image is malformed or unsupported.
novelai_image_mcp.nai.service¶
create_novelai_client factory + NovelAIConfigLike protocol. The factory
takes a settings-like object and an httpx.AsyncClient, returns a fully
wired NovelAIClient.
High-level NovelAI service construction for the MCP server and CLI consumers.
A duck-typed config object (NovelAIConfigLike Protocol) keeps the nai
package decoupled from the MCP wrapper. The wrapper’s NovelAISettings
(pydantic-settings, env-driven) satisfies this protocol structurally; see
novelai_image_mcp.settings.
- class novelai_image_mcp.nai.service.NovelAIConfigLike(*args, **kwargs)[source]¶
Bases:
ProtocolStructural shape of any object supplying NovelAI client configuration.
- novelai_image_mcp.nai.service.create_novelai_client(config, *, http_client=None)[source]¶
Create a complete client from a configuration object.
Accepts either a token or a complete username/password pair. Pass a shared
http_clientwhen the caller (e.g. the MCP lifespan) wants connection pooling across requests; otherwise the client owns a private session.- Parameters:
config (NovelAIConfigLike)
http_client (httpx.AsyncClient | None)
- Return type: