media-agent-mcp 0.3.9__py3-none-any.whl → 0.3.10__py3-none-any.whl

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.
@@ -22,6 +22,17 @@ from typing import List, Optional
22
22
  import json
23
23
  from dotenv import load_dotenv
24
24
  import uvicorn
25
+ from tenacity import retry, stop_after_attempt, wait_fixed
26
+
27
+ def _is_result_error(result):
28
+ """Return True if the result is a dictionary with status 'error'."""
29
+ if isinstance(result, str):
30
+ try:
31
+ data = json.loads(result)
32
+ return isinstance(data, dict) and data.get('status') == 'error'
33
+ except json.JSONDecodeError:
34
+ return False
35
+ return isinstance(result, dict) and result.get('status') == 'error'
25
36
 
26
37
  from mcp.server.fastmcp import FastMCP
27
38
 
@@ -49,7 +60,8 @@ mcp = FastMCP("Media-Agent-MCP-Async")
49
60
 
50
61
 
51
62
  @mcp.tool()
52
- async def video_concat_tool(video_urls: List[str]) -> str:
63
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
64
+ async def video_concat_tool(video_urls: List[str]) -> dict:
53
65
  """
54
66
  Asynchronously concatenate multiple videos from URLs and upload to TOS.
55
67
 
@@ -57,13 +69,14 @@ async def video_concat_tool(video_urls: List[str]) -> str:
57
69
  video_urls: List of video URLs to concatenate in order
58
70
 
59
71
  Returns:
60
- JSON string with status, data, and message
72
+ Dictionary with status, data, and message
61
73
  """
62
74
  return await async_video_concat_tool(video_urls)
63
75
 
64
76
 
65
77
  @mcp.tool()
66
- async def video_last_frame_tool(video_url: str) -> str:
78
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
79
+ async def video_last_frame_tool(video_url: str) -> dict:
67
80
  """
68
81
  Asynchronously extract the last frame from a video file and upload to TOS.
69
82
 
@@ -71,13 +84,14 @@ async def video_last_frame_tool(video_url: str) -> str:
71
84
  video_url: URL or path to the video file
72
85
 
73
86
  Returns:
74
- JSON string with status, data, and message
87
+ Dictionary with status, data, and message
75
88
  """
76
89
  return await async_video_last_frame_tool(video_url)
77
90
 
78
91
 
79
92
  @mcp.tool()
80
- async def seedream_generate_image_tool(prompt: str, size: str = "1024x1024") -> str:
93
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
94
+ async def seedream_generate_image_tool(prompt: str, size: str = "1024x1024") -> dict:
81
95
  """
82
96
  Asynchronously generate an image using Seedream AI model.
83
97
 
@@ -86,15 +100,16 @@ async def seedream_generate_image_tool(prompt: str, size: str = "1024x1024") ->
86
100
  size: Size of the image (e.g., "1024x1024")
87
101
 
88
102
  Returns:
89
- JSON string with status, data, and message
103
+ Dictionary with status, data, and message
90
104
  """
91
105
  return await async_seedream_generate_image_tool(prompt, size)
92
106
 
93
107
 
94
108
  @mcp.tool()
109
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
95
110
  async def seedance_generate_video_tool(prompt: str, first_frame_image: str,
96
111
  last_frame_image: str = None, duration: int = 5,
97
- resolution: str = "720p") -> str:
112
+ resolution: str = "720p") -> dict:
98
113
  """
99
114
  Asynchronously generate a video using Seedance AI model with first/last frame images.
100
115
 
@@ -106,14 +121,15 @@ async def seedance_generate_video_tool(prompt: str, first_frame_image: str,
106
121
  resolution: Video resolution (480p, 720p)
107
122
 
108
123
  Returns:
109
- JSON string with status, data, and message
124
+ Dictionary with status, data, and message
110
125
  """
111
126
  return await async_seedance_generate_video_tool(prompt, first_frame_image, last_frame_image, duration, resolution)
112
127
 
113
128
 
114
129
  @mcp.tool()
130
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
115
131
  async def seededit_tool(image_url: str, prompt: str, seed: int = -1,
116
- scale: float = 0.5, charactor_keep: bool = False) -> str:
132
+ scale: float = 0.5, charactor_keep: bool = False) -> dict:
117
133
  """
118
134
  Asynchronously edit an image using Seededit model.
119
135
 
@@ -125,13 +141,14 @@ async def seededit_tool(image_url: str, prompt: str, seed: int = -1,
125
141
  charactor_keep: whether to keep the main character in this image, if you wanna change the main character, please keep False
126
142
 
127
143
  Returns:
128
- JSON string with status, data, and message
144
+ Dictionary with status, data, and message
129
145
  """
130
146
  return await async_seededit_tool(image_url, prompt, seed, scale, charactor_keep)
131
147
 
132
148
 
133
149
  @mcp.tool()
134
- async def vlm_vision_task_tool(messages: List) -> str:
150
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
151
+ async def vlm_vision_task_tool(messages: List) -> dict:
135
152
  """
136
153
  Asynchronously perform vision-language tasks using VLM model.
137
154
 
@@ -139,13 +156,14 @@ async def vlm_vision_task_tool(messages: List) -> str:
139
156
  messages: OpenAI-compatible messages format
140
157
 
141
158
  Returns:
142
- JSON string with status, data, and message
159
+ Dictionary with status, data, and message
143
160
  """
144
161
  return await async_vlm_vision_task_tool(messages)
145
162
 
146
163
 
147
164
  @mcp.tool()
148
- async def image_selector_tool(image_paths: List[str], prompt: str) -> str:
165
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
166
+ async def image_selector_tool(image_paths: List[str], prompt: str) -> dict:
149
167
  """
150
168
  Asynchronously select the best image from multiple options using VLM model.
151
169
 
@@ -154,13 +172,14 @@ async def image_selector_tool(image_paths: List[str], prompt: str) -> str:
154
172
  prompt: Selection criteria prompt
155
173
 
156
174
  Returns:
157
- JSON string with status, data, and message
175
+ Dictionary with status, data, and message
158
176
  """
159
177
  return await async_image_selector_tool(image_paths, prompt)
160
178
 
161
179
 
162
180
  @mcp.tool()
163
- async def video_selector_tool(video_paths: List[str], prompt: str) -> str:
181
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
182
+ async def video_selector_tool(video_paths: List[str], prompt: str) -> dict:
164
183
  """
165
184
  Asynchronously select the best video from multiple options using VLM model.
166
185
 
@@ -169,14 +188,15 @@ async def video_selector_tool(video_paths: List[str], prompt: str) -> str:
169
188
  prompt: Selection criteria prompt
170
189
 
171
190
  Returns:
172
- JSON string with status, data, and message
191
+ Dictionary with status, data, and message
173
192
  """
174
193
  return await async_video_selector_tool(video_paths, prompt)
175
194
 
176
195
 
177
196
  @mcp.tool()
197
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2), retry_if_result=_is_result_error)
178
198
  async def tos_save_content_tool(content: str, file_extension: str = "txt",
179
- object_key: Optional[str] = None) -> str:
199
+ object_key: Optional[str] = None) -> dict:
180
200
  """
181
201
  Asynchronously save content to TOS and return URL.
182
202
 
@@ -186,7 +206,7 @@ async def tos_save_content_tool(content: str, file_extension: str = "txt",
186
206
  object_key: Optional key to use for the object in TOS
187
207
 
188
208
  Returns:
189
- JSON string with status, data, and message
209
+ Dictionary with status, data, and message
190
210
  """
191
211
  return await async_tos_save_content_tool(content, file_extension, object_key)
192
212
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: media-agent-mcp
3
- Version: 0.3.9
3
+ Version: 0.3.10
4
4
  Summary: A Model Context Protocol server for media processing with AI tools
5
5
  Author-email: Media Agent Team <team@mediaagent.com>
6
6
  Keywords: mcp,ai,media,video,image,processing
@@ -22,6 +22,7 @@ Requires-Dist: numpy>=1.24.0
22
22
  Requires-Dist: python-dotenv>=1.0.0
23
23
  Requires-Dist: volcengine-python-sdk>=1.0.0
24
24
  Requires-Dist: volcengine>=1.0.194
25
+ Requires-Dist: tenacity>=8.2.3
25
26
 
26
27
  # Media Agent MCP
27
28
 
@@ -1,5 +1,5 @@
1
1
  media_agent_mcp/__init__.py,sha256=4kV5u8kHrsdjpMHDNUhc8h4U6AwOyw1mNptFPd2snrQ,365
2
- media_agent_mcp/async_server.py,sha256=QYOcX0X3vFJ4elOwb1FzFItHC9YVpjA9DCg9CBanSiw,9238
2
+ media_agent_mcp/async_server.py,sha256=vpOMvN804eWz-FKf00Y_H3pE5FTl2C52SeXvFtfDJ8U,10495
3
3
  media_agent_mcp/async_wrapper.py,sha256=bHi0cCKxv6R9oHcNcNq8tV0AyKrTDV47s8BuWetqlIg,8992
4
4
  media_agent_mcp/server.py,sha256=-mTeNcJXIlgByCG2HhaqV6zSbhjrQIEv_ssLN47KAzM,13759
5
5
  media_agent_mcp/ai_models/__init__.py,sha256=WN8JDSJbj2-sNwaQg3MDwmm9mvJTC1mqpWliac3sHoc,427
@@ -14,8 +14,8 @@ media_agent_mcp/storage/__init__.py,sha256=eio7ZiSeLjCxICSZwZisiR7wKJfXlT2PV7aDE
14
14
  media_agent_mcp/storage/tos_client.py,sha256=9c3GPmQe2stvxgZzsWYjVqKzVyvluZqYneCXYj-FQ3M,3174
15
15
  media_agent_mcp/video/__init__.py,sha256=4ILnqYaUaYKI4GWOSg2SNZqt10UM1Y-8Q2SVvjoijqY,277
16
16
  media_agent_mcp/video/processor.py,sha256=5ABPyj1IoD2xyIiB8dkEx4ZssPTXKHtuoFjy-dmnFks,11866
17
- media_agent_mcp-0.3.9.dist-info/METADATA,sha256=HgLx9BJINu6TANDbAZT4qX4adNFegiJDR6BYqm9OwSM,10975
18
- media_agent_mcp-0.3.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- media_agent_mcp-0.3.9.dist-info/entry_points.txt,sha256=qhOUwR-ORVf9GO7emhhl7Lgd6MISgqbZr8bEuSH_VdA,70
20
- media_agent_mcp-0.3.9.dist-info/top_level.txt,sha256=WEa0YfchpTxZgiKn8gdxYgs-dir5HepJaTOrxAGx9nY,16
21
- media_agent_mcp-0.3.9.dist-info/RECORD,,
17
+ media_agent_mcp-0.3.10.dist-info/METADATA,sha256=F0VfYB3vYpzoj0vk9537QWNBFIsCjfzpGUrvd15QdA8,11007
18
+ media_agent_mcp-0.3.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ media_agent_mcp-0.3.10.dist-info/entry_points.txt,sha256=qhOUwR-ORVf9GO7emhhl7Lgd6MISgqbZr8bEuSH_VdA,70
20
+ media_agent_mcp-0.3.10.dist-info/top_level.txt,sha256=WEa0YfchpTxZgiKn8gdxYgs-dir5HepJaTOrxAGx9nY,16
21
+ media_agent_mcp-0.3.10.dist-info/RECORD,,