From 1c67e73a85f832d68a58d1514b797513245c8e18 Mon Sep 17 00:00:00 2001 From: DenSul Date: Thu, 16 Apr 2026 22:54:57 +0000 Subject: [PATCH] feat: make music_generation model configurable via MINIMAX_MUSIC_MODEL env The music_generation tool previously hardcoded model=music-2.0 which is deprecated. This change: - Adds MINIMAX_MUSIC_MODEL env variable for configuring the music model - Changes default from music-2.0 to music-2.6 (the currently available model) - Adds optional model parameter to music_generation() tool for per-request override - Reads model from env at startup with fallback to DEFAULT_MUSIC_MODEL Fixes music_generation being completely broken due to deprecated model. --- .env.example | 3 ++- README-CN.md | 3 ++- README.md | 3 ++- minimax_mcp/const.py | 3 ++- minimax_mcp/server.py | 5 +++- tests/test_music_model.py | 50 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 tests/test_music_model.py diff --git a/.env.example b/.env.example index c893dad..d5626e1 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,5 @@ MINIMAX_API_KEY=PUT_YOUR_KEY_HERE MINIMAX_MCP_BASE_PATH=~/Desktop MINIMAX_API_HOST=https://api.minimax.chat #optional resource mode[url, local], default is url -# MINIMAX_API_RESOURCE_MODE=local \ No newline at end of file +# MINIMAX_API_RESOURCE_MODE=local +MINIMAX_MUSIC_MODEL=music-2.6 \ No newline at end of file diff --git a/README-CN.md b/README-CN.md index 8e8bd65..f1d34ed 100644 --- a/README-CN.md +++ b/README-CN.md @@ -69,7 +69,8 @@ "MINIMAX_API_KEY": "填写你的API密钥", "MINIMAX_MCP_BASE_PATH": "本地输出目录路径,如/User/xxx/Desktop", "MINIMAX_API_HOST": "填写API Host, https://api.minimaxi.com 或 https://api.minimax.io", - "MINIMAX_API_RESOURCE_MODE": "可选配置,资源生成后的提供方式, 可选项为 [url|local], 默认为 url" + "MINIMAX_API_RESOURCE_MODE": "可选配置,资源生成后的提供方式, 可选项为 [url|local], 默认为 url", + "MINIMAX_MUSIC_MODEL": "音乐生成模型 (默认: music-2.6)" } } } diff --git a/README.md b/README.md index 196ea7d..b47ca4b 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,8 @@ Go to `Claude > Settings > Developer > Edit Config > claude_desktop_config.json` "MINIMAX_API_KEY": "insert-your-api-key-here", "MINIMAX_MCP_BASE_PATH": "local-output-dir-path, such as /User/xxx/Desktop", "MINIMAX_API_HOST": "api host, https://api.minimax.io | https://api.minimaxi.com", - "MINIMAX_API_RESOURCE_MODE": "optional, [url|local], url is default, audio/image/video are downloaded locally or provided in URL format" + "MINIMAX_API_RESOURCE_MODE": "optional, [url|local], url is default, audio/image/video are downloaded locally or provided in URL format", + "MINIMAX_MUSIC_MODEL": "Music generation model (default: music-2.6)" } } } diff --git a/minimax_mcp/const.py b/minimax_mcp/const.py index d1c3964..cb8b3e2 100644 --- a/minimax_mcp/const.py +++ b/minimax_mcp/const.py @@ -1,7 +1,7 @@ # speech model default values DEFAULT_VOICE_ID = "female-shaonv" DEFAULT_SPEECH_MODEL = "speech-2.6-hd" -DEFAULT_MUSIC_MODEL = "music-2.0" +DEFAULT_MUSIC_MODEL = "music-2.6" DEFAULT_SPEED = 1.0 DEFAULT_VOLUME = 1.0 DEFAULT_PITCH = 0 @@ -23,6 +23,7 @@ ENV_MINIMAX_API_HOST = "MINIMAX_API_HOST" ENV_MINIMAX_MCP_BASE_PATH = "MINIMAX_MCP_BASE_PATH" ENV_RESOURCE_MODE = "MINIMAX_API_RESOURCE_MODE" +ENV_MUSIC_MODEL = "MINIMAX_MUSIC_MODEL" RESOURCE_MODE_LOCAL = "local" # save resource to local file system RESOURCE_MODE_URL = "url" # provide resource url diff --git a/minimax_mcp/server.py b/minimax_mcp/server.py index c767441..99efd53 100644 --- a/minimax_mcp/server.py +++ b/minimax_mcp/server.py @@ -36,6 +36,7 @@ api_host = os.getenv(ENV_MINIMAX_API_HOST) resource_mode = os.getenv(ENV_RESOURCE_MODE) or RESOURCE_MODE_URL fastmcp_log_level = os.getenv(ENV_FASTMCP_LOG_LEVEL) or "WARNING" +music_model = os.getenv(ENV_MUSIC_MODEL) or DEFAULT_MUSIC_MODEL if not api_key: raise ValueError("MINIMAX_API_KEY environment variable is required") @@ -587,6 +588,7 @@ def text_to_image( bitrate (int, optional): Bitrate of generated music. Values: [32000, 64000, 128000, 256000] format (str, optional): Format of generated music. Values: ["mp3", "wav", "pcm"]. Defaults to "mp3" output_directory (str, optional): Directory to save the generated music file + model (str, optional): Music model to use for generation. Defaults to environment or config default Note: Currently supports generating music up to 1 minute in length. @@ -597,6 +599,7 @@ def text_to_image( def music_generation( prompt: str, lyrics: str, + model: str = None, sample_rate: int = DEFAULT_SAMPLE_RATE, bitrate: int = DEFAULT_BITRATE, format: str = DEFAULT_FORMAT, @@ -611,7 +614,7 @@ def music_generation( # Build request payload payload = { - "model": DEFAULT_MUSIC_MODEL, + "model": model or music_model, "prompt": prompt, "lyrics": lyrics, "audio_setting": { diff --git a/tests/test_music_model.py b/tests/test_music_model.py new file mode 100644 index 0000000..409ed10 --- /dev/null +++ b/tests/test_music_model.py @@ -0,0 +1,50 @@ +import pytest +from unittest.mock import patch + +from minimax_mcp.const import DEFAULT_MUSIC_MODEL, ENV_MUSIC_MODEL + + +def test_default_music_model_value(): + """Test that DEFAULT_MUSIC_MODEL equals 'music-2.6'.""" + assert DEFAULT_MUSIC_MODEL == "music-2.6" + + +def test_env_music_model_value(): + """Test that ENV_MUSIC_MODEL equals 'MINIMAX_MUSIC_MODEL'.""" + assert ENV_MUSIC_MODEL == "MINIMAX_MUSIC_MODEL" + + +@patch('os.getenv') +def test_music_model_resolved_from_env(mock_getenv): + """Test that music_model is correctly resolved from MINIMAX_MUSIC_MODEL env var.""" + # The server.py uses: music_model = os.getenv(ENV_MUSIC_MODEL) or DEFAULT_MUSIC_MODEL + mock_getenv.return_value = "music-custom-model" + + # Simulate what server.py does at module level + music_model = mock_getenv(ENV_MUSIC_MODEL) or DEFAULT_MUSIC_MODEL + + assert music_model == "music-custom-model" + mock_getenv.assert_called_with(ENV_MUSIC_MODEL) + + +@patch('os.getenv') +def test_music_model_uses_default_when_env_not_set(mock_getenv): + """Test that music_model uses DEFAULT_MUSIC_MODEL when env var is not set.""" + mock_getenv.return_value = None # Env var not set + + # Simulate what server.py does at module level + music_model = mock_getenv(ENV_MUSIC_MODEL) or DEFAULT_MUSIC_MODEL + + assert music_model == DEFAULT_MUSIC_MODEL + assert music_model == "music-2.6" + + +@patch('os.getenv') +def test_music_model_resolve_empty_string_env(mock_getenv): + """Test that empty string env var falls back to default.""" + mock_getenv.return_value = "" # Env var is empty string + + # Simulate what server.py does - empty string is falsy so falls back to default + music_model = mock_getenv(ENV_MUSIC_MODEL) or DEFAULT_MUSIC_MODEL + + assert music_model == DEFAULT_MUSIC_MODEL