@felores/kie-ai-mcp-server 1.1.3 → 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
@@ -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,
@@ -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.3',
15
+ version: '1.2.0',
16
16
  });
17
17
  // Initialize client with config from environment
18
18
  const config = {
@@ -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
  };
@@ -289,6 +364,8 @@ class KieAiMcpServer {
289
364
  return await this.handleListTasks(args);
290
365
  case 'veo3_get_1080p_video':
291
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
  }
@@ -573,6 +650,62 @@ class KieAiMcpServer {
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.3",
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",