Skip to content

Commit 2d87d57

Browse files
committed
fix: Correct WAV conversion to accept EITHER task_id OR audio_id
Per Suno API documentation: 'You can provide either taskId or audioId to identify the source track' Changes: - Update convert_to_wav() signature: callback_url required, task_id and audio_id optional - Validate that at least one ID (task_id or audio_id) is provided - Build payload dynamically based on which ID(s) are provided - Update MCP tool definition to reflect optional parameters - Update tool handler to support flexible ID parameters - Add comprehensive docstring with both usage examples This resolves the 'record does not exist' error by allowing users to provide just the audio_id (track ID) without requiring the task_id. Recommended usage: Provide audio_id for precise track conversion, especially when generation task has multiple tracks.
1 parent 2f69bae commit 2d87d57

2 files changed

Lines changed: 56 additions & 20 deletions

File tree

server.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,20 +150,24 @@ async def handle_list_tools() -> list[Tool]:
150150
),
151151
Tool(
152152
name="convert_to_wav",
153-
description="Convert a generated audio track to WAV format. Use the track ID (audioId) from a previously generated music track. Returns a task ID that can be used to check conversion status.",
153+
description="Convert a generated audio track to WAV format. Provide EITHER task_id OR audio_id (or both). Using audio_id is recommended for precision when a generation task has multiple tracks. Returns a conversion task ID that can be used to check conversion status.",
154154
inputSchema={
155155
"type": "object",
156156
"properties": {
157-
"audio_id": {
158-
"type": "string",
159-
"description": "Track ID (audioId) of the generated music to convert to WAV format"
160-
},
161157
"callback_url": {
162158
"type": "string",
163159
"description": "Webhook URL for conversion completion notification (e.g., 'https://example.com/webhook')"
160+
},
161+
"task_id": {
162+
"type": "string",
163+
"description": "Original generation task ID (taskId) from generate_music - converts all tracks from that generation (optional if audio_id provided)"
164+
},
165+
"audio_id": {
166+
"type": "string",
167+
"description": "Track ID (audioId) of the specific generated music track to convert - more precise, recommended (optional if task_id provided)"
164168
}
165169
},
166-
"required": ["audio_id", "callback_url"]
170+
"required": ["callback_url"]
167171
}
168172
),
169173
Tool(
@@ -403,16 +407,22 @@ async def handle_call_tool(name: str, arguments: dict | None) -> list[TextConten
403407

404408
elif name == "convert_to_wav":
405409
# Extract arguments
406-
audio_id = arguments.get("audio_id")
407410
callback_url = arguments.get("callback_url")
411+
task_id = arguments.get("task_id")
412+
audio_id = arguments.get("audio_id")
408413

409-
if not audio_id:
410-
raise ValueError("audio_id is required")
411414
if not callback_url:
412415
raise ValueError("callback_url is required")
413416

414-
# Convert to WAV
415-
result = await suno_client.convert_to_wav(audio_id, callback_url)
417+
if not task_id and not audio_id:
418+
raise ValueError("Either task_id or audio_id must be provided")
419+
420+
# Convert to WAV (pass whichever IDs were provided)
421+
result = await suno_client.convert_to_wav(
422+
callback_url=callback_url,
423+
task_id=task_id,
424+
audio_id=audio_id
425+
)
416426

417427
# Format response
418428
response_text = "WAV Conversion Started!\n\n"

suno_client.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,34 +240,60 @@ async def get_credits(self) -> Dict[str, Any]:
240240

241241
async def convert_to_wav(
242242
self,
243-
audio_id: str,
244-
callback_url: str
243+
callback_url: str,
244+
task_id: str = None,
245+
audio_id: str = None
245246
) -> Dict[str, Any]:
246247
"""
247248
Convert a generated audio track to WAV format.
248249
250+
Per Suno API docs: You can provide EITHER taskId OR audioId to identify the source track.
251+
Providing audioId ensures the exact track is converted (recommended when a task has multiple tracks).
252+
249253
Args:
250-
audio_id: Track ID (audioId) of the generated music to convert
251-
callback_url: Webhook URL for conversion completion notification
254+
callback_url: Webhook URL for conversion completion notification (required)
255+
task_id: Original generation task ID (taskId) from generate_music (optional)
256+
audio_id: Track ID (audioId) of the specific track to convert (optional)
252257
253258
Returns:
254259
Dictionary containing WAV conversion task information with taskId
255260
256261
Raises:
257262
SunoAPIError: If the API request fails
258-
ValueError: If required parameters are missing or invalid
263+
ValueError: If neither task_id nor audio_id is provided, or if callback_url is missing
264+
265+
Example:
266+
# Option 1: Convert using audio_id (recommended - more precise)
267+
music = await client.generate_music(prompt="Epic soundtrack", wait_audio=True)
268+
track_id = music['data']['sunoData'][0]['id']
269+
conversion = await client.convert_to_wav(
270+
callback_url="https://example.com/webhook",
271+
audio_id=track_id
272+
)
273+
274+
# Option 2: Convert using task_id (converts all tracks from that generation)
275+
generation_task_id = music['data']['taskId']
276+
conversion = await client.convert_to_wav(
277+
callback_url="https://example.com/webhook",
278+
task_id=generation_task_id
279+
)
259280
"""
260-
if not audio_id:
261-
raise ValueError("audio_id is required for WAV conversion")
262281
if not callback_url:
263282
raise ValueError("callback_url is required for WAV conversion")
264283

265-
# Build payload with required parameters
284+
if not task_id and not audio_id:
285+
raise ValueError("Either task_id or audio_id must be provided for WAV conversion")
286+
287+
# Build payload - include whichever ID was provided
266288
payload: Dict[str, Any] = {
267-
"audioId": audio_id,
268289
"callBackUrl": callback_url
269290
}
270291

292+
if task_id:
293+
payload["taskId"] = task_id
294+
if audio_id:
295+
payload["audioId"] = audio_id
296+
271297
try:
272298
response = await self.client.post("/api/v1/wav/generate", json=payload)
273299
response.raise_for_status()

0 commit comments

Comments
 (0)