freebeat-mcp 0.1.4 → 0.2.0

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 (139) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +58 -117
  3. package/dist/capabilities/agents/register.d.ts +4 -0
  4. package/dist/capabilities/agents/register.js +7 -0
  5. package/dist/capabilities/agents/register.js.map +1 -0
  6. package/dist/capabilities/{mv/tools/generate-music-video.d.ts → agents/tools/create-agent-video.d.ts} +1 -1
  7. package/dist/capabilities/agents/tools/create-agent-video.js +83 -0
  8. package/dist/capabilities/agents/tools/create-agent-video.js.map +1 -0
  9. package/dist/capabilities/assets/register.d.ts +2 -1
  10. package/dist/capabilities/assets/register.js +8 -3
  11. package/dist/capabilities/assets/register.js.map +1 -1
  12. package/dist/capabilities/assets/tools/upload-audio.d.ts +1 -1
  13. package/dist/capabilities/assets/tools/upload-audio.js +48 -15
  14. package/dist/capabilities/assets/tools/upload-audio.js.map +1 -1
  15. package/dist/capabilities/assets/tools/upload-image.d.ts +1 -1
  16. package/dist/capabilities/assets/tools/upload-image.js +56 -9
  17. package/dist/capabilities/assets/tools/upload-image.js.map +1 -1
  18. package/dist/capabilities/assets/tools/upload-video.d.ts +3 -0
  19. package/dist/capabilities/assets/tools/upload-video.js +79 -0
  20. package/dist/capabilities/assets/tools/upload-video.js.map +1 -0
  21. package/dist/capabilities/effects/register.d.ts +2 -1
  22. package/dist/capabilities/effects/register.js +6 -3
  23. package/dist/capabilities/effects/register.js.map +1 -1
  24. package/dist/capabilities/effects/tools/generate-effect.js +2 -0
  25. package/dist/capabilities/effects/tools/generate-effect.js.map +1 -1
  26. package/dist/capabilities/effects/tools/list-effects.js +2 -0
  27. package/dist/capabilities/effects/tools/list-effects.js.map +1 -1
  28. package/dist/capabilities/media/register.d.ts +2 -1
  29. package/dist/capabilities/media/register.js +13 -6
  30. package/dist/capabilities/media/register.js.map +1 -1
  31. package/dist/capabilities/media/tools/edit-image.js +14 -43
  32. package/dist/capabilities/media/tools/edit-image.js.map +1 -1
  33. package/dist/capabilities/media/tools/generate-image.d.ts +9 -0
  34. package/dist/capabilities/media/tools/generate-image.js +24 -39
  35. package/dist/capabilities/media/tools/generate-image.js.map +1 -1
  36. package/dist/capabilities/media/tools/generate-text.d.ts +3 -0
  37. package/dist/capabilities/media/tools/generate-text.js +37 -0
  38. package/dist/capabilities/media/tools/generate-text.js.map +1 -0
  39. package/dist/capabilities/media/tools/generate-video.d.ts +1 -1
  40. package/dist/capabilities/media/tools/generate-video.js +31 -80
  41. package/dist/capabilities/media/tools/generate-video.js.map +1 -1
  42. package/dist/capabilities/media/tools/get-model-help.d.ts +2 -1
  43. package/dist/capabilities/media/tools/get-model-help.js +35 -7
  44. package/dist/capabilities/media/tools/get-model-help.js.map +1 -1
  45. package/dist/capabilities/media/tools/list-models.d.ts +2 -1
  46. package/dist/capabilities/media/tools/list-models.js +14 -9
  47. package/dist/capabilities/media/tools/list-models.js.map +1 -1
  48. package/dist/capabilities/media/tools/shared.d.ts +16 -4
  49. package/dist/capabilities/media/tools/shared.js +35 -28
  50. package/dist/capabilities/media/tools/shared.js.map +1 -1
  51. package/dist/capabilities/music/register.d.ts +4 -0
  52. package/dist/capabilities/music/register.js +10 -0
  53. package/dist/capabilities/music/register.js.map +1 -0
  54. package/dist/capabilities/music/tools/generate-music.d.ts +3 -0
  55. package/dist/capabilities/music/tools/generate-music.js +70 -0
  56. package/dist/capabilities/music/tools/generate-music.js.map +1 -0
  57. package/dist/capabilities/music/tools/list-music-models.d.ts +3 -0
  58. package/dist/capabilities/music/tools/list-music-models.js +33 -0
  59. package/dist/capabilities/music/tools/list-music-models.js.map +1 -0
  60. package/dist/capabilities/performance/register.d.ts +4 -0
  61. package/dist/capabilities/performance/register.js +10 -0
  62. package/dist/capabilities/performance/register.js.map +1 -0
  63. package/dist/capabilities/performance/tools/generate-lip-sync-video.d.ts +3 -0
  64. package/dist/capabilities/performance/tools/generate-lip-sync-video.js +90 -0
  65. package/dist/capabilities/performance/tools/generate-lip-sync-video.js.map +1 -0
  66. package/dist/capabilities/performance/tools/generate-singing-video.d.ts +3 -0
  67. package/dist/capabilities/performance/tools/generate-singing-video.js +97 -0
  68. package/dist/capabilities/performance/tools/generate-singing-video.js.map +1 -0
  69. package/dist/capabilities/tasks/register.d.ts +2 -1
  70. package/dist/capabilities/tasks/register.js +4 -1
  71. package/dist/capabilities/tasks/register.js.map +1 -1
  72. package/dist/capabilities/tasks/task-type.d.ts +1 -1
  73. package/dist/capabilities/tasks/task-type.js +1 -1
  74. package/dist/capabilities/tasks/task-type.js.map +1 -1
  75. package/dist/capabilities/tasks/tools/get-task-result.js +35 -19
  76. package/dist/capabilities/tasks/tools/get-task-result.js.map +1 -1
  77. package/dist/capabilities/tasks/tools/get-task-status.js +9 -2
  78. package/dist/capabilities/tasks/tools/get-task-status.js.map +1 -1
  79. package/dist/core/agent-products.d.ts +39 -0
  80. package/dist/core/agent-products.js +38 -0
  81. package/dist/core/agent-products.js.map +1 -0
  82. package/dist/core/config.d.ts +5 -1
  83. package/dist/core/config.js +3 -0
  84. package/dist/core/config.js.map +1 -1
  85. package/dist/core/creative-task-id.d.ts +7 -0
  86. package/dist/core/creative-task-id.js +33 -0
  87. package/dist/core/creative-task-id.js.map +1 -0
  88. package/dist/core/music-source-url.d.ts +1 -0
  89. package/dist/core/music-source-url.js +45 -0
  90. package/dist/core/music-source-url.js.map +1 -0
  91. package/dist/core/openai-file.d.ts +17 -0
  92. package/dist/core/openai-file.js +10 -0
  93. package/dist/core/openai-file.js.map +1 -0
  94. package/dist/core/scopes.d.ts +8 -0
  95. package/dist/core/scopes.js +9 -0
  96. package/dist/core/scopes.js.map +1 -0
  97. package/dist/core/task-types.d.ts +5 -1
  98. package/dist/core/task-types.js +5 -5
  99. package/dist/core/task-types.js.map +1 -1
  100. package/dist/core/tool-annotations.d.ts +12 -0
  101. package/dist/core/tool-annotations.js +13 -0
  102. package/dist/core/tool-annotations.js.map +1 -0
  103. package/dist/hosted.d.ts +14 -0
  104. package/dist/hosted.js +21 -0
  105. package/dist/hosted.js.map +1 -0
  106. package/dist/index.js +4 -20
  107. package/dist/index.js.map +1 -1
  108. package/dist/server.d.ts +6 -0
  109. package/dist/server.js +25 -0
  110. package/dist/server.js.map +1 -0
  111. package/dist/services/freebeat-api.d.ts +718 -24
  112. package/dist/services/freebeat-api.js +590 -39
  113. package/dist/services/freebeat-api.js.map +1 -1
  114. package/dist/services/remote-media.d.ts +8 -0
  115. package/dist/services/remote-media.js +191 -0
  116. package/dist/services/remote-media.js.map +1 -0
  117. package/dist/services/upload-service.js +13 -2
  118. package/dist/services/upload-service.js.map +1 -1
  119. package/dist/utils/file.d.ts +2 -1
  120. package/dist/utils/file.js +11 -54
  121. package/dist/utils/file.js.map +1 -1
  122. package/package.json +15 -4
  123. package/dist/capabilities/mv/register.d.ts +0 -3
  124. package/dist/capabilities/mv/register.js +0 -5
  125. package/dist/capabilities/mv/register.js.map +0 -1
  126. package/dist/capabilities/mv/task-type.d.ts +0 -1
  127. package/dist/capabilities/mv/task-type.js +0 -2
  128. package/dist/capabilities/mv/task-type.js.map +0 -1
  129. package/dist/capabilities/mv/tools/generate-music-video.js +0 -116
  130. package/dist/capabilities/mv/tools/generate-music-video.js.map +0 -1
  131. package/dist/core/model-catalog.d.ts +0 -82
  132. package/dist/core/model-catalog.js +0 -861
  133. package/dist/core/model-catalog.js.map +0 -1
  134. package/dist/core/tasks.d.ts +0 -1
  135. package/dist/core/tasks.js +0 -2
  136. package/dist/core/tasks.js.map +0 -1
  137. package/dist/core/tool-schemas.d.ts +0 -7
  138. package/dist/core/tool-schemas.js +0 -64
  139. package/dist/core/tool-schemas.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,14 @@ The format is based on Keep a Changelog, and this project follows Semantic Versi
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.0] - 2026-10-23
10
+
11
+ ### Added
12
+ - Export `handleHostedMcpRequest` and `FREEBEAT_SCOPES` from `freebeat-mcp/hosted` so the Freebeat website can serve MCP requests with the resolved user credentials and token scopes.
13
+
14
+ ### Removed
15
+ - Standalone hosted HTTP server, OAuth grant resolver, Redis configuration, and Docker/GitOps deployment. The stdio CLI remains unchanged.
16
+
9
17
  ## [0.1.4] - 2026-07-10
10
18
 
11
19
  ### Added
package/README.md CHANGED
@@ -4,7 +4,7 @@ MCP server for Freebeat creative workflows.
4
4
 
5
5
  Use it from MCP clients such as Claude Desktop and Cursor through `npx freebeat-mcp`.
6
6
 
7
- It currently supports audio and image upload, effect template discovery, AI effect generation, AI music video generation, Open RPC image/video generation, model discovery, and async task polling.
7
+ It currently supports audio, image, and video upload, Freebeat's music-video, dance, and lyric-video agents, effect templates, live model discovery, image/video/text generation with any model Freebeat publishes, and async task polling.
8
8
 
9
9
  ## Features
10
10
 
@@ -12,10 +12,11 @@ It currently supports audio and image upload, effect template discovery, AI effe
12
12
  - Image upload for workflows that accept reference images
13
13
  - Supported effect template listing
14
14
  - AI effect generation
15
- - AI music video generation
16
- - Supported image and video model discovery
15
+ - Music-video, dance, and lyric-video agents in Auto mode
16
+ - Live image, image edit, video, and text model discovery with pricing
17
17
  - AI image generation and single-image editing
18
- - AI text-to-video generation
18
+ - AI video generation (text, image, transition, reference)
19
+ - Text generation with any model on the user's Freebeat gateway
19
20
  - Generic task polling and result retrieval
20
21
 
21
22
  ## Installation
@@ -70,6 +71,13 @@ npx -y freebeat-mcp
70
71
  | Variable | Required | Description |
71
72
  | --- | --- | --- |
72
73
  | `FREEBEAT_API_KEY` | Yes | API authentication key |
74
+ | `FREEBEAT_MV_AGENT_URL` | No | Music-video agent host, default `https://da-api.freebeat.ai` |
75
+ | `FREEBEAT_DANCE_AGENT_URL` | No | Dance agent host, default `https://fb-dance-agent-api.freebeat.ai` |
76
+ | `FREEBEAT_LYRIC_AGENT_URL` | No | Lyric-video agent host, default `https://lyric-video-agent-api.freebeat.ai` |
77
+ | `FREEBEAT_WEB_HOST` | No | Site used for agent session links, default `https://freebeat.ai` |
78
+
79
+ The hosted MCP endpoint is served by freebeat.ai.
80
+ The website mounts `freebeat-mcp/hosted`.
73
81
 
74
82
  This package depends on Freebeat online services. Available source platforms, effect templates, and generation capabilities may change with backend updates.
75
83
 
@@ -89,18 +97,36 @@ Currently supported platforms:
89
97
  - Stable Audio
90
98
  - Riffusion
91
99
 
92
- Provide exactly one of `file_path` or `url`.
100
+ Provide exactly one of:
101
+
102
+ - `file`, a ChatGPT attachment object
103
+ - `file_path`, for local stdio installations only
104
+ - `url`, for a supported music platform
93
105
 
94
- Returns a `music_id` that can be used by either `generate_music_video` or `generate_effect`.
106
+ Returns a `music_id` that can be used by either `create_agent_video` or `generate_effect`.
95
107
 
96
108
  ### `upload_image`
97
109
 
98
110
  Upload one or two images and receive `image_urls`.
99
111
 
100
- For MV generation, pass the returned `image_urls` into `generate_music_video.reference_image_urls`.
112
+ Provide exactly one of `files` (ChatGPT attachments), `file_paths` (local stdio
113
+ only), or `urls` (guarded public HTTPS downloads).
114
+
115
+ For agent videos, pass the returned `image_urls` into `create_agent_video.image_urls`.
101
116
 
102
117
  For effect generation, the default recommendation is still `list_effects.image_url`, but you can also upload one image and pass `image_urls[0]` into `generate_effect.reference_image_urls`.
103
118
 
119
+ ### `upload_video`
120
+
121
+ Upload one MP4, MOV, or WebM clip and receive a `video_url` for
122
+ `generate_lip_sync_video`. Provide exactly one of `file` (a ChatGPT attachment),
123
+ `file_path` (local stdio only), or `url` (a guarded public HTTPS download).
124
+
125
+ Hosted HTTP mode never reads caller-provided local file paths. Attachment and
126
+ URL downloads require HTTPS, reject private or reserved network addresses and
127
+ redirects, enforce media content types, and stream to size-limited temporary
128
+ files that are removed after upload.
129
+
104
130
  ### `list_effects`
105
131
 
106
132
  List supported effects with:
@@ -148,148 +174,63 @@ Returns a task envelope with:
148
174
  - `task_type` currently `effect_generation`
149
175
  - `status`
150
176
 
151
- ### `generate_music_video`
177
+ ### `create_agent_video`
152
178
 
153
- Start an async MV generation task from a `music_id` returned by `upload_audio`.
154
-
155
- Recommended flow:
156
-
157
- - `upload_audio`
158
- - optional `upload_image`
159
- - `generate_music_video`
160
- - `get_task_status`
161
- - `get_task_result` only after status is `completed`
179
+ Start one of Freebeat's creative agents on a song in Auto mode, the same way freebeat.ai does: `music_video`, `dance`, or `lyric_video`. The agent plans, generates, and edits on its own, usually in 15-60 minutes, and spends Freebeat credits as it works.
162
180
 
163
181
  Parameters:
164
182
 
183
+ - `product` required: `music_video`, `dance`, or `lyric_video`
165
184
  - `music_id` required, from `upload_audio`
166
- - `prompt` required, trimmed length must be `1` to `2000`
167
- - `mv_type` optional, default `abstract`
168
- - `style` optional
185
+ - `prompt` optional creative direction
186
+ - `start_ms` / `end_ms` optional song window, default the first 15 seconds; standard accounts allow 10-15 seconds, VIP accounts up to 360 seconds
169
187
  - `aspect_ratio` optional, default `16:9`
170
- - `resolution` optional, default `720`
171
- - `watermark` optional, default `false`
172
- - `start_ms` optional
173
- - `end_ms` optional
174
- - `reference_image_urls` optional
175
-
176
- Returns a task envelope with:
188
+ - `resolution` optional: `720p`/`1080p` for `music_video`, `720p` for `dance`, `768P`/`2K` for `lyric_video`
189
+ - `image_urls` optional photos from `upload_image`
190
+ - `remove_watermark` optional, default `false`
177
191
 
178
- - `task_id`
179
- - `task_type` currently `music_video_generation`
180
- - `status`
192
+ Returns `task_id`, `task_type`, `status`, and `session_url`, the freebeat.ai page for the session. `get_task_status` reports `running`, `completed`, or `action_required`; on `action_required` (for example the account ran out of credits, or the agent needs a decision) give the user `session_url` to continue on freebeat.ai.
181
193
 
182
194
  ### `list_models`
183
195
 
184
- List supported Open RPC models for either `image` or `video`.
185
-
186
- Recommended flow:
187
-
188
- - `list_models` with `type: "image"` before `generate_image` or `edit_image`
189
- - `list_models` with `type: "video"` before `generate_video`
190
- - optional `get_model_help` for model-specific examples and constraints
191
-
192
- Each model entry includes:
193
-
194
- - `model_id`
195
- - `model`, the API model key when one is available
196
- - `display_name`
197
- - `commands`
198
- - `constraints`
196
+ List the models Freebeat publishes right now. `type` is `image` (for `generate_image`), `image_edit` (for `edit_image`), `video` (for `generate_video`), or `text` (for `generate_text`). Image, image edit, and video lists come live from Freebeat's model configuration, so new models appear without a plugin update. Text models come from the user's Freebeat model gateway. Music and voice models are listed by `list_music_models`.
199
197
 
200
198
  ### `get_model_help`
201
199
 
202
- Show detailed usage guidance for one Open RPC model.
203
-
204
- Parameters:
205
-
206
- - `model` required, using either a numeric `model_id` or API model key from `list_models`
207
-
208
- Use this before video generation to confirm required `duration`, `resolution`, supported `aspect_ratio`, and whether `generate_audio` is supported.
209
- For video models, help also lists supported generation modes (`text`, `image`, `transition`, `reference`) and duration values by resolution when the local catalog has that detail.
200
+ Show what one image, image edit, or video model accepts and what it costs, read live from Freebeat. Parameters: `type` and `model_id`. The response has the model description, per-generation-type options (aspect ratios, resolutions, durations, and credits when Freebeat publishes them), and pricing rules: `keys` name the parameters that change the price and `prices` lists the allowed combinations.
210
201
 
211
202
  ### `generate_image`
212
203
 
213
- Create an async Open RPC image generation batch.
214
-
215
- Recommended flow:
216
-
217
- - `list_models` with `type: "image"`
218
- - optional `get_model_help`
219
- - `generate_image`
220
- - `get_task_status` with the returned `batch_id`
221
-
222
- Parameters:
223
-
224
- - `model` required, from `list_models`
225
- - `prompt` required, trimmed length must be `1` to `2000`
226
- - `size` optional
227
- - `resolution` optional
228
- - `quality` optional
229
- - `output_format` optional, for supported models such as `png`, `jpeg`, or `webp`
230
- - `custom_resolution` optional, only accepted for models that support custom pixel dimensions
231
- - `count` optional, default `1`
204
+ Create an async image generation batch with any model from `list_models(type=image)`.
232
205
 
233
- For GPT-Image 1.5 (`model_id` `70`) and GPT-Image 2 (`model_id` `108`), the MCP server sends `quality: "medium"` and `resolution: "1024x1024"` by default when omitted. GPT-Image 1.5 currently accepts `resolution` values `1024x1024`, `1536x1024`, and `1024x1536`; GPT-Image 2 exposes its broader list through `get_model_help`. If `resolution` is omitted but `size` is provided, that `size` is also sent as `resolution` for compatibility.
206
+ Parameters: `model_id` and `prompt` (1-2000 characters) are required; `size`, `resolution`, `quality`, `output_format`, `custom_resolution`, and `count` (default `1`) are optional and passed through to Freebeat, which validates them per model. A rejected request returns the reason in `message` and the per-item `items[].message`.
234
207
 
235
208
  ### `edit_image`
236
209
 
237
- Create an async Open RPC single-image edit batch.
210
+ Create an async single-image edit batch with any model from `list_models(type=image_edit)`. Parameters: `model_id`, `image` (an image URL, usually from `upload_image`), `prompt`, and the same optional image options as `generate_image`.
238
211
 
239
- Recommended flow:
212
+ ### `generate_video`
240
213
 
241
- - `upload_image` or provide an existing image URL
242
- - `list_models` with `type: "image"`
243
- - optional `get_model_help`
244
- - `edit_image`
245
- - `get_task_status` with the returned `batch_id`
214
+ Create an async video generation batch with any model from `list_models(type=video)`.
246
215
 
247
216
  Parameters:
248
217
 
249
- - `model` required, from `list_models`
250
- - `image` required, a single image URL
251
- - `prompt` required, trimmed length must be `1` to `2000`
252
- - `size` optional
253
- - `resolution` optional
254
- - `quality` optional
255
- - `output_format` optional
256
- - `custom_resolution` optional
257
- - `count` optional, default `1`
258
-
259
- For Qwen Image Edit (`model_id` `76`), the MCP server sends `quality: "medium"`, `resolution: "1024x1024"`, and `customResolution: 1` by default for pricing compatibility.
218
+ - `model_id` and `prompt` (1-2000 characters) required
219
+ - `generation_type` optional, default `text`; `text`, `image`, `transition`, or `reference`
220
+ - `images` image URLs from `upload_image` for non-text modes
221
+ - `duration`, `resolution`, `aspect_ratio`, `style`, `generate_audio`, `multi_clip`, `watermark` optional
260
222
 
261
- ### `generate_video`
223
+ Freebeat validates the options per model; check `get_model_help` first and read `message` if a request is rejected.
262
224
 
263
- Create an async Open RPC video generation batch.
225
+ ### `generate_text`
264
226
 
265
- Recommended flow:
266
-
267
- - `list_models` with `type: "video"`
268
- - `get_model_help`
269
- - `generate_video`
270
- - `get_task_status` with the returned `batch_id`
271
-
272
- Parameters:
273
-
274
- - `model` required, from `list_models`
275
- - `prompt` required, trimmed length must be `1` to `2000`
276
- - `generation_type` optional, default `text`; supported values are `text`, `image`, `transition`, and `reference`
277
- - `images` required for non-text modes: exactly one for `image`, exactly two for `transition`, at least one for `reference`; entries may be image URLs or local image paths
278
- - `duration` required when the selected model declares supported durations
279
- - `resolution` required when the selected model declares supported resolutions
280
- - `aspect_ratio` optional, validated when the selected model declares supported ratios
281
- - `style` optional, only accepted for models that declare styles
282
- - `generate_audio` optional, only accepted for models that support generated audio
283
- - `multi_clip` optional, only accepted for models that support multi-clip generation
284
- - `watermark` optional, default `false`; Open RPC video requests send `watermark: 0` unless set
285
-
286
- Video model constraints are validated locally before a request is sent. Local images used for video generation must be at least `300x300` and are uploaded automatically. `wan-v2.6-video` is not exposed until its downstream reference image mapping is fixed; `kling-o3-pro` currently exposes `text`, `image`, and `transition`, but not `reference`.
227
+ Ask any text model from `list_models(type=text)` and get its reply. Parameters: `model`, `messages` (`role` and `content`, oldest first), optional `max_tokens` and `temperature`. Usage is billed to the user's Freebeat credits through the user's own gateway token.
287
228
 
288
229
  ### `get_task_status`
289
230
 
290
231
  Poll a Freebeat async task or Open RPC batch until it reaches a terminal status. Current MCP endpoints return lowercase status values such as `pending`, `completed`, and `failed`; older backends may still return uppercase variants.
291
232
 
292
- For legacy MV/effect tasks, continue polling while the status is still in progress. Only call `get_task_result` after the status is `completed`.
233
+ For agent videos, effects, music, singing, and lip-sync tasks, continue polling while the status is still in progress. Agent videos may also report `action_required` with a `session_url` for the user. Only call `get_task_result` after the status is `completed`.
293
234
 
294
235
  For Open RPC image/video batches, pass the returned `batch_id` as `task_id`. You can also pass `serial_no` to query a single batch item. Completed batch items include result URLs directly in `get_task_status`, so `get_task_result` is not used for Open RPC batches.
295
236
 
@@ -311,7 +252,7 @@ If the task is not completed yet, this tool returns error code `TASK_NOT_COMPLET
311
252
 
312
253
  If the task has failed, this tool surfaces the backend failure as an error.
313
254
 
314
- For current supported completed MV tasks, `result` is an object containing:
255
+ For completed agent videos, `result` is an object containing:
315
256
 
316
257
  - `video_url`
317
258
  - `cover_url`
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { FreebeatApiClient } from "../../services/freebeat-api.js";
3
+ import { ToolAccess } from "../../core/scopes.js";
4
+ export declare function registerAgentTools(server: McpServer, client: FreebeatApiClient, access?: ToolAccess): void;
@@ -0,0 +1,7 @@
1
+ import { ALL_TOOL_ACCESS } from "../../core/scopes.js";
2
+ import { registerCreateAgentVideoTool } from "./tools/create-agent-video.js";
3
+ export function registerAgentTools(server, client, access = ALL_TOOL_ACCESS) {
4
+ if (access.generate)
5
+ registerCreateAgentVideoTool(server, client);
6
+ }
7
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/capabilities/agents/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAc,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAE7E,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,MAAyB,EACzB,SAAqB,eAAe;IAEpC,IAAI,MAAM,CAAC,QAAQ;QAAE,4BAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { FreebeatApiClient } from "../../../services/freebeat-api.js";
3
- export declare function registerGenerateMusicVideoTool(server: McpServer, client: Pick<FreebeatApiClient, "generateMusicVideo">): void;
3
+ export declare function registerCreateAgentVideoTool(server: McpServer, client: Pick<FreebeatApiClient, "createAgentVideo">): void;
@@ -0,0 +1,83 @@
1
+ import { z } from "zod";
2
+ import { AGENT_PRODUCT_NAMES } from "../../../core/agent-products.js";
3
+ import { formatToolError, jsonContent } from "../../../core/response.js";
4
+ import { CREATE_TOOL_ANNOTATIONS } from "../../../core/tool-annotations.js";
5
+ export function registerCreateAgentVideoTool(server, client) {
6
+ server.registerTool("create_agent_video", {
7
+ description: "Start one of Freebeat's creative agents on a song in Auto mode: music_video (a full story music video), dance (dancers performing to the song; photos become the dancers), or lyric_video (an animated lyric video). Upload the song with upload_audio first and optional photos with upload_image. The agent plans, generates, and edits on its own and usually takes 15-60 minutes; it spends Freebeat credits as it works. Poll get_task_status (statuses: running, completed, action_required) and fetch get_task_result when completed. When the status is action_required, give the user session_url to review or continue on freebeat.ai.",
8
+ annotations: { title: "Create agent video", ...CREATE_TOOL_ANNOTATIONS },
9
+ inputSchema: {
10
+ product: z
11
+ .enum(AGENT_PRODUCT_NAMES)
12
+ .describe("Which Freebeat agent makes the video: music_video, dance, or lyric_video."),
13
+ music_id: z
14
+ .number()
15
+ .int()
16
+ .positive()
17
+ .describe("An analyzed music_id from upload_audio."),
18
+ prompt: z
19
+ .string()
20
+ .trim()
21
+ .max(2000)
22
+ .optional()
23
+ .describe("The user's creative direction in their own words. Leave empty to let the agent decide."),
24
+ start_ms: z
25
+ .number()
26
+ .int()
27
+ .min(0)
28
+ .optional()
29
+ .describe("Start of the song window in milliseconds. Defaults to 0."),
30
+ end_ms: z
31
+ .number()
32
+ .int()
33
+ .positive()
34
+ .optional()
35
+ .describe("End of the song window in milliseconds. Defaults to start_ms + 15000. Standard accounts allow 10-15 seconds; VIP accounts up to 360 seconds; lyric_video needs at least 4 seconds."),
36
+ aspect_ratio: z
37
+ .enum(["16:9", "9:16", "1:1", "4:3", "3:4"])
38
+ .default("16:9")
39
+ .describe("Output aspect ratio."),
40
+ resolution: z
41
+ .enum(["720p", "1080p", "768P", "2K"])
42
+ .optional()
43
+ .describe("music_video: 720p (default) or 1080p. dance: 720p only. lyric_video: 768P (default) or 2K."),
44
+ image_urls: z
45
+ .array(z.string().url())
46
+ .max(5)
47
+ .optional()
48
+ .describe("Optional photo URLs from upload_image: people or characters to feature, or dancers for dance."),
49
+ remove_watermark: z
50
+ .boolean()
51
+ .default(false)
52
+ .describe("Remove the Freebeat watermark if the account allows it."),
53
+ },
54
+ outputSchema: {
55
+ success: z.literal(true),
56
+ task_id: z
57
+ .string()
58
+ .describe("The scoped task ID for get_task_status and get_task_result."),
59
+ task_type: z.string().describe("The task category."),
60
+ status: z.string().describe("The initial task status, typically pending."),
61
+ session_url: z
62
+ .string()
63
+ .describe("The freebeat.ai page where the user can watch, review, or continue this session."),
64
+ message: z.string().describe("What to do next."),
65
+ },
66
+ }, async (params) => {
67
+ try {
68
+ const result = await client.createAgentVideo(params);
69
+ return jsonContent({
70
+ success: true,
71
+ task_id: result.task_id,
72
+ task_type: result.task_type,
73
+ status: result.status,
74
+ session_url: result.session_url,
75
+ message: "The Freebeat agent started. Poll get_task_status every few minutes; full videos usually take 15-60 minutes. Share session_url if the user wants to watch it work.",
76
+ });
77
+ }
78
+ catch (error) {
79
+ return formatToolError(error);
80
+ }
81
+ });
82
+ }
83
+ //# sourceMappingURL=create-agent-video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-agent-video.js","sourceRoot":"","sources":["../../../../src/capabilities/agents/tools/create-agent-video.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { FreebeatApiClient } from "../../services/freebeat-api.js";
3
- export declare function registerAssetTools(server: McpServer, client: FreebeatApiClient): void;
3
+ import { ToolAccess } from "../../core/scopes.js";
4
+ export declare function registerAssetTools(server: McpServer, client: FreebeatApiClient, access?: ToolAccess, allowLocalFiles?: boolean): void;
@@ -1,7 +1,12 @@
1
+ import { ALL_TOOL_ACCESS } from "../../core/scopes.js";
1
2
  import { registerUploadAudioTool } from "./tools/upload-audio.js";
2
3
  import { registerUploadImageTool } from "./tools/upload-image.js";
3
- export function registerAssetTools(server, client) {
4
- registerUploadAudioTool(server, client);
5
- registerUploadImageTool(server, client);
4
+ import { registerUploadVideoTool } from "./tools/upload-video.js";
5
+ export function registerAssetTools(server, client, access = ALL_TOOL_ACCESS, allowLocalFiles = true) {
6
+ if (!access.generate)
7
+ return;
8
+ registerUploadAudioTool(server, client, allowLocalFiles);
9
+ registerUploadImageTool(server, client, allowLocalFiles);
10
+ registerUploadVideoTool(server, client, allowLocalFiles);
6
11
  }
7
12
  //# sourceMappingURL=register.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/capabilities/assets/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,MAAyB;IAEzB,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/capabilities/assets/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAc,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,UAAU,kBAAkB,CAChC,MAAiB,EACjB,MAAyB,EACzB,SAAqB,eAAe,EACpC,eAAe,GAAG,IAAI;IAEtB,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO;IAC7B,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IACzD,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IACzD,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { FreebeatApiClient } from "../../../services/freebeat-api.js";
3
- export declare function registerUploadAudioTool(server: McpServer, client: Pick<FreebeatApiClient, "createUploadUrl" | "uploadToPreSignedUrl" | "saveMusicSource">): void;
3
+ export declare function registerUploadAudioTool(server: McpServer, client: Pick<FreebeatApiClient, "createUploadUrl" | "uploadToPreSignedUrl" | "saveMusicSource">, allowLocalFiles?: boolean): void;
@@ -1,45 +1,76 @@
1
1
  import { z } from "zod";
2
2
  import { AppError } from "../../../core/errors.js";
3
+ import { validateSupportedMusicSourceUrl } from "../../../core/music-source-url.js";
4
+ import { openAiFileSchema } from "../../../core/openai-file.js";
3
5
  import { formatToolError, jsonContent } from "../../../core/response.js";
6
+ import { CREATE_TOOL_ANNOTATIONS } from "../../../core/tool-annotations.js";
7
+ import { downloadRemoteMedia, removeRemoteMedia, } from "../../../services/remote-media.js";
4
8
  import { UploadService } from "../../../services/upload-service.js";
5
9
  import { detectAudioMimeType, validateAudioFile, } from "../../../utils/file.js";
6
- export function registerUploadAudioTool(server, client) {
10
+ const REMOTE_AUDIO_TYPES = {
11
+ "audio/mpeg": "mp3",
12
+ "audio/wav": "wav",
13
+ "audio/x-wav": "wav",
14
+ "audio/ogg": "ogg",
15
+ "audio/flac": "flac",
16
+ "audio/x-flac": "flac",
17
+ "audio/aac": "aac",
18
+ "audio/x-aac": "aac",
19
+ };
20
+ const MAX_AUDIO_BYTES = 50 * 1024 * 1024;
21
+ export function registerUploadAudioTool(server, client, allowLocalFiles = true) {
7
22
  const uploadService = new UploadService(client);
8
23
  server.registerTool("upload_audio", {
9
- description: "Upload a local audio file or import from a supported music URL. Supported platforms: SoundCloud, YouTube, Suno, Udio, TikTok, Stable Audio, and Riffusion. Provide exactly one of file_path or url. Returns a music_id for generate_music_video or generate_effect.",
24
+ description: "Upload an attached audio file, upload a local audio file, or import from a supported music URL. Supported platforms: SoundCloud, YouTube, Suno, Udio, TikTok, Stable Audio, and Riffusion. Provide exactly one of file, file_path, or url. Returns a music_id for Freebeat video workflows.",
25
+ annotations: { title: "Upload audio", ...CREATE_TOOL_ANNOTATIONS },
26
+ _meta: { "openai/fileParams": ["file"] },
10
27
  outputSchema: {
11
28
  success: z
12
29
  .literal(true)
13
30
  .describe("Whether the audio upload or import completed successfully."),
14
31
  music_id: z
15
32
  .number()
16
- .describe("The audio asset ID to pass into generate_music_video or generate_effect."),
33
+ .describe("The audio asset ID to pass into create_agent_video or generate_effect."),
17
34
  message: z
18
35
  .string()
19
36
  .describe("A human-readable summary of the audio source preparation result."),
20
37
  },
21
38
  inputSchema: {
39
+ file: openAiFileSchema
40
+ .optional()
41
+ .describe("Audio attachment supplied by ChatGPT."),
22
42
  file_path: z
23
43
  .string()
24
44
  .optional()
25
- .describe("Local audio file path. Set this or url, not both."),
45
+ .describe("Local audio file path for stdio installations. Not available on the hosted server."),
26
46
  url: z
27
47
  .string()
48
+ .url()
28
49
  .optional()
29
50
  .describe("Supported music source URL from SoundCloud, YouTube, Suno, Udio, TikTok, Stable Audio, or Riffusion. Set this or file_path, not both."),
30
51
  },
31
- }, async ({ file_path, url }) => {
52
+ }, async ({ file, file_path, url }) => {
53
+ let remotePath;
32
54
  try {
33
- if ((!file_path && !url) || (file_path && url)) {
34
- return formatToolError(new AppError("Exactly one of file_path or url must be provided", "INVALID_PARAMS"));
55
+ const inputCount = Number(Boolean(file)) + Number(Boolean(file_path)) + Number(Boolean(url));
56
+ if (inputCount !== 1) {
57
+ return formatToolError(new AppError("Exactly one of file, file_path, or url must be provided", "INVALID_PARAMS"));
58
+ }
59
+ if (file_path && !allowLocalFiles) {
60
+ return formatToolError(new AppError("This hosted server cannot read local file paths. Provide url instead.", "INVALID_PARAMS"));
35
61
  }
36
62
  let musicId;
37
- if (file_path) {
38
- validateAudioFile(file_path);
63
+ if (file || file_path) {
64
+ const localPath = file_path
65
+ ?? (remotePath = await downloadRemoteMedia(file.download_url, {
66
+ acceptedTypes: REMOTE_AUDIO_TYPES,
67
+ maxBytes: MAX_AUDIO_BYTES,
68
+ }));
69
+ validateAudioFile(localPath);
39
70
  const finalStaticUrl = await uploadService.uploadLocalFile({
40
- filePath: file_path,
71
+ filePath: localPath,
41
72
  keyPrefix: "dance/music",
42
- contentType: detectAudioMimeType(file_path),
73
+ contentType: detectAudioMimeType(localPath),
43
74
  });
44
75
  try {
45
76
  musicId = await client.saveMusicSource(finalStaticUrl);
@@ -50,21 +81,23 @@ export function registerUploadAudioTool(server, client) {
50
81
  }
51
82
  }
52
83
  else {
53
- if (!url) {
54
- return formatToolError(new AppError("Exactly one of file_path or url must be provided", "INVALID_PARAMS"));
55
- }
84
+ validateSupportedMusicSourceUrl(url);
56
85
  musicId = await client.saveMusicSource(url);
57
86
  }
58
87
  return jsonContent({
59
88
  success: true,
60
89
  music_id: musicId,
61
90
  message: `Audio source ready. Use music_id=${musicId} with ` +
62
- "generate_music_video or generate_effect.",
91
+ "create_agent_video or generate_effect.",
63
92
  });
64
93
  }
65
94
  catch (error) {
66
95
  return formatToolError(error);
67
96
  }
97
+ finally {
98
+ if (remotePath)
99
+ await removeRemoteMedia(remotePath).catch(() => { });
100
+ }
68
101
  });
69
102
  }
70
103
  //# sourceMappingURL=upload-audio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-audio.js","sourceRoot":"","sources":["../../../../src/capabilities/assets/tools/upload-audio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,MAGC;IAED,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAEhD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,WAAW,EACT,qQAAqQ;QACvQ,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC;iBACP,OAAO,CAAC,IAAI,CAAC;iBACb,QAAQ,CAAC,4DAA4D,CAAC;YACzE,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,CAAC,0EAA0E,CAAC;YACvF,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,CAAC,kEAAkE,CAAC;SAChF;QACD,WAAW,EAAE;YACX,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,mDAAmD,CACpD;YACH,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,uIAAuI,CACxI;SACJ;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC/C,OAAO,eAAe,CACpB,IAAI,QAAQ,CAAC,kDAAkD,EAAE,gBAAgB,CAAC,CACnF,CAAC;YACJ,CAAC;YAED,IAAI,OAAe,CAAC;YAEpB,IAAI,SAAS,EAAE,CAAC;gBACd,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAE7B,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC;oBACzD,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,aAAa;oBACxB,WAAW,EAAE,mBAAmB,CAAC,SAAS,CAAC;iBAC5C,CAAC,CAAC;gBAEH,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;gBACzD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CACX,kBAAkB,cAAc,sDAAsD,CACvF,CAAC;oBACF,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,OAAO,eAAe,CACpB,IAAI,QAAQ,CAAC,kDAAkD,EAAE,gBAAgB,CAAC,CACnF,CAAC;gBACJ,CAAC;gBAED,OAAO,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC;YAED,OAAO,WAAW,CAAC;gBACjB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,OAAO;gBACjB,OAAO,EACL,oCAAoC,OAAO,QAAQ;oBACnD,0CAA0C;aAC7C,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"upload-audio.js","sourceRoot":"","sources":["../../../../src/capabilities/assets/tools/upload-audio.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { FreebeatApiClient } from "../../../services/freebeat-api.js";
3
- export declare function registerUploadImageTool(server: McpServer, client: Pick<FreebeatApiClient, "createUploadUrl" | "uploadToPreSignedUrl">): void;
3
+ export declare function registerUploadImageTool(server: McpServer, client: Pick<FreebeatApiClient, "createUploadUrl" | "uploadToPreSignedUrl">, allowLocalFiles?: boolean): void;