nvidia-nim-mcp 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -153,6 +153,21 @@ export declare class NIMClient {
153
153
  embeddings(request: EmbeddingRequest): Promise<EmbeddingResponse>;
154
154
  rerank(request: RerankRequest): Promise<RerankResponse>;
155
155
  generateImage(request: ImageGenerationRequest): Promise<ImageGenerationResponse>;
156
+ generateImageFluxSchnell(request: {
157
+ prompt: string;
158
+ width?: number;
159
+ height?: number;
160
+ seed?: number;
161
+ steps?: number;
162
+ }): Promise<ImageGenerationResponse>;
163
+ generateImageFluxKontext(request: {
164
+ prompt: string;
165
+ image: string;
166
+ aspect_ratio?: string;
167
+ steps?: number;
168
+ cfg_scale?: number;
169
+ seed?: number;
170
+ }): Promise<ImageGenerationResponse>;
156
171
  analyzeImage(request: ImageAnalysisRequest): Promise<ChatCompletionResponse>;
157
172
  listModels(): Promise<string[]>;
158
173
  }
package/dist/client.js CHANGED
@@ -96,8 +96,13 @@ export class NIMClient {
96
96
  return new Error(`Authentication failed: ${apiMsg}`);
97
97
  if (status === 403)
98
98
  return new Error(`Authorization failed: ${apiMsg}`);
99
- if (status === 404)
100
- return new Error(`Model not found: ${apiMsg}`);
99
+ if (status === 404) {
100
+ const msg = `Model not found: ${apiMsg}. ` +
101
+ `Note: Image generation models (SDXL, FLUX, SD3) are not deployed on the free integration endpoint. ` +
102
+ `They require dedicated GPU instances (H100/B200). ` +
103
+ `Use a self-hosted NIM or check https://build.nvidia.com for available models.`;
104
+ return new Error(msg);
105
+ }
101
106
  if (status === 422)
102
107
  return new Error(`Invalid request: ${apiMsg}`);
103
108
  if (status === 429)
@@ -144,6 +149,91 @@ export class NIMClient {
144
149
  });
145
150
  return data;
146
151
  }
152
+ // ─── FLUX.1-schnell (AI Foundation Models) ──────────────────────────────────
153
+ async generateImageFluxSchnell(request) {
154
+ await this.httpClient.rateLimiter.acquire();
155
+ const payload = {
156
+ prompt: request.prompt,
157
+ width: request.width ?? 1024,
158
+ height: request.height ?? 1024,
159
+ seed: request.seed ?? 0,
160
+ steps: 4, // FLUX Schnell is fixed at 4 steps
161
+ };
162
+ const modelId = config.DEFAULT_FLUX_SCHNELL_MODEL;
163
+ const url = `${config.NVIDIA_AI_FOUNDATION_URL}/${modelId}`;
164
+ logger.debug("FLUX Schnell request", { prompt: request.prompt, width: payload.width, height: payload.height });
165
+ const response = await fetch(url, {
166
+ method: "POST",
167
+ headers: {
168
+ "Authorization": `Bearer ${config.NVIDIA_API_KEY}`,
169
+ "Accept": "application/json",
170
+ "Content-Type": "application/json",
171
+ },
172
+ body: JSON.stringify(payload),
173
+ signal: AbortSignal.timeout(config.IMAGE_GENERATION_TIMEOUT_MS),
174
+ });
175
+ if (!response.ok) {
176
+ const errorText = await response.text();
177
+ logger.error("FLUX Schnell API error", { status: response.status, error: errorText });
178
+ throw new Error(`FLUX Schnell API error (${response.status}): ${errorText}`);
179
+ }
180
+ const data = await response.json();
181
+ logger.debug("FLUX Schnell response", { keys: Object.keys(data), hasImages: !!data.images, hasImage: !!data.image, hasData: !!data.data, hasArtifacts: !!data.artifacts, dataType: typeof data.data, imagesType: typeof data.images });
182
+ // Handle different response formats
183
+ const images = data.images ?? data.data ?? data.artifacts ?? (data.image ? [data.image] : []);
184
+ return {
185
+ created: Date.now(),
186
+ model: modelId,
187
+ data: images.map((img) => ({
188
+ b64_json: img.b64_json ?? img.base64,
189
+ revised_prompt: request.prompt,
190
+ })),
191
+ usage: { total_images: images.length },
192
+ };
193
+ }
194
+ // ─── FLUX.1-kontext-dev (AI Foundation Models) ──────────────────────────────
195
+ async generateImageFluxKontext(request) {
196
+ await this.httpClient.rateLimiter.acquire();
197
+ const payload = {
198
+ prompt: request.prompt,
199
+ image: request.image,
200
+ aspect_ratio: request.aspect_ratio ?? "match_input_image",
201
+ steps: request.steps ?? 30,
202
+ cfg_scale: request.cfg_scale ?? 3.5,
203
+ seed: request.seed ?? 0,
204
+ };
205
+ const modelId = config.DEFAULT_FLUX_KONTEXT_MODEL;
206
+ const url = `${config.NVIDIA_AI_FOUNDATION_URL}/${modelId}`;
207
+ logger.debug("FLUX Kontext request", { prompt: request.prompt, aspect_ratio: payload.aspect_ratio, steps: payload.steps });
208
+ const response = await fetch(url, {
209
+ method: "POST",
210
+ headers: {
211
+ "Authorization": `Bearer ${config.NVIDIA_API_KEY}`,
212
+ "Accept": "application/json",
213
+ "Content-Type": "application/json",
214
+ },
215
+ body: JSON.stringify(payload),
216
+ signal: AbortSignal.timeout(config.IMAGE_GENERATION_TIMEOUT_MS),
217
+ });
218
+ if (!response.ok) {
219
+ const errorText = await response.text();
220
+ logger.error("FLUX Kontext API error", { status: response.status, error: errorText });
221
+ throw new Error(`FLUX Kontext API error (${response.status}): ${errorText}`);
222
+ }
223
+ const data = await response.json();
224
+ logger.debug("FLUX Kontext response", { keys: Object.keys(data), hasImages: !!data.images, hasImage: !!data.image, hasData: !!data.data, hasArtifacts: !!data.artifacts });
225
+ // Handle different response formats
226
+ const images = data.images ?? data.data ?? data.artifacts ?? (data.image ? [data.image] : []);
227
+ return {
228
+ created: Date.now(),
229
+ model: modelId,
230
+ data: images.map((img) => ({
231
+ b64_json: img.b64_json ?? img.base64,
232
+ revised_prompt: request.prompt,
233
+ })),
234
+ usage: { total_images: images.length },
235
+ };
236
+ }
147
237
  async analyzeImage(request) {
148
238
  await this.httpClient.rateLimiter.acquire();
149
239
  const payload = {
package/dist/config.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare class ConfigError extends Error {
4
4
  export declare function getConfig(): {
5
5
  NVIDIA_API_KEY?: string;
6
6
  NVIDIA_NIM_BASE_URL?: string;
7
+ NVIDIA_AI_FOUNDATION_URL?: string;
7
8
  MCP_SERVER_NAME?: string;
8
9
  MCP_SERVER_VERSION?: string;
9
10
  MCP_SERVER_PORT?: number;
@@ -18,6 +19,8 @@ export declare function getConfig(): {
18
19
  DEFAULT_TOP_P?: number;
19
20
  DEFAULT_MAX_TOKENS?: number;
20
21
  DEFAULT_IMAGE_MODEL?: string;
22
+ DEFAULT_FLUX_SCHNELL_MODEL?: string;
23
+ DEFAULT_FLUX_KONTEXT_MODEL?: string;
21
24
  IMAGE_GENERATION_TIMEOUT_MS?: number;
22
25
  ENABLE_IMAGE_GENERATION?: boolean;
23
26
  ENABLE_VISION?: boolean;
package/dist/config.js CHANGED
@@ -1,11 +1,16 @@
1
1
  import { z } from "zod";
2
2
  const ConfigSchema = z.object({
3
- // NVIDIA API - Primary connection
3
+ // NVIDIA API - Primary connection (self-hosted NIM)
4
4
  NVIDIA_API_KEY: z.string().min(1, "NVIDIA_API_KEY is required"),
5
5
  NVIDIA_NIM_BASE_URL: z
6
6
  .string()
7
7
  .url()
8
8
  .default("https://integrate.api.nvidia.com/v1"),
9
+ // NVIDIA AI Foundation Models (cloud, free tier available)
10
+ NVIDIA_AI_FOUNDATION_URL: z
11
+ .string()
12
+ .url()
13
+ .default("https://ai.api.nvidia.com/v1/genai"),
9
14
  // Server
10
15
  MCP_SERVER_NAME: z.string().default("nvidia-nim-mcp"),
11
16
  MCP_SERVER_VERSION: z.string().default("1.0.0"),
@@ -21,12 +26,14 @@ const ConfigSchema = z.object({
21
26
  MAX_RETRIES: z.coerce.number().int().min(0).max(10).default(3),
22
27
  RETRY_DELAY_MS: z.coerce.number().int().positive().default(1000),
23
28
  // Defaults
24
- DEFAULT_MODEL: z.string().default("z-ai/glm5"),
29
+ DEFAULT_MODEL: z.string().default("meta/llama-3.1-8b-instruct"),
25
30
  DEFAULT_TEMPERATURE: z.coerce.number().min(0).max(2).default(0.3),
26
31
  DEFAULT_TOP_P: z.coerce.number().min(0).max(1).default(0.95),
27
32
  DEFAULT_MAX_TOKENS: z.coerce.number().int().positive().default(4096),
28
- // Image Generation
29
- DEFAULT_IMAGE_MODEL: z.string().default("black-forest-labs/flux.1-dev"),
33
+ // Image Generation - AI Foundation Models (free tier available)
34
+ DEFAULT_IMAGE_MODEL: z.string().default("black-forest-labs/flux.1-schnell"),
35
+ DEFAULT_FLUX_SCHNELL_MODEL: z.string().default("black-forest-labs/flux.1-schnell"),
36
+ DEFAULT_FLUX_KONTEXT_MODEL: z.string().default("black-forest-labs/flux.1-kontext-dev"),
30
37
  IMAGE_GENERATION_TIMEOUT_MS: z.coerce.number().int().positive().default(300000),
31
38
  // Feature flags
32
39
  ENABLE_IMAGE_GENERATION: z.coerce.boolean().default(true),
package/dist/handlers.js CHANGED
@@ -2,6 +2,9 @@ import { NIM_MODELS, getModelsByCategory, getModel } from "./models.js";
2
2
  import { getConfig } from "./config.js";
3
3
  import { logger } from "./logger.js";
4
4
  import { ChatCompletionSchema, TextGenerationSchema, EmbeddingsSchema, RerankSchema, FunctionCallingSchema, ListModelsSchema, ModelInfoSchema, ImageGenerationSchema, ImageAnalysisSchema, MultimodalTaskSchema, CompareModelsSchema, } from "./tools.js";
5
+ import { z } from "zod";
6
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
7
+ import { dirname, resolve } from "path";
5
8
  const config = getConfig();
6
9
  function ok(data) {
7
10
  return {
@@ -14,6 +17,42 @@ function err(message) {
14
17
  isError: true,
15
18
  };
16
19
  }
20
+ // Extended schema for FLUX Kontext (image-to-image)
21
+ const FluxKontextSchema = ImageGenerationSchema.extend({
22
+ image: z.string().optional().describe("Base64 data URL of input image (required for FLUX Kontext)"),
23
+ aspect_ratio: z.string().optional().describe("Aspect ratio for output (e.g., 'match_input_image', '1:1', '16:9')"),
24
+ // File save options
25
+ save_path: z.string().optional().describe("Optional file path to save the generated image as PNG (e.g., './output/image.png' or '/absolute/path/image.png')"),
26
+ save_filename: z.string().optional().describe("Optional filename (without extension) to auto-generate path in current directory"),
27
+ });
28
+ // Helper function to save base64 image as PNG file
29
+ function saveBase64Image(base64, savePath, saveFilename) {
30
+ if (!savePath && !saveFilename) {
31
+ return null;
32
+ }
33
+ let filePath;
34
+ if (savePath) {
35
+ filePath = resolve(savePath);
36
+ }
37
+ else {
38
+ const timestamp = Date.now();
39
+ const filename = `${saveFilename || `generated_${timestamp}`}.png`;
40
+ filePath = resolve(process.cwd(), filename);
41
+ }
42
+ // Ensure directory exists
43
+ const dir = dirname(filePath);
44
+ if (!existsSync(dir)) {
45
+ mkdirSync(dir, { recursive: true });
46
+ }
47
+ // Remove data URL prefix if present
48
+ const base64Data = base64.replace(/^data:image\/[a-z]+;base64,/, "");
49
+ const buffer = Buffer.from(base64Data, "base64");
50
+ writeFileSync(filePath, buffer);
51
+ return {
52
+ path: filePath,
53
+ absolutePath: filePath,
54
+ };
55
+ }
17
56
  export class ToolHandlers {
18
57
  client;
19
58
  constructor(client) {
@@ -217,6 +256,69 @@ export class ToolHandlers {
217
256
  }
218
257
  const args = ImageGenerationSchema.parse(rawArgs);
219
258
  const model = args.model ?? config.DEFAULT_IMAGE_MODEL;
259
+ // Route to appropriate backend based on model
260
+ const isFluxSchnell = model === "black-forest-labs/flux.1-schnell" || model === config.DEFAULT_FLUX_SCHNELL_MODEL;
261
+ const isFluxKontext = model === "black-forest-labs/flux.1-kontext-dev" || model === config.DEFAULT_FLUX_KONTEXT_MODEL;
262
+ // FLUX.1-schnell: Fast text-to-image via AI Foundation
263
+ if (isFluxSchnell) {
264
+ const fluxArgs = FluxKontextSchema.parse(rawArgs); // Reuse schema, image is optional
265
+ const response = await this.client.generateImageFluxSchnell({
266
+ prompt: fluxArgs.prompt,
267
+ width: fluxArgs.width,
268
+ height: fluxArgs.height,
269
+ seed: fluxArgs.seed,
270
+ });
271
+ const images = response.data.map((img, idx) => {
272
+ const saved = saveBase64Image(img.b64_json, fluxArgs.save_path, fluxArgs.save_filename);
273
+ return {
274
+ index: idx,
275
+ b64_json: img.b64_json,
276
+ revised_prompt: img.revised_prompt,
277
+ saved_path: saved?.absolutePath,
278
+ };
279
+ });
280
+ return ok({
281
+ model: response.model,
282
+ created: response.created,
283
+ images,
284
+ usage: response.usage,
285
+ });
286
+ }
287
+ // FLUX.1-kontext-dev: Image-to-image editing via AI Foundation
288
+ if (isFluxKontext) {
289
+ const fluxArgs = FluxKontextSchema.parse(rawArgs);
290
+ if (!fluxArgs.image) {
291
+ return err("FLUX Kontext requires an 'image' parameter (base64 data URL of input image)");
292
+ }
293
+ const response = await this.client.generateImageFluxKontext({
294
+ prompt: fluxArgs.prompt,
295
+ image: fluxArgs.image,
296
+ aspect_ratio: fluxArgs.aspect_ratio,
297
+ steps: fluxArgs.steps,
298
+ cfg_scale: fluxArgs.cfg_scale,
299
+ seed: fluxArgs.seed,
300
+ });
301
+ const images = response.data.map((img, idx) => {
302
+ const saved = saveBase64Image(img.b64_json, fluxArgs.save_path, fluxArgs.save_filename);
303
+ return {
304
+ index: idx,
305
+ b64_json: img.b64_json,
306
+ revised_prompt: img.revised_prompt,
307
+ saved_path: saved?.absolutePath,
308
+ };
309
+ });
310
+ return ok({
311
+ model: response.model,
312
+ created: response.created,
313
+ images,
314
+ usage: response.usage,
315
+ });
316
+ }
317
+ // Self-hosted NIM (SDXL, SD3, flux.1-dev, etc.)
318
+ if (!config.DEFAULT_IMAGE_MODEL && !args.model) {
319
+ return err("No default image generation model configured for self-hosted NIM. " +
320
+ "Set DEFAULT_IMAGE_MODEL or specify a model explicitly.");
321
+ }
220
322
  const request = {
221
323
  model,
222
324
  prompt: args.prompt,
@@ -229,18 +331,23 @@ export class ToolHandlers {
229
331
  seed: args.seed,
230
332
  sampler: args.sampler,
231
333
  scheduler: args.scheduler,
232
- response_format: args.response_format,
334
+ response_format: args.response_format ?? "b64_json",
233
335
  };
234
336
  const response = await this.client.generateImage(request);
235
- return ok({
236
- model: response.model ?? model,
237
- created: response.created,
238
- images: response.data.map((img, idx) => ({
337
+ const images = response.data.map((img, idx) => {
338
+ const saved = saveBase64Image(img.b64_json ?? "", args.save_path, args.save_filename);
339
+ return {
239
340
  index: idx,
240
341
  url: img.url,
241
342
  b64_json: img.b64_json,
242
343
  revised_prompt: img.revised_prompt,
243
- })),
344
+ saved_path: saved?.absolutePath,
345
+ };
346
+ });
347
+ return ok({
348
+ model: response.model ?? model,
349
+ created: response.created,
350
+ images,
244
351
  usage: response.usage,
245
352
  });
246
353
  }
package/dist/logger.js CHANGED
@@ -10,7 +10,7 @@ export let logger = winston.createLogger({
10
10
  },
11
11
  transports: [
12
12
  new winston.transports.Console({
13
- stderrLevels: ["error", "warn"],
13
+ stderrLevels: ["error", "warn", "info", "debug", "silly"],
14
14
  }),
15
15
  ],
16
16
  });
@@ -27,7 +27,7 @@ export function initLogger(options) {
27
27
  },
28
28
  transports: [
29
29
  new winston.transports.Console({
30
- stderrLevels: ["error", "warn"],
30
+ stderrLevels: ["error", "warn", "info", "debug", "silly"],
31
31
  }),
32
32
  ],
33
33
  });
package/dist/models.js CHANGED
@@ -976,10 +976,49 @@ export const NIM_MODELS = {
976
976
  },
977
977
  tags: ["text-to-image", "photorealistic", "flux", "controlnet", "controlnet-canny", "controlnet-depth"],
978
978
  },
979
+ // === FLUX.1 AI Foundation Models (Free Tier) ===
980
+ "black-forest-labs/flux.1-schnell": {
981
+ id: "black-forest-labs/flux.1-schnell",
982
+ name: "FLUX.1 [schnell]",
983
+ description: "Fast text-to-image model (4 steps, distilled). Optimized for speed. Available on NVIDIA AI Foundation free tier.",
984
+ category: "image_generation",
985
+ contextLength: 512,
986
+ supportsStreaming: false,
987
+ supportsFunctionCalling: false,
988
+ supportsImageGeneration: true,
989
+ maxTokens: 512,
990
+ recommendedUseCases: [
991
+ "Fast text-to-image generation",
992
+ "Rapid prototyping",
993
+ "Real-time applications",
994
+ "Interactive image generation",
995
+ ],
996
+ license: "Apache 2.0 (non-commercial default, commercial via contact)",
997
+ commercialUse: false,
998
+ thirdPartyModel: true,
999
+ minGpuRequirements: ["N/A - Cloud API"],
1000
+ supportedHardware: ["Cloud"],
1001
+ runtimeEngines: ["NVIDIA AI Foundation"],
1002
+ imageGenSpecs: {
1003
+ supportedResolutions: ["1024x1024", "1152x896", "896x1152", "1344x768", "768x1344"],
1004
+ supportedAspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"],
1005
+ maxImagesPerRequest: 1,
1006
+ recommendedSamplers: ["euler"],
1007
+ recommendedSchedulers: ["simple"],
1008
+ defaultSteps: 4,
1009
+ defaultCfgScale: 1.0,
1010
+ supportsNegativePrompt: false,
1011
+ supportsImageToImage: false,
1012
+ supportsInpainting: false,
1013
+ supportsControlNet: false,
1014
+ },
1015
+ tags: ["text-to-image", "fast", "schnell", "flux", "free-tier", "distilled"],
1016
+ deploymentNotes: "Available via NVIDIA AI Foundation Models API (https://ai.api.nvidia.com/v1/genai/black-forest-labs/flux.1-schnell). 4-step distilled model for rapid generation.",
1017
+ },
979
1018
  "black-forest-labs/flux.1-kontext-dev": {
980
1019
  id: "black-forest-labs/flux.1-kontext-dev",
981
1020
  name: "FLUX.1 Kontext [dev]",
982
- description: "FLUX.1 variant for image-to-image editing with context preservation. Supports inpainting, outpainting, style transfer with layout preservation.",
1021
+ description: "Image-to-image editing with context preservation. Inpainting, outpainting, style transfer with layout preservation. Available on NVIDIA AI Foundation free tier.",
983
1022
  category: "image_generation",
984
1023
  contextLength: 512,
985
1024
  supportsStreaming: false,
@@ -991,27 +1030,29 @@ export const NIM_MODELS = {
991
1030
  "Inpainting and outpainting",
992
1031
  "Style transfer with layout preservation",
993
1032
  "Character consistency across images",
1033
+ "Object replacement in images",
994
1034
  ],
995
1035
  license: "Apache 2.0 (non-commercial default, commercial via contact)",
996
1036
  commercialUse: false,
997
1037
  thirdPartyModel: true,
998
- minGpuRequirements: ["1x H100 80GB", "1x B200"],
999
- supportedHardware: ["Blackwell", "Hopper", "Lovelace"],
1000
- runtimeEngines: ["TensorRT"],
1038
+ minGpuRequirements: ["N/A - Cloud API"],
1039
+ supportedHardware: ["Cloud"],
1040
+ runtimeEngines: ["NVIDIA AI Foundation"],
1001
1041
  imageGenSpecs: {
1002
1042
  supportedResolutions: ["1024x1024", "1152x896", "896x1152", "1344x768", "768x1344"],
1003
- supportedAspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"],
1043
+ supportedAspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21", "match_input_image"],
1004
1044
  maxImagesPerRequest: 1,
1005
1045
  recommendedSamplers: ["euler", "euler_a"],
1006
1046
  recommendedSchedulers: ["simple"],
1007
- defaultSteps: 20,
1047
+ defaultSteps: 30,
1008
1048
  defaultCfgScale: 3.5,
1009
1049
  supportsNegativePrompt: true,
1010
1050
  supportsImageToImage: true,
1011
1051
  supportsInpainting: true,
1012
1052
  supportsControlNet: false,
1013
1053
  },
1014
- tags: ["image-to-image", "editing", "inpainting", "outpainting", "style-transfer", "flux", "character-consistency"],
1054
+ tags: ["image-to-image", "editing", "inpainting", "outpainting", "style-transfer", "flux", "kontext", "free-tier", "character-consistency"],
1055
+ deploymentNotes: "Available via NVIDIA AI Foundation Models API (https://ai.api.nvidia.com/v1/genai/black-forest-labs/flux.1-kontext-dev). Requires input image as base64 data URL.",
1015
1056
  },
1016
1057
  // === Multimodal ===
1017
1058
  "nvidia/neva-22b": {
package/dist/tools.d.ts CHANGED
@@ -73,6 +73,7 @@ export declare const ChatCompletionSchema: z.ZodObject<{
73
73
  presence_penalty: z.ZodOptional<z.ZodNumber>;
74
74
  seed: z.ZodOptional<z.ZodNumber>;
75
75
  }, "strip", z.ZodTypeAny, {
76
+ seed?: number;
76
77
  model?: string;
77
78
  messages?: {
78
79
  role?: "system" | "user" | "assistant";
@@ -85,8 +86,8 @@ export declare const ChatCompletionSchema: z.ZodObject<{
85
86
  stop?: string | string[];
86
87
  frequency_penalty?: number;
87
88
  presence_penalty?: number;
88
- seed?: number;
89
89
  }, {
90
+ seed?: number;
90
91
  model?: string;
91
92
  messages?: {
92
93
  role?: "system" | "user" | "assistant";
@@ -99,7 +100,6 @@ export declare const ChatCompletionSchema: z.ZodObject<{
99
100
  stop?: string | string[];
100
101
  frequency_penalty?: number;
101
102
  presence_penalty?: number;
102
- seed?: number;
103
103
  }>;
104
104
  export declare const TextGenerationSchema: z.ZodObject<{
105
105
  model: z.ZodOptional<z.ZodString>;
@@ -290,9 +290,14 @@ export declare const ImageGenerationSchema: z.ZodObject<{
290
290
  sampler: z.ZodOptional<z.ZodString>;
291
291
  scheduler: z.ZodOptional<z.ZodString>;
292
292
  response_format: z.ZodDefault<z.ZodOptional<z.ZodEnum<["url", "b64_json"]>>>;
293
+ image: z.ZodOptional<z.ZodString>;
294
+ aspect_ratio: z.ZodOptional<z.ZodString>;
295
+ save_path: z.ZodOptional<z.ZodString>;
296
+ save_filename: z.ZodOptional<z.ZodString>;
293
297
  }, "strip", z.ZodTypeAny, {
294
- model?: string;
298
+ image?: string;
295
299
  seed?: number;
300
+ model?: string;
296
301
  prompt?: string;
297
302
  negative_prompt?: string;
298
303
  width?: number;
@@ -303,9 +308,13 @@ export declare const ImageGenerationSchema: z.ZodObject<{
303
308
  sampler?: string;
304
309
  scheduler?: string;
305
310
  response_format?: "url" | "b64_json";
311
+ aspect_ratio?: string;
312
+ save_path?: string;
313
+ save_filename?: string;
306
314
  }, {
307
- model?: string;
315
+ image?: string;
308
316
  seed?: number;
317
+ model?: string;
309
318
  prompt?: string;
310
319
  negative_prompt?: string;
311
320
  width?: number;
@@ -316,6 +325,9 @@ export declare const ImageGenerationSchema: z.ZodObject<{
316
325
  sampler?: string;
317
326
  scheduler?: string;
318
327
  response_format?: "url" | "b64_json";
328
+ aspect_ratio?: string;
329
+ save_path?: string;
330
+ save_filename?: string;
319
331
  }>;
320
332
  export declare const ImageAnalysisSchema: z.ZodObject<{
321
333
  model: z.ZodOptional<z.ZodString>;
@@ -755,13 +767,13 @@ export declare const TOOL_DEFINITIONS: readonly [{
755
767
  };
756
768
  }, {
757
769
  readonly name: "generate_image";
758
- readonly description: "Generate images from text prompts using NVIDIA NIM image generation models (Stable Diffusion XL, SDXL Turbo, SD3, FLUX.1). Supports various resolutions, samplers, and schedulers.";
770
+ readonly description: "Generate images from text prompts using NVIDIA NIM image generation models (Stable Diffusion XL, SDXL Turbo, SD3, FLUX.1). Supports various resolutions, samplers, and schedulers. FLUX.1-schnell and FLUX.1-kontext-dev are available on the free NVIDIA AI Foundation tier. Can save generated images as PNG files to disk.";
759
771
  readonly inputSchema: {
760
772
  readonly type: "object";
761
773
  readonly properties: {
762
774
  readonly model: {
763
775
  readonly type: "string";
764
- readonly description: "Image generation model ID (e.g., nvidia/stable-diffusion-xl, nvidia/sdxl-turbo, stabilityai/sd-3-medium, black-forest-labs/flux.1-dev)";
776
+ readonly description: "Image generation model ID (e.g., nvidia/stable-diffusion-xl, nvidia/sdxl-turbo, stabilityai/sd-3-medium, black-forest-labs/flux.1-dev, black-forest-labs/flux.1-schnell, black-forest-labs/flux.1-kontext-dev)";
765
777
  };
766
778
  readonly prompt: {
767
779
  readonly type: "string";
@@ -797,7 +809,7 @@ export declare const TOOL_DEFINITIONS: readonly [{
797
809
  readonly minimum: 1;
798
810
  readonly maximum: 100;
799
811
  readonly default: 20;
800
- readonly description: "Number of diffusion steps";
812
+ readonly description: "Number of diffusion steps (ignored for FLUX Schnell, fixed at 4)";
801
813
  };
802
814
  readonly cfg_scale: {
803
815
  readonly type: "number";
@@ -824,6 +836,22 @@ export declare const TOOL_DEFINITIONS: readonly [{
824
836
  readonly default: "url";
825
837
  readonly description: "Response format: URL or base64 JSON";
826
838
  };
839
+ readonly image: {
840
+ readonly type: "string";
841
+ readonly description: "Base64 data URL of input image (required for FLUX Kontext image-to-image editing, format: data:image/png;base64,...)";
842
+ };
843
+ readonly aspect_ratio: {
844
+ readonly type: "string";
845
+ readonly description: "Aspect ratio for output (e.g., 'match_input_image', '1:1', '16:9', '4:3', '3:4', '21:9')";
846
+ };
847
+ readonly save_path: {
848
+ readonly type: "string";
849
+ readonly description: "Optional file path to save the generated image as PNG (e.g., './output/image.png' or '/absolute/path/image.png')";
850
+ };
851
+ readonly save_filename: {
852
+ readonly type: "string";
853
+ readonly description: "Optional filename (without extension) to auto-generate path in current directory (e.g., 'my-image' creates './my-image.png')";
854
+ };
827
855
  };
828
856
  readonly required: readonly ["prompt"];
829
857
  };
package/dist/tools.js CHANGED
@@ -81,6 +81,12 @@ export const ImageGenerationSchema = z.object({
81
81
  sampler: z.string().optional().describe("Sampler algorithm (e.g., euler, euler_a, dpmpp_2m)"),
82
82
  scheduler: z.string().optional().describe("Scheduler type (e.g., karras, exponential, simple)"),
83
83
  response_format: z.enum(["url", "b64_json"]).optional().default("url").describe("Response format"),
84
+ // FLUX Kontext specific parameters
85
+ image: z.string().optional().describe("Base64 data URL of input image (required for FLUX Kontext image-to-image editing)"),
86
+ aspect_ratio: z.string().optional().describe("Aspect ratio for output (e.g., 'match_input_image', '1:1', '16:9', '4:3')"),
87
+ // File save options
88
+ save_path: z.string().optional().describe("Optional file path to save the generated image as PNG (e.g., './output/image.png' or '/absolute/path/image.png')"),
89
+ save_filename: z.string().optional().describe("Optional filename (without extension) to auto-generate path in current directory"),
84
90
  });
85
91
  export const ImageAnalysisSchema = z.object({
86
92
  model: z.string().optional().describe("Vision/multimodal model ID"),
@@ -281,22 +287,28 @@ export const TOOL_DEFINITIONS = [
281
287
  },
282
288
  {
283
289
  name: "generate_image",
284
- description: "Generate images from text prompts using NVIDIA NIM image generation models (Stable Diffusion XL, SDXL Turbo, SD3, FLUX.1). Supports various resolutions, samplers, and schedulers.",
290
+ description: "Generate images from text prompts using NVIDIA NIM image generation models (Stable Diffusion XL, SDXL Turbo, SD3, FLUX.1). Supports various resolutions, samplers, and schedulers. FLUX.1-schnell and FLUX.1-kontext-dev are available on the free NVIDIA AI Foundation tier. Can save generated images as PNG files to disk.",
285
291
  inputSchema: {
286
292
  type: "object",
287
293
  properties: {
288
- model: { type: "string", description: "Image generation model ID (e.g., nvidia/stable-diffusion-xl, nvidia/sdxl-turbo, stabilityai/sd-3-medium, black-forest-labs/flux.1-dev)" },
294
+ model: { type: "string", description: "Image generation model ID (e.g., nvidia/stable-diffusion-xl, nvidia/sdxl-turbo, stabilityai/sd-3-medium, black-forest-labs/flux.1-dev, black-forest-labs/flux.1-schnell, black-forest-labs/flux.1-kontext-dev)" },
289
295
  prompt: { type: "string", description: "Text prompt describing the image to generate" },
290
296
  negative_prompt: { type: "string", description: "Negative prompt to avoid unwanted features" },
291
297
  width: { type: "integer", minimum: 64, maximum: 2048, default: 1024, description: "Image width in pixels" },
292
298
  height: { type: "integer", minimum: 64, maximum: 2048, default: 1024, description: "Image height in pixels" },
293
299
  num_images: { type: "integer", minimum: 1, maximum: 4, default: 1, description: "Number of images to generate" },
294
- steps: { type: "integer", minimum: 1, maximum: 100, default: 20, description: "Number of diffusion steps" },
300
+ steps: { type: "integer", minimum: 1, maximum: 100, default: 20, description: "Number of diffusion steps (ignored for FLUX Schnell, fixed at 4)" },
295
301
  cfg_scale: { type: "number", minimum: 1, maximum: 20, default: 7.0, description: "Classifier-free guidance scale" },
296
302
  seed: { type: "integer", description: "Random seed for reproducibility" },
297
303
  sampler: { type: "string", description: "Sampler algorithm (e.g., euler, euler_a, dpmpp_2m, dpmpp_sde, ddim)" },
298
304
  scheduler: { type: "string", description: "Scheduler type (e.g., karras, exponential, simple, ddim_uniform)" },
299
305
  response_format: { type: "string", enum: ["url", "b64_json"], default: "url", description: "Response format: URL or base64 JSON" },
306
+ // FLUX Kontext specific parameters
307
+ image: { type: "string", description: "Base64 data URL of input image (required for FLUX Kontext image-to-image editing, format: data:image/png;base64,...)" },
308
+ aspect_ratio: { type: "string", description: "Aspect ratio for output (e.g., 'match_input_image', '1:1', '16:9', '4:3', '3:4', '21:9')" },
309
+ // File save options
310
+ save_path: { type: "string", description: "Optional file path to save the generated image as PNG (e.g., './output/image.png' or '/absolute/path/image.png')" },
311
+ save_filename: { type: "string", description: "Optional filename (without extension) to auto-generate path in current directory (e.g., 'my-image' creates './my-image.png')" },
300
312
  },
301
313
  required: ["prompt"],
302
314
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nvidia-nim-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Production-ready MCP server for NVIDIA NIM models - 50+ LLMs, multimodal, image generation, embeddings, reranking with rich metadata for agent selection",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",