mcp-ai-music 1.0.6 → 1.0.7

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.
Files changed (2) hide show
  1. package/dist/index.js +33 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26,8 +26,8 @@ function getServiceBase() {
26
26
  process.env.SUNO_QUERY_BASE_URL ||
27
27
  process.env.SUNO_CALLBACK_URL);
28
28
  }
29
- // 构造回调地址
30
- function buildCallbackUrl(kind) {
29
+ // 构造回调地址,可附带 chatSessionId
30
+ function buildCallbackUrl(kind, chatSessionId) {
31
31
  const base = getServiceBase();
32
32
  if (!base) {
33
33
  throw new Error("未配置 SUNO_SERVICE_BASE(或兼容变量),用于设置服务端基地址");
@@ -37,7 +37,11 @@ function buildCallbackUrl(kind) {
37
37
  "upload-cover": "/suno/callback/upload-cover",
38
38
  "upload-extend": "/suno/callback/upload-extend",
39
39
  };
40
- return `${base.replace(/\/$/, "")}${pathMap[kind]}`;
40
+ const url = `${base.replace(/\/$/, "")}${pathMap[kind]}`;
41
+ if (chatSessionId) {
42
+ return `${url}?chat_session_id=${encodeURIComponent(chatSessionId)}`;
43
+ }
44
+ return url;
41
45
  }
42
46
  // 查询同样使用统一基地址
43
47
  function getQueryBase() {
@@ -351,7 +355,7 @@ async function makeApiRequestRaw(url, method, body, retries = 3) {
351
355
  }
352
356
  }
353
357
  // 生成音乐处理函数
354
- async function handleGenerateMusic(input) {
358
+ async function handleGenerateMusic(input, chatSessionId) {
355
359
  try {
356
360
  if (!input || typeof input !== 'object') {
357
361
  return {
@@ -456,7 +460,7 @@ async function handleGenerateMusic(input) {
456
460
  errorMessage: "title长度超过限制,最大允许80字符。",
457
461
  };
458
462
  }
459
- const callbackUrl = buildCallbackUrl("generate");
463
+ const callbackUrl = buildCallbackUrl("generate", chatSessionId);
460
464
  console.error(`使用回调地址: ${callbackUrl}`);
461
465
  // 构建请求体,根据API文档,当customMode=true且instrumental=false时,
462
466
  // 如果提供了lyrics,则使用lyrics作为prompt字段发送给API
@@ -505,7 +509,7 @@ async function handleGenerateMusic(input) {
505
509
  }
506
510
  }
507
511
  // 翻唱音乐处理函数
508
- async function handleCoverMusic(input) {
512
+ async function handleCoverMusic(input, chatSessionId) {
509
513
  try {
510
514
  if (!input || typeof input !== 'object') {
511
515
  return {
@@ -559,7 +563,7 @@ async function handleCoverMusic(input) {
559
563
  instrumental,
560
564
  model,
561
565
  negativeTags,
562
- callBackUrl: buildCallbackUrl("upload-cover"), // 必需的参数
566
+ callBackUrl: buildCallbackUrl("upload-cover", chatSessionId), // 必需的参数
563
567
  };
564
568
  // 根据Suno API文档,当instrumental=false且提供了lyrics时,使用lyrics作为prompt字段发送给API
565
569
  if (!instrumental && lyrics) {
@@ -596,7 +600,7 @@ async function handleCoverMusic(input) {
596
600
  }
597
601
  }
598
602
  // 扩展音乐处理函数
599
- async function handleExtendMusic(input) {
603
+ async function handleExtendMusic(input, chatSessionId) {
600
604
  try {
601
605
  if (!input || typeof input !== 'object') {
602
606
  return {
@@ -658,7 +662,7 @@ async function handleExtendMusic(input) {
658
662
  continueAt,
659
663
  model,
660
664
  negativeTags,
661
- callBackUrl: buildCallbackUrl("upload-extend"), // 必需的参数
665
+ callBackUrl: buildCallbackUrl("upload-extend", chatSessionId), // 必需的参数
662
666
  };
663
667
  // 根据Suno API文档,当instrumental=false且提供了lyrics时,使用lyrics作为prompt字段发送给API
664
668
  if (!instrumental && lyrics) {
@@ -755,6 +759,12 @@ async function handleQueryProgress(input) {
755
759
  status = 'complete';
756
760
  if (status === 'running')
757
761
  status = 'processing';
762
+ // 仅当存在最终音频链接(audioUrl 非空)才认为完成;
763
+ // 如果只有流式地址(streamAudioUrl)但 audioUrl 为空,则视为进行中
764
+ const hasFinalAudio = typeof result.audioUrl === 'string' && result.audioUrl.trim() !== '';
765
+ if (status === 'complete' && !hasFinalAudio) {
766
+ status = 'processing';
767
+ }
758
768
  let statusMessage = "";
759
769
  switch (status) {
760
770
  case 'pending':
@@ -783,7 +793,7 @@ async function handleQueryProgress(input) {
783
793
  status,
784
794
  progress,
785
795
  message: statusMessage,
786
- result: status === 'complete' ? {
796
+ result: status === 'complete' && hasFinalAudio ? {
787
797
  // 基本信息
788
798
  taskId: result.taskId,
789
799
  status: result.status,
@@ -953,14 +963,24 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
953
963
  try {
954
964
  const toolName = request.params.name;
955
965
  const toolInput = request.params.arguments;
966
+ // 解析 meta.chatSessionId (如果存在)
967
+ const chatSessionId = request?.meta?.chatSessionId
968
+ ?? request?.params?.meta?.chatSessionId
969
+ ?? undefined;
970
+ if (chatSessionId) {
971
+ console.error(`接收到 chatSessionId: ${chatSessionId}`);
972
+ }
973
+ else {
974
+ console.error("未在请求中检测到 chatSessionId(meta.chatSessionId)");
975
+ }
956
976
  console.error(`收到工具调用请求: ${toolName}, 输入: ${JSON.stringify(toolInput)}`);
957
977
  switch (toolName) {
958
978
  case GENERATE_MUSIC_TOOL.name:
959
- return await handleGenerateMusic(toolInput);
979
+ return await handleGenerateMusic(toolInput, chatSessionId);
960
980
  case COVER_MUSIC_TOOL.name:
961
- return await handleCoverMusic(toolInput);
981
+ return await handleCoverMusic(toolInput, chatSessionId);
962
982
  case EXTEND_MUSIC_TOOL.name:
963
- return await handleExtendMusic(toolInput);
983
+ return await handleExtendMusic(toolInput, chatSessionId);
964
984
  case QUERY_PROGRESS_TOOL.name:
965
985
  return await handleQueryProgress(toolInput);
966
986
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-ai-music",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "AI作曲MCP服务 - 基于Suno4.5 API的音乐生成、翻唱、扩展和进度查询工具",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {