@felores/kie-ai-mcp-server 1.1.2 → 1.2.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/README.md CHANGED
@@ -9,6 +9,7 @@ An MCP (Model Context Protocol) server that provides access to Kie.ai's AI APIs
9
9
  - **Nano Banana Image Upscaling**: Upscale images 1-4x with optional face enhancement
10
10
  - **Veo3 Video Generation**: Professional-quality video generation with text-to-video and image-to-video capabilities
11
11
  - **1080p Video Upgrade**: Get high-definition versions of Veo3 videos
12
+ - **Suno Music Generation**: AI-powered music creation with multiple models (V3_5, V4, V4_5, V4_5PLUS, V5)
12
13
  - **Task Management**: SQLite-based task tracking with status polling
13
14
  - **Smart Endpoint Routing**: Automatic detection of task types for status checking
14
15
  - **Error Handling**: Comprehensive error handling and validation
@@ -87,7 +88,7 @@ Or if installed globally:
87
88
 
88
89
  ## Available Tools
89
90
 
90
- ### 1. `generate_nano_banana`
91
+ ### 1. `nano_banana_generate`
91
92
  Generate images using Nano Banana.
92
93
 
93
94
  **Parameters:**
@@ -104,7 +105,7 @@ Generate images using Nano Banana.
104
105
  }
105
106
  ```
106
107
 
107
- ### 2. `edit_nano_banana`
108
+ ### 2. `nano_banana_edit`
108
109
  Edit images using natural language prompts.
109
110
 
110
111
  **Parameters:**
@@ -123,7 +124,7 @@ Edit images using natural language prompts.
123
124
  }
124
125
  ```
125
126
 
126
- ### 3. `upscale_nano_banana`
127
+ ### 3. `nano_banana_upscale`
127
128
  Upscale images with optional face enhancement.
128
129
 
129
130
  **Parameters:**
@@ -140,7 +141,7 @@ Upscale images with optional face enhancement.
140
141
  }
141
142
  ```
142
143
 
143
- ### 4. `generate_veo3_video`
144
+ ### 4. `veo3_generate_video`
144
145
  Generate videos using Veo3.
145
146
 
146
147
  **Parameters:**
@@ -178,7 +179,7 @@ List recent tasks with their status.
178
179
  - `limit` (integer, optional): Max tasks to return (default: 20, max: 100)
179
180
  - `status` (string, optional): Filter by status ("pending", "processing", "completed", "failed")
180
181
 
181
- ### 7. `get_veo3_1080p_video`
182
+ ### 7. `veo3_get_1080p_video`
182
183
  Get 1080P high-definition version of a Veo3 video.
183
184
 
184
185
  **Parameters:**
@@ -187,6 +188,38 @@ Get 1080P high-definition version of a Veo3 video.
187
188
 
188
189
  **Note**: Not available for videos generated with fallback mode.
189
190
 
191
+ ### 8. `suno_generate_music`
192
+ Generate music with AI using Suno models.
193
+
194
+ **Parameters:**
195
+ - `prompt` (string, required): Description of desired audio content (max 5000 chars for V4_5+, V5; 3000 for V3_5, V4; 500 chars for non-custom mode)
196
+ - `customMode` (boolean, required): Enable advanced parameter customization
197
+ - `instrumental` (boolean, required): Generate instrumental music (no lyrics)
198
+ - `model` (enum, required): AI model version - "V3_5", "V4", "V4_5", "V4_5PLUS", or "V5"
199
+ - `callBackUrl` (string, required): URL to receive task completion updates
200
+ - `style` (string, optional): Music style/genre (required in custom mode, max 1000 chars for V4_5+, V5; 200 for V3_5, V4)
201
+ - `title` (string, optional): Track title (required in custom mode, max 80 chars)
202
+ - `negativeTags` (string, optional): Music styles to exclude (max 200 chars)
203
+ - `vocalGender` (enum, optional): Vocal gender preference - "m" or "f" (custom mode only)
204
+ - `styleWeight` (number, optional): Style adherence strength (0-1, up to 2 decimal places)
205
+ - `weirdnessConstraint` (number, optional): Creative deviation control (0-1, up to 2 decimal places)
206
+ - `audioWeight` (number, optional): Audio feature balance (0-1, up to 2 decimal places)
207
+
208
+ **Example:**
209
+ ```json
210
+ {
211
+ "prompt": "A calm and relaxing piano track with soft melodies",
212
+ "customMode": true,
213
+ "instrumental": true,
214
+ "model": "V5",
215
+ "callBackUrl": "https://api.example.com/callback",
216
+ "style": "Classical",
217
+ "title": "Peaceful Piano Meditation"
218
+ }
219
+ ```
220
+
221
+ **Note**: In custom mode, `style` and `title` are required. If `instrumental` is false, `prompt` is used as exact lyrics.
222
+
190
223
  ## API Endpoints
191
224
 
192
225
  The server interfaces with these Kie.ai API endpoints:
@@ -198,6 +231,8 @@ The server interfaces with these Kie.ai API endpoints:
198
231
  - **Nano Banana Edit**: `POST /api/v1/jobs/createTask`
199
232
  - **Nano Banana Upscale**: `POST /api/v1/jobs/createTask`
200
233
  - **Nano Banana Status**: `GET /api/v1/jobs/recordInfo`
234
+ - **Suno Music Generation**: `POST /api/v1/generate` ✅ **VALIDATED**
235
+ - **Suno Music Status**: `GET /api/v1/generate?taskId=XXX` ✅ **VALIDATED**
201
236
 
202
237
  All endpoints follow official Kie.ai API documentation.
203
238
 
@@ -209,7 +244,7 @@ The server uses SQLite to track tasks:
209
244
  CREATE TABLE tasks (
210
245
  id INTEGER PRIMARY KEY AUTOINCREMENT,
211
246
  task_id TEXT UNIQUE NOT NULL,
212
- api_type TEXT NOT NULL, -- 'nano-banana', 'nano-banana-edit', 'veo3'
247
+ api_type TEXT NOT NULL, -- 'nano-banana', 'nano-banana-edit', 'veo3', 'suno'
213
248
  status TEXT DEFAULT 'pending',
214
249
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
215
250
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
@@ -226,7 +261,7 @@ CREATE TABLE tasks (
226
261
  curl -X POST http://localhost:3000/tools/call \
227
262
  -H "Content-Type: application/json" \
228
263
  -d '{
229
- "name": "generate_nano_banana",
264
+ "name": "nano_banana_generate",
230
265
  "arguments": {
231
266
  "prompt": "A cat wearing a space helmet"
232
267
  }
@@ -239,7 +274,7 @@ curl -X POST http://localhost:3000/tools/call \
239
274
  curl -X POST http://localhost:3000/tools/call \
240
275
  -H "Content-Type: application/json" \
241
276
  -d '{
242
- "name": "generate_veo3_video",
277
+ "name": "veo3_generate_video",
243
278
  "arguments": {
244
279
  "prompt": "A peaceful garden with blooming flowers",
245
280
  "aspectRatio": "16:9",
@@ -335,44 +370,4 @@ MIT License - see LICENSE file for details.
335
370
 
336
371
  ## Changelog
337
372
 
338
- ### v1.1.1 (2025-01-14)
339
-
340
- **Improvements:**
341
- - Added `KIE_AI_CALLBACK_URL` environment variable for default callback URL
342
- - Added `enableTranslation` parameter to Veo3 (auto-translate prompts to English)
343
- - Added `Auto` option to Veo3 `aspectRatio`
344
- - Exposed `callBackUrl` parameter in Veo3 tool schema
345
- - Veo3 tool now fully aligned with official Kie.ai API documentation
346
-
347
- ### v1.1.0 (2025-01-14)
348
-
349
- **Breaking Changes:**
350
- - Migrated from `/playground/*` to official `/jobs/*` API endpoints for all Nano Banana operations
351
- - Updated status check endpoint from `/playground/recordInfo` to `/jobs/recordInfo`
352
-
353
- **New Features:**
354
- - Added `upscale_nano_banana` tool for image upscaling (1-4x) with optional GFPGAN face enhancement
355
- - Added `output_format` parameter (png/jpeg) to `generate_nano_banana` and `edit_nano_banana`
356
- - Added `image_size` parameter (11 aspect ratios) to `generate_nano_banana` and `edit_nano_banana`
357
-
358
- **Improvements:**
359
- - Increased prompt max length from 1,000 to 5,000 characters for Nano Banana tools
360
- - Increased max input images from 5 to 10 for `edit_nano_banana`
361
- - Enhanced `get_task_status` to properly parse `resultJson` and extract result URLs
362
- - Improved task status mapping: `waiting` → `processing`, `success` → `completed`, `fail` → `failed`
363
- - Task status now automatically updates local database with API responses
364
- - Better error message handling from API responses
365
-
366
- **Documentation:**
367
- - Updated README with all new parameters and tools
368
- - Corrected API endpoints to match official Kie.ai documentation
369
- - Added comprehensive examples for all tools
370
-
371
- ### v1.0.0 (2024-12-XX)
372
- - Initial release
373
- - Nano Banana image generation and editing
374
- - Veo3 video generation
375
- - 1080p video upgrade support
376
- - SQLite task tracking
377
- - Smart endpoint routing
378
- - Comprehensive error handling
373
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history and release notes.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
4
4
  import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { KieAiClient } from './kie-ai-client.js';
6
6
  import { TaskDatabase } from './database.js';
7
- import { NanoBananaGenerateSchema, NanoBananaEditSchema, NanoBananaUpscaleSchema, Veo3GenerateSchema } from './types.js';
7
+ import { NanoBananaGenerateSchema, NanoBananaEditSchema, NanoBananaUpscaleSchema, Veo3GenerateSchema, SunoGenerateSchema } from './types.js';
8
8
  class KieAiMcpServer {
9
9
  server;
10
10
  client;
@@ -12,7 +12,7 @@ class KieAiMcpServer {
12
12
  constructor() {
13
13
  this.server = new Server({
14
14
  name: 'kie-ai-mcp-server',
15
- version: '1.1.2',
15
+ version: '1.2.0',
16
16
  });
17
17
  // Initialize client with config from environment
18
18
  const config = {
@@ -66,7 +66,7 @@ class KieAiMcpServer {
66
66
  return {
67
67
  tools: [
68
68
  {
69
- name: 'generate_nano_banana',
69
+ name: 'nano_banana_generate',
70
70
  description: 'Generate images using Google\'s Gemini 2.5 Flash Image Preview (Nano Banana)',
71
71
  inputSchema: {
72
72
  type: 'object',
@@ -94,7 +94,7 @@ class KieAiMcpServer {
94
94
  }
95
95
  },
96
96
  {
97
- name: 'edit_nano_banana',
97
+ name: 'nano_banana_edit',
98
98
  description: 'Edit images using natural language prompts with Nano Banana Edit',
99
99
  inputSchema: {
100
100
  type: 'object',
@@ -129,7 +129,7 @@ class KieAiMcpServer {
129
129
  }
130
130
  },
131
131
  {
132
- name: 'upscale_nano_banana',
132
+ name: 'nano_banana_upscale',
133
133
  description: 'Upscale images using Nano Banana Upscale with optional face enhancement',
134
134
  inputSchema: {
135
135
  type: 'object',
@@ -156,7 +156,7 @@ class KieAiMcpServer {
156
156
  }
157
157
  },
158
158
  {
159
- name: 'generate_veo3_video',
159
+ name: 'veo3_generate_video',
160
160
  description: 'Generate professional-quality videos using Google\'s Veo3 API',
161
161
  inputSchema: {
162
162
  type: 'object',
@@ -250,7 +250,7 @@ class KieAiMcpServer {
250
250
  }
251
251
  },
252
252
  {
253
- name: 'get_veo3_1080p_video',
253
+ name: 'veo3_get_1080p_video',
254
254
  description: 'Get 1080P high-definition version of a Veo3 video (not available for fallback mode videos)',
255
255
  inputSchema: {
256
256
  type: 'object',
@@ -267,6 +267,81 @@ class KieAiMcpServer {
267
267
  },
268
268
  required: ['task_id']
269
269
  }
270
+ },
271
+ {
272
+ name: 'suno_generate_music',
273
+ description: 'Generate music with AI using Suno models (V3_5, V4, V4_5, V4_5PLUS, V5)',
274
+ inputSchema: {
275
+ type: 'object',
276
+ properties: {
277
+ prompt: {
278
+ type: 'string',
279
+ description: 'Description of the desired audio content. In custom mode: used as exact lyrics (max 5000 chars for V4_5+, V5; 3000 for V3_5, V4). In non-custom mode: core idea for auto-generated lyrics (max 500 chars)',
280
+ minLength: 1,
281
+ maxLength: 5000
282
+ },
283
+ customMode: {
284
+ type: 'boolean',
285
+ description: 'Enable advanced parameter customization. If true: requires style and title. If false: simplified mode with only prompt required'
286
+ },
287
+ instrumental: {
288
+ type: 'boolean',
289
+ description: 'Generate instrumental music (no lyrics). In custom mode: if true, only style and title required; if false, prompt used as exact lyrics'
290
+ },
291
+ model: {
292
+ type: 'string',
293
+ description: 'AI model version for generation',
294
+ enum: ['V3_5', 'V4', 'V4_5', 'V4_5PLUS', 'V5']
295
+ },
296
+ callBackUrl: {
297
+ type: 'string',
298
+ description: 'URL to receive task completion updates (required for all requests)',
299
+ format: 'uri'
300
+ },
301
+ style: {
302
+ type: 'string',
303
+ description: 'Music style/genre (required in custom mode, max 1000 chars for V4_5+, V5; 200 for V3_5, V4)',
304
+ maxLength: 1000
305
+ },
306
+ title: {
307
+ type: 'string',
308
+ description: 'Track title (required in custom mode, max 80 chars)',
309
+ maxLength: 80
310
+ },
311
+ negativeTags: {
312
+ type: 'string',
313
+ description: 'Music styles to exclude (optional, max 200 chars)',
314
+ maxLength: 200
315
+ },
316
+ vocalGender: {
317
+ type: 'string',
318
+ description: 'Vocal gender preference (optional, only effective in custom mode)',
319
+ enum: ['m', 'f']
320
+ },
321
+ styleWeight: {
322
+ type: 'number',
323
+ description: 'Strength of style adherence (optional, range 0-1, up to 2 decimal places)',
324
+ minimum: 0,
325
+ maximum: 1,
326
+ multipleOf: 0.01
327
+ },
328
+ weirdnessConstraint: {
329
+ type: 'number',
330
+ description: 'Controls experimental/creative deviation (optional, range 0-1, up to 2 decimal places)',
331
+ minimum: 0,
332
+ maximum: 1,
333
+ multipleOf: 0.01
334
+ },
335
+ audioWeight: {
336
+ type: 'number',
337
+ description: 'Balance weight for audio features (optional, range 0-1, up to 2 decimal places)',
338
+ minimum: 0,
339
+ maximum: 1,
340
+ multipleOf: 0.01
341
+ }
342
+ },
343
+ required: ['prompt', 'customMode', 'instrumental', 'model', 'callBackUrl']
344
+ }
270
345
  }
271
346
  ]
272
347
  };
@@ -275,20 +350,22 @@ class KieAiMcpServer {
275
350
  try {
276
351
  const { name, arguments: args } = request.params;
277
352
  switch (name) {
278
- case 'generate_nano_banana':
279
- return await this.handleGenerateNanoBanana(args);
280
- case 'edit_nano_banana':
281
- return await this.handleEditNanoBanana(args);
282
- case 'upscale_nano_banana':
283
- return await this.handleUpscaleNanoBanana(args);
284
- case 'generate_veo3_video':
285
- return await this.handleGenerateVeo3Video(args);
353
+ case 'nano_banana_generate':
354
+ return await this.handleNanoBananaGenerate(args);
355
+ case 'nano_banana_edit':
356
+ return await this.handleNanoBananaEdit(args);
357
+ case 'nano_banana_upscale':
358
+ return await this.handleNanoBananaUpscale(args);
359
+ case 'veo3_generate_video':
360
+ return await this.handleVeo3GenerateVideo(args);
286
361
  case 'get_task_status':
287
362
  return await this.handleGetTaskStatus(args);
288
363
  case 'list_tasks':
289
364
  return await this.handleListTasks(args);
290
- case 'get_veo3_1080p_video':
291
- return await this.handleGetVeo1080pVideo(args);
365
+ case 'veo3_get_1080p_video':
366
+ return await this.handleVeo3Get1080pVideo(args);
367
+ case 'suno_generate_music':
368
+ return await this.handleSunoGenerateMusic(args);
292
369
  default:
293
370
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
294
371
  }
@@ -302,7 +379,7 @@ class KieAiMcpServer {
302
379
  }
303
380
  });
304
381
  }
305
- async handleGenerateNanoBanana(args) {
382
+ async handleNanoBananaGenerate(args) {
306
383
  try {
307
384
  const request = NanoBananaGenerateSchema.parse(args);
308
385
  const response = await this.client.generateNanoBanana(request);
@@ -328,14 +405,14 @@ class KieAiMcpServer {
328
405
  };
329
406
  }
330
407
  catch (error) {
331
- return this.formatError('generate_nano_banana', error, {
408
+ return this.formatError('nano_banana_generate', error, {
332
409
  prompt: 'Required: text description of image to generate (max 5000 chars)',
333
410
  output_format: 'Optional: "png" or "jpeg"',
334
411
  image_size: 'Optional: aspect ratio like "16:9", "1:1", etc.'
335
412
  });
336
413
  }
337
414
  }
338
- async handleEditNanoBanana(args) {
415
+ async handleNanoBananaEdit(args) {
339
416
  try {
340
417
  const request = NanoBananaEditSchema.parse(args);
341
418
  const response = await this.client.editNanoBanana(request);
@@ -361,7 +438,7 @@ class KieAiMcpServer {
361
438
  };
362
439
  }
363
440
  catch (error) {
364
- return this.formatError('edit_nano_banana', error, {
441
+ return this.formatError('nano_banana_edit', error, {
365
442
  prompt: 'Required: editing instructions (max 5000 chars)',
366
443
  image_urls: 'Required: array of 1-10 image URLs to edit',
367
444
  output_format: 'Optional: "png" or "jpeg"',
@@ -369,7 +446,7 @@ class KieAiMcpServer {
369
446
  });
370
447
  }
371
448
  }
372
- async handleUpscaleNanoBanana(args) {
449
+ async handleNanoBananaUpscale(args) {
373
450
  try {
374
451
  const request = NanoBananaUpscaleSchema.parse(args);
375
452
  const response = await this.client.upscaleNanaBanana(request);
@@ -395,14 +472,14 @@ class KieAiMcpServer {
395
472
  };
396
473
  }
397
474
  catch (error) {
398
- return this.formatError('upscale_nano_banana', error, {
475
+ return this.formatError('nano_banana_upscale', error, {
399
476
  image: 'Required: URL of image to upscale (jpeg/png/webp, max 10MB)',
400
477
  scale: 'Optional: upscale factor 1-4 (default: 2)',
401
478
  face_enhance: 'Optional: enable face enhancement (default: false)'
402
479
  });
403
480
  }
404
481
  }
405
- async handleGenerateVeo3Video(args) {
482
+ async handleVeo3GenerateVideo(args) {
406
483
  try {
407
484
  const request = Veo3GenerateSchema.parse(args);
408
485
  // Use environment variable as fallback if callBackUrl not provided
@@ -432,7 +509,7 @@ class KieAiMcpServer {
432
509
  };
433
510
  }
434
511
  catch (error) {
435
- return this.formatError('generate_veo3_video', error, {
512
+ return this.formatError('veo3_generate_video', error, {
436
513
  prompt: 'Required: video description (max 2000 chars)',
437
514
  imageUrls: 'Optional: array with 1 image URL for image-to-video',
438
515
  model: 'Optional: "veo3" (quality) or "veo3_fast" (cost-efficient)',
@@ -544,7 +621,7 @@ class KieAiMcpServer {
544
621
  });
545
622
  }
546
623
  }
547
- async handleGetVeo1080pVideo(args) {
624
+ async handleVeo3Get1080pVideo(args) {
548
625
  try {
549
626
  const { task_id, index } = args;
550
627
  if (!task_id || typeof task_id !== 'string') {
@@ -567,12 +644,68 @@ class KieAiMcpServer {
567
644
  };
568
645
  }
569
646
  catch (error) {
570
- return this.formatError('get_veo3_1080p_video', error, {
647
+ return this.formatError('veo3_get_1080p_video', error, {
571
648
  task_id: 'Required: Veo3 task ID to get 1080p video for',
572
649
  index: 'Optional: video index (for multiple video results)'
573
650
  });
574
651
  }
575
652
  }
653
+ async handleSunoGenerateMusic(args) {
654
+ try {
655
+ const request = SunoGenerateSchema.parse(args);
656
+ const response = await this.client.generateSunoMusic(request);
657
+ if (response.code === 200 && response.data?.taskId) {
658
+ // Store task in database
659
+ await this.db.createTask({
660
+ task_id: response.data.taskId,
661
+ api_type: 'suno',
662
+ status: 'pending'
663
+ });
664
+ return {
665
+ content: [
666
+ {
667
+ type: 'text',
668
+ text: JSON.stringify({
669
+ success: true,
670
+ task_id: response.data.taskId,
671
+ message: 'Music generation task created successfully',
672
+ parameters: {
673
+ model: request.model,
674
+ customMode: request.customMode,
675
+ instrumental: request.instrumental,
676
+ callBackUrl: request.callBackUrl
677
+ },
678
+ next_steps: [
679
+ 'Use get_task_status to check generation progress',
680
+ 'Task completion will be sent to the provided callback URL',
681
+ 'Generation typically takes 1-3 minutes depending on model and length'
682
+ ]
683
+ }, null, 2)
684
+ }
685
+ ]
686
+ };
687
+ }
688
+ else {
689
+ throw new Error(response.msg || 'Failed to create music generation task');
690
+ }
691
+ }
692
+ catch (error) {
693
+ return this.formatError('suno_generate_music', error, {
694
+ prompt: 'Required: Description of desired audio content',
695
+ customMode: 'Required: Enable advanced customization (true/false)',
696
+ instrumental: 'Required: Generate instrumental music (true/false)',
697
+ model: 'Required: AI model version (V3_5, V4, V4_5, V4_5PLUS, V5)',
698
+ callBackUrl: 'Required: URL for task completion notifications',
699
+ style: 'Optional: Music style/genre (required in custom mode)',
700
+ title: 'Optional: Track title (required in custom mode, max 80 chars)',
701
+ negativeTags: 'Optional: Styles to exclude (max 200 chars)',
702
+ vocalGender: 'Optional: Vocal gender preference (m/f, custom mode only)',
703
+ styleWeight: 'Optional: Style adherence strength (0-1, 2 decimal places)',
704
+ weirdnessConstraint: 'Optional: Creative deviation control (0-1, 2 decimal places)',
705
+ audioWeight: 'Optional: Audio feature balance (0-1, 2 decimal places)'
706
+ });
707
+ }
708
+ }
576
709
  async run() {
577
710
  const transport = new StdioServerTransport();
578
711
  await this.server.connect(transport);
@@ -1,4 +1,4 @@
1
- import { KieAiConfig, KieAiResponse, NanoBananaGenerateRequest, NanaBananaEditRequest, NanoBananaUpscaleRequest, Veo3GenerateRequest, ImageResponse, TaskResponse } from './types.js';
1
+ import { KieAiConfig, KieAiResponse, NanoBananaGenerateRequest, NanaBananaEditRequest, NanoBananaUpscaleRequest, Veo3GenerateRequest, SunoGenerateRequest, ImageResponse, TaskResponse } from './types.js';
2
2
  export declare class KieAiClient {
3
3
  private config;
4
4
  constructor(config: KieAiConfig);
@@ -8,5 +8,6 @@ export declare class KieAiClient {
8
8
  upscaleNanaBanana(request: NanoBananaUpscaleRequest): Promise<KieAiResponse<ImageResponse>>;
9
9
  generateVeo3Video(request: Veo3GenerateRequest): Promise<KieAiResponse<TaskResponse>>;
10
10
  getTaskStatus(taskId: string, apiType?: string): Promise<KieAiResponse<any>>;
11
+ generateSunoMusic(request: SunoGenerateRequest): Promise<KieAiResponse<TaskResponse>>;
11
12
  getVeo1080pVideo(taskId: string, index?: number): Promise<KieAiResponse<any>>;
12
13
  }
@@ -77,7 +77,10 @@ export class KieAiClient {
77
77
  else if (apiType === 'nano-banana' || apiType === 'nano-banana-edit' || apiType === 'nano-banana-upscale') {
78
78
  return this.makeRequest(`/jobs/recordInfo?taskId=${taskId}`, 'GET');
79
79
  }
80
- // Fallback: try jobs first, then veo (for tasks not in database)
80
+ else if (apiType === 'suno') {
81
+ return this.makeRequest(`/generate?taskId=${taskId}`, 'GET');
82
+ }
83
+ // Fallback: try jobs first, then veo, then generate (for tasks not in database)
81
84
  try {
82
85
  return await this.makeRequest(`/jobs/recordInfo?taskId=${taskId}`, 'GET');
83
86
  }
@@ -86,10 +89,18 @@ export class KieAiClient {
86
89
  return await this.makeRequest(`/veo/record-info?taskId=${taskId}`, 'GET');
87
90
  }
88
91
  catch (veoError) {
89
- throw error;
92
+ try {
93
+ return await this.makeRequest(`/generate?taskId=${taskId}`, 'GET');
94
+ }
95
+ catch (sunoError) {
96
+ throw error;
97
+ }
90
98
  }
91
99
  }
92
100
  }
101
+ async generateSunoMusic(request) {
102
+ return this.makeRequest('/generate', 'POST', request);
103
+ }
93
104
  async getVeo1080pVideo(taskId, index) {
94
105
  const params = new URLSearchParams({ taskId });
95
106
  if (index !== undefined) {
package/dist/types.d.ts CHANGED
@@ -72,10 +72,77 @@ export declare const Veo3GenerateSchema: z.ZodObject<{
72
72
  enableFallback?: boolean | undefined;
73
73
  enableTranslation?: boolean | undefined;
74
74
  }>;
75
+ export declare const SunoGenerateSchema: z.ZodEffects<z.ZodObject<{
76
+ prompt: z.ZodString;
77
+ customMode: z.ZodBoolean;
78
+ instrumental: z.ZodBoolean;
79
+ model: z.ZodEnum<["V3_5", "V4", "V4_5", "V4_5PLUS", "V5"]>;
80
+ callBackUrl: z.ZodString;
81
+ style: z.ZodOptional<z.ZodString>;
82
+ title: z.ZodOptional<z.ZodString>;
83
+ negativeTags: z.ZodOptional<z.ZodString>;
84
+ vocalGender: z.ZodOptional<z.ZodEnum<["m", "f"]>>;
85
+ styleWeight: z.ZodOptional<z.ZodNumber>;
86
+ weirdnessConstraint: z.ZodOptional<z.ZodNumber>;
87
+ audioWeight: z.ZodOptional<z.ZodNumber>;
88
+ }, "strip", z.ZodTypeAny, {
89
+ prompt: string;
90
+ model: "V3_5" | "V4" | "V4_5" | "V4_5PLUS" | "V5";
91
+ callBackUrl: string;
92
+ customMode: boolean;
93
+ instrumental: boolean;
94
+ style?: string | undefined;
95
+ title?: string | undefined;
96
+ negativeTags?: string | undefined;
97
+ vocalGender?: "m" | "f" | undefined;
98
+ styleWeight?: number | undefined;
99
+ weirdnessConstraint?: number | undefined;
100
+ audioWeight?: number | undefined;
101
+ }, {
102
+ prompt: string;
103
+ model: "V3_5" | "V4" | "V4_5" | "V4_5PLUS" | "V5";
104
+ callBackUrl: string;
105
+ customMode: boolean;
106
+ instrumental: boolean;
107
+ style?: string | undefined;
108
+ title?: string | undefined;
109
+ negativeTags?: string | undefined;
110
+ vocalGender?: "m" | "f" | undefined;
111
+ styleWeight?: number | undefined;
112
+ weirdnessConstraint?: number | undefined;
113
+ audioWeight?: number | undefined;
114
+ }>, {
115
+ prompt: string;
116
+ model: "V3_5" | "V4" | "V4_5" | "V4_5PLUS" | "V5";
117
+ callBackUrl: string;
118
+ customMode: boolean;
119
+ instrumental: boolean;
120
+ style?: string | undefined;
121
+ title?: string | undefined;
122
+ negativeTags?: string | undefined;
123
+ vocalGender?: "m" | "f" | undefined;
124
+ styleWeight?: number | undefined;
125
+ weirdnessConstraint?: number | undefined;
126
+ audioWeight?: number | undefined;
127
+ }, {
128
+ prompt: string;
129
+ model: "V3_5" | "V4" | "V4_5" | "V4_5PLUS" | "V5";
130
+ callBackUrl: string;
131
+ customMode: boolean;
132
+ instrumental: boolean;
133
+ style?: string | undefined;
134
+ title?: string | undefined;
135
+ negativeTags?: string | undefined;
136
+ vocalGender?: "m" | "f" | undefined;
137
+ styleWeight?: number | undefined;
138
+ weirdnessConstraint?: number | undefined;
139
+ audioWeight?: number | undefined;
140
+ }>;
75
141
  export type NanoBananaGenerateRequest = z.infer<typeof NanoBananaGenerateSchema>;
76
142
  export type NanaBananaEditRequest = z.infer<typeof NanoBananaEditSchema>;
77
143
  export type NanoBananaUpscaleRequest = z.infer<typeof NanoBananaUpscaleSchema>;
78
144
  export type Veo3GenerateRequest = z.infer<typeof Veo3GenerateSchema>;
145
+ export type SunoGenerateRequest = z.infer<typeof SunoGenerateSchema>;
79
146
  export interface KieAiResponse<T = any> {
80
147
  code: number;
81
148
  msg: string;
@@ -91,7 +158,7 @@ export interface TaskResponse {
91
158
  export interface TaskRecord {
92
159
  id?: number;
93
160
  task_id: string;
94
- api_type: 'nano-banana' | 'nano-banana-edit' | 'nano-banana-upscale' | 'veo3';
161
+ api_type: 'nano-banana' | 'nano-banana-edit' | 'nano-banana-upscale' | 'veo3' | 'suno';
95
162
  status: 'pending' | 'processing' | 'completed' | 'failed';
96
163
  created_at: string;
97
164
  updated_at: string;
package/dist/types.js CHANGED
@@ -27,3 +27,30 @@ export const Veo3GenerateSchema = z.object({
27
27
  enableFallback: z.boolean().default(false),
28
28
  enableTranslation: z.boolean().default(true).optional()
29
29
  });
30
+ export const SunoGenerateSchema = z.object({
31
+ prompt: z.string().min(1).max(5000),
32
+ customMode: z.boolean(),
33
+ instrumental: z.boolean(),
34
+ model: z.enum(['V3_5', 'V4', 'V4_5', 'V4_5PLUS', 'V5']),
35
+ callBackUrl: z.string().url(),
36
+ style: z.string().max(1000).optional(),
37
+ title: z.string().max(80).optional(),
38
+ negativeTags: z.string().max(200).optional(),
39
+ vocalGender: z.enum(['m', 'f']).optional(),
40
+ styleWeight: z.number().min(0).max(1).multipleOf(0.01).optional(),
41
+ weirdnessConstraint: z.number().min(0).max(1).multipleOf(0.01).optional(),
42
+ audioWeight: z.number().min(0).max(1).multipleOf(0.01).optional()
43
+ }).refine((data) => {
44
+ if (data.customMode) {
45
+ if (data.instrumental) {
46
+ return data.style && data.title;
47
+ }
48
+ else {
49
+ return data.style && data.title && data.prompt;
50
+ }
51
+ }
52
+ return true;
53
+ }, {
54
+ message: "In customMode: style and title are always required, prompt is required when instrumental is false",
55
+ path: ["customMode"]
56
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felores/kie-ai-mcp-server",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server for Kie.ai APIs (Nano Banana image generation/editing and Veo3 video generation)",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -34,6 +34,13 @@
34
34
  "bugs": {
35
35
  "url": "https://github.com/felores/kie-ai-mcp-server/issues"
36
36
  },
37
+ "publishConfig": {
38
+ "registry": "https://registry.npmjs.org/"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/felores/kie-ai-mcp-server.git"
43
+ },
37
44
  "dependencies": {
38
45
  "@modelcontextprotocol/sdk": "^0.4.0",
39
46
  "sqlite3": "^5.1.6",