Improve MCP discovery and release 0.1.2 (#3423)

Clarify the FunASR MCP tool contract for agent discovery, update the runtime to FunASR 1.3.29, and prepare the 0.1.2 Registry/GHCR release.
This commit is contained in:
zhifu gao
2026-07-26 20:07:31 +08:00
committed by GitHub
parent 5f0e67fec6
commit 02cc93d11f
6 changed files with 53 additions and 11 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
FROM python:3.10-slim
ARG FUNASR_VERSION=1.3.14
ARG VERSION=0.1.0
ARG FUNASR_VERSION=1.3.29
ARG VERSION=0.1.2
ARG VCS_REF=unknown
LABEL io.modelcontextprotocol.server.name="io.github.modelscope/funasr-mcp" \
+3 -3
View File
@@ -44,7 +44,7 @@ the public GHCR image and asks clients to mount one host audio directory at
Current published release:
- [GitHub release mcp-v0.1.1](https://github.com/modelscope/FunASR/releases/tag/mcp-v0.1.1)
- [GitHub release mcp-v0.1.2](https://github.com/modelscope/FunASR/releases/tag/mcp-v0.1.2)
- [Official MCP Registry entry](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.modelscope/funasr-mcp)
- [Public GHCR package](https://github.com/orgs/modelscope/packages/container/package/funasr-mcp)
@@ -62,7 +62,7 @@ To release a new MCP server version:
1. Update `version` and the OCI image tag in `server.json` together.
2. Merge the change after the MCP validation workflow passes.
3. Have a `modelscope` organization Owner push the matching `mcp-v<version>`
tag, for example `mcp-v0.1.1`.
tag, for example `mcp-v0.1.2`.
4. Approve the protected `mcp-registry-publish` environment deployment.
The official Registry only grants the `io.github.modelscope/*` namespace to a
@@ -76,7 +76,7 @@ After publication, clients can run the pinned image directly:
docker run --rm -i \
--mount type=bind,src=/path/to/audio,dst=/audio,readonly \
--mount type=volume,src=funasr-mcp-cache,dst=/root/.cache/modelscope \
ghcr.io/modelscope/funasr-mcp:0.1.1
ghcr.io/modelscope/funasr-mcp:0.1.2
```
When using the container, pass tool paths under `/audio`, such as
+23 -3
View File
@@ -123,17 +123,37 @@ def handle_request(request):
"tools": [
{
"name": "transcribe_audio",
"description": "Transcribe local speech audio with SenseVoiceSmall. Supports automatic or explicit Mandarin, Cantonese, English, Japanese, and Korean recognition with VAD segmentation.",
"description": (
"Transcribe one existing local audio file with FunASR and "
"SenseVoiceSmall. Use this tool when the user provides a file "
"path accessible to the MCP server and wants speech converted "
"to text. Do not use it for URLs, live microphone streams, or "
"files that are not mounted into the container. The first call "
"may download and load model weights into the model cache, so "
"it can take longer than later calls. Returns transcript text "
"and, when available, time-aligned segments. Supports automatic "
"or explicit Mandarin, Cantonese, English, Japanese, and Korean "
"recognition with VAD segmentation."
),
"inputSchema": {
"type": "object",
"properties": {
"audio_path": {
"type": "string",
"description": "Path to audio file (wav, mp3, flac, etc)"
"description": (
"Existing local audio file path visible to the MCP "
"server, such as /audio/meeting.wav for the container. "
"URLs and live streams are not accepted. Common WAV, "
"MP3, and FLAC files are supported."
),
},
"language": {
"type": "string",
"description": "Language hint: auto, zh, yue, en, ja, or ko",
"description": (
"Optional language hint. Use auto to detect Mandarin, "
"Cantonese, English, Japanese, or Korean, or provide an "
"explicit code: zh, yue, en, ja, or ko."
),
"enum": list(SUPPORTED_LANGUAGES),
"default": "auto",
}
+2 -2
View File
@@ -3,7 +3,7 @@
"name": "io.github.modelscope/funasr-mcp",
"title": "FunASR",
"description": "Transcribe local audio with FunASR and SenseVoice using private, on-device inference.",
"version": "0.1.1",
"version": "0.1.2",
"websiteUrl": "https://github.com/modelscope/FunASR/tree/main/examples/mcp_server",
"repository": {
"url": "https://github.com/modelscope/FunASR",
@@ -14,7 +14,7 @@
"packages": [
{
"registryType": "oci",
"identifier": "ghcr.io/modelscope/funasr-mcp:0.1.1",
"identifier": "ghcr.io/modelscope/funasr-mcp:0.1.2",
"runtimeHint": "docker",
"runtimeArguments": [
{
+21
View File
@@ -128,6 +128,27 @@ class FunASRMCPToolContractTest(unittest.TestCase):
language_schema["enum"], ["auto", "zh", "yue", "en", "ja", "ko"]
)
def test_tool_contract_explains_usage_side_effects_and_path_scope(self):
with patch.object(self.server, "send_response") as send_response:
self.server.handle_request({"id": 1, "method": "tools/list"})
tool = send_response.call_args[0][1]["tools"][0]
description = tool["description"].lower()
properties = tool["inputSchema"]["properties"]
audio_path_description = properties["audio_path"]["description"].lower()
language_description = properties["language"]["description"].lower()
self.assertIn("use this tool", description)
self.assertIn("do not use", description)
self.assertIn("first call", description)
self.assertIn("model cache", description)
self.assertIn("segments", description)
self.assertIn("local", audio_path_description)
self.assertIn("container", audio_path_description)
self.assertIn("url", audio_path_description)
self.assertIn("auto", language_description)
self.assertIn("explicit", language_description)
def test_empty_audio_path_returns_a_parameter_error(self):
with patch.object(self.server, "send_response") as send_response:
self.server.handle_request(
@@ -34,6 +34,7 @@ class MCPRegistryMetadataTest(unittest.TestCase):
"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
)
self.assertEqual(self.metadata["name"], "io.github.modelscope/funasr-mcp")
self.assertEqual(self.metadata["version"], "0.1.2")
self.assertLessEqual(len(self.metadata["description"]), 100)
self.assertEqual(
self.metadata["repository"],
@@ -89,7 +90,7 @@ class MCPRegistryMetadataTest(unittest.TestCase):
)
self.assertIsNotNone(match)
self.assertEqual(match.group(1), self.metadata["name"])
self.assertIn("ARG FUNASR_VERSION=1.3.14", dockerfile)
self.assertIn("ARG FUNASR_VERSION=1.3.29", dockerfile)
self.assertIn("funasr==${FUNASR_VERSION}", dockerfile)
def test_release_workflow_is_versioned_and_oidc_authenticated(self):