@kolbo/mcp 1.31.6 → 1.32.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.
package/README.md CHANGED
@@ -1,250 +1,251 @@
1
- # @kolbo/mcp
2
-
3
- Use [Kolbo AI](https://kolbo.ai) as native tools in Claude Code and Claude Desktop via MCP (Model Context Protocol).
4
-
5
- Generate images, videos, music, speech, sound effects, multi-scene campaigns, and conversational chat — all from natural language in your coding environment. 100+ AI models behind Smart Select routing, with reusable Visual DNA profiles for character/style consistency.
6
-
7
- **✨ Interactive widgets (v1.30+):** in claude.ai and Claude Desktop, generations render as live Kolbo cards — real-time progress with model + settings chips, an inline result gallery / video player, and one-click **Animate · Edit · Recreate · Download** actions. Library and model searches render as browsable grids with audio preview. Text-only clients (Claude Code, Cursor) keep the classic text responses.
8
-
9
- ## Set up — paste one prompt, or one config block (keyless, no API key)
10
-
11
- ### Easiest: paste this prompt to your AI
12
-
13
- Copy this and paste it to Claude, ChatGPT, Cursor, or any AI assistant — it installs Kolbo itself (picks local config or remote connector based on what it can do):
14
-
15
- ```
16
- Connect the Kolbo AI MCP server (generate images, video, music and more).
17
-
18
- - If you can run terminal commands (Claude Code, Cursor, Claude Desktop, or any local setup): run "npx -y @kolbo/mcp install" — it auto-configures Kolbo in the right place. If you can't run it, give me the command to run. Then I'll restart the app.
19
- - If you're a browser chat (claude.ai, ChatGPT): add a custom connector with URL https://api.kolbo.ai/mcp under Settings → Connectors, then Connect → log in → Allow.
20
-
21
- No API key needed — on first use a Kolbo login opens in my browser and I click Allow. When set up, confirm Kolbo is connected and offer to generate a test image of a sunset.
22
- ```
23
-
24
- ### Or set it up yourself — one command
25
-
26
- <!--
27
- AI ASSISTANT SETUP INSTRUCTIONS — if you are an AI agent reading this to set up Kolbo for a user, do exactly this:
28
- 1. If you can run a terminal command (Claude Code, Cursor, Claude Desktop): run `npx -y @kolbo/mcp install` — it writes the keyless config to the right file for every installed agent. (Don't hand-edit settings.json; the installer is deterministic.) Then tell the user to restart the app. On the first generation a Kolbo login opens in the browser — they click Allow (no API key).
29
- 2. If you're a web chat that can't run commands (claude.ai, ChatGPT): tell the user to add the connector URL https://api.kolbo.ai/mcp under Settings → Connectors instead.
30
- The plugin below is an optional slash-command upgrade.
31
- -->
32
-
33
- Run this once — it sets up the **full** Kolbo experience (the MCP tools **and** the routing skill) for every installed agent (Claude Desktop, Claude Code, Cursor), keyless:
34
-
35
- ```bash
36
- npx -y @kolbo/mcp install
37
- ```
38
-
39
- Or add the config by hand — this block is identical for every MCP client and carries **no API key** (on first use it logs you in via the browser):
40
-
41
- ```json
42
- {
43
- "mcpServers": {
44
- "kolbo": {
45
- "command": "npx",
46
- "args": ["-y", "@kolbo/mcp@latest"]
47
- }
48
- }
49
- }
50
- ```
51
-
52
- | Client | Where the config goes |
53
- |--------|----------------------|
54
- | **Claude Code** | `.claude/settings.json` (or `claude mcp add kolbo -- npx -y @kolbo/mcp@latest`) |
55
- | **Claude Desktop** | `claude_desktop_config.json` |
56
- | **Cursor** | `.cursor/mcp.json` |
57
- | **Kolbo Code** | configured automatically on `kolbo auth login` |
58
-
59
- Restart your app, then ask it to generate something. The first time, a Kolbo login opens in your browser — click **Allow** (no API key to create). _Prefer an API key? Create one at [app.kolbo.ai/developer](https://app.kolbo.ai/developer) and add `"env": { "KOLBO_API_KEY": "kolbo_live_..." }` to the block above._
60
-
61
- ### Browser-only (claude.ai / ChatGPT): the connector
62
-
63
- No install at all — add the custom connector **`https://api.kolbo.ai/mcp`** under Settings → Connectors, then Connect → log in → Allow. Great for generating from text or URLs; to upload your own local files, use the config install above (it runs on your machine).
64
-
65
- ### Optional upgrade: add the Kolbo skill for slash-commands + smart routing
66
-
67
- The config above is all you need. If you want one-word slash-commands (`/kolbo:marketing-studio`, `/kolbo:product-photoshoot`, …) and automatic routing to the best tool with the right defaults, install the Kolbo skill on top — it's an enhancement layer, not a requirement:
68
-
69
- ```bash
70
- # Claude Code (also writes the MCP config for you, so you can skip Step 2 above)
71
- claude plugin marketplace add Zoharvan12/kolbo-skills
72
- claude plugin install kolbo@kolbo-skills
73
-
74
- # Cursor / Codex / any agent (cross-agent installer)
75
- npx skills add Zoharvan12/kolbo-skills
76
- ```
77
-
78
- The skill content is the same canonical routing logic that ships inside [Kolbo Code](https://github.com/Zoharvan12/kolbo-code), so however you connect, the behavior matches. See the full setup guide at [docs.kolbo.ai/developer-api/claude-code-skill](https://docs.kolbo.ai/developer-api/claude-code-skill).
79
-
80
- ### Use it
81
-
82
- Just ask your agent naturally:
83
-
84
- **Generation**
85
- - *"Generate an image of a sunset over mountains"*
86
- - *"Create a 5-second video of waves crashing"*
87
- - *"Build a 4-scene storyboard for a coffee shop ad"*
88
- - *"Remove the background from this image"*
89
- - *"Make a lo-fi hip hop beat"*
90
- - *"Read this out loud with a British female voice"*
91
-
92
- **Marketing & UGC**
93
- - *"Make me a UGC ad for my sneaker brand — 9:16, talking-head style"*
94
- - *"TV spot for my new beverage, 15 seconds, cinematic"*
95
- - *"Unboxing video for this product photo"*
96
-
97
- **Brand & product imagery**
98
- - *"Pinterest pin for my candle brand, cottagecore mood"*
99
- - *"Hero banner for my landing page, wide format"*
100
- - *"Lifestyle shot of my product in a kitchen"*
101
- - *"4 ad creative variants for Meta and TikTok"*
102
-
103
- **Marketplace listings**
104
- - *"Generate Amazon main image + 5 secondary images for my product"*
105
- - *"Full A+ content set for my Shopify listing"*
106
-
107
- **Analysis & utility**
108
- - *"Ask Claude about the latest AI news with web search on"*
109
- - *"Analyze this video and tell me what prompts are shown on screen"*
110
- - *"What's in this image?"*
111
- - *"Create a Visual DNA profile called 'Alex' from these images"*
112
- - *"Use the same brand as last time"* (loads a persisted brand kit from the workspace)
113
-
114
- Without the optional skill, the config block alone already exposes every tool — you just describe what you want. With the skill installed, each of these is also routed to the right MCP tool with the right defaults — UGC mode picks 9:16 + sound-off + no-captions, marketplace mode enforces compliance (pure white bg, no text, no props), product photoshoot mode uses the right aspect for the platform (2:3 Pinterest, 16:9 hero banner, 1:1 IG feed), etc. The routing logic is shared with [Kolbo Code](https://github.com/Zoharvan12/kolbo-code), so the behavior is identical however you connect.
115
-
116
- ## Available Tools (86)
117
-
118
- **Generation**
119
- | Tool | Description |
120
- |------|-------------|
121
- | `generate_image` | Text → image |
122
- | `generate_image_edit` | Existing image(s) + prompt → edited image |
123
- | `generate_video` | Text → video |
124
- | `generate_video_from_image` | Still image + motion prompt → video |
125
- | `generate_video_from_video` | Input video → restyled video, or burn in subtitles (video-to-video). `prompt` optional — prompt-less models (VEED Subtitles, Act Two, Wan Animate) use `preset` / `source_language` / `translation_language`, plus `srt_content` / `srt_file_url` / `vocabulary` / `customization` for VEED |
126
- | `generate_elements` | Reference images/videos + prompt → animated video |
127
- | `generate_first_last_frame` | First frame + last frame → interpolated video |
128
- | `generate_lipsync` | Source image/video + audio → lipsynced video (Sync-3 adds active-speaker selection, emotion, model mode, temperature) |
129
- | `generate_creative_director` | One brief → N coordinated scenes (image or video) |
130
- | `generate_music` | Text (+ optional lyrics) → song |
131
- | `generate_speech` | Text + voice → spoken audio |
132
- | `generate_sound` | Text → sound effect |
133
- | `generate_3d` | Text or reference images → 3D model (GLB/FBX/OBJ/USDZ) |
134
- | `transcribe_audio` | Audio/video URL or file → text + SRT subtitles |
135
-
136
- Every image/video/creative-director tool accepts `visual_dna_ids` and `moodboard_id` for character/style consistency across outputs — you can compose `create_visual_dna` → `generate_image` (with the DNA applied server-side) in a single agent turn. `generate_creative_director` also accepts `moodboard_ids` plural for blending.
137
-
138
- Every generation tool also accepts an optional `resolution` arg. Images use `"1K"` (~1024px) / `"2K"` (Full HD) / `"3K"` (QHD) / `"4K"` (UHD); videos use vertical-pixel tiers like `"720p"` / `"1080p"` / `"1440p"` / `"2160p"`. Values are model-dependent — call `list_models` and read the chosen model's `supported_resolutions` and `resolutionMultipliers`. Omit to use the model default.
139
-
140
- Every generation tool also accepts an optional `project_id` arg that routes the generation into a specific project (owned or shared with edit+). Call `list_projects` to discover IDs. When omitted, generations land in the user's auto-created "API Generations" project.
141
-
142
- **Chat & Vision**
143
- | Tool | Description |
144
- |------|-------------|
145
- | `chat_send_message` | Multi-turn chat with any Kolbo model. Pass `media_urls` to analyze images, videos, or audio — auto-routes to Gemini for vision. Supports web search and deep think. |
146
- | `chat_list_conversations` | List past chat threads |
147
- | `chat_get_messages` | Fetch messages in a conversation |
148
-
149
- **Visual DNA** (reusable character/style/product profiles)
150
- | Tool | Description |
151
- |------|-------------|
152
- | `create_visual_dna` | Create a profile from URLs or local files |
153
- | `list_visual_dnas` | List your profiles |
154
- | `get_visual_dna` | Fetch one profile |
155
- | `delete_visual_dna` | Delete a profile |
156
-
157
- **Moodboards**
158
- | Tool | Description |
159
- |------|-------------|
160
- | `list_moodboards` | Browse presets + your moodboards |
161
- | `get_moodboard` | Fetch one moodboard with all image URLs |
162
-
163
- **Media Library**
164
- | Tool | Description |
165
- |------|-------------|
166
- | `upload_media` | Upload a local file (or remote URL) → stable Kolbo CDN URL for reuse |
167
- | `list_media` | Browse media library — filter by `project_id`, `folder_id`, `type`, `category` (ai / uploaded / edited / favorites / training-lab), `source_type`, `sort`, `search`, pagination |
168
- | `list_media_folders` | List the user's media folders (owned + shared) — discover `folder_id` values to pass to `list_media` |
169
- | `create_media_folder` | Create a new folder (name, optional description / color / icon) |
170
- | `update_media_folder` | Rename / recolor / re-icon a folder (owner only) |
171
- | `delete_media_folder` | Soft-delete a folder (owner only; items remain in library) |
172
- | `add_media_to_folder` | Add up to 500 media items to a folder (idempotent) |
173
- | `remove_media_from_folder` | Remove media items from a folder |
174
- | `share_media_folder` | Share a folder by user email (owner only) |
175
- | `unshare_media_folder` | Revoke a user's access to a folder (owner only) |
176
- | `favorite_media` | Mark a media item as favorited (idempotent) — pass `media_id` from `list_media` |
177
- | `unfavorite_media` | Remove a media item from favorites (idempotent) — pass `media_id` from `list_media` |
178
- | `get_media` | Fetch one media item's full details by id |
179
- | `delete_media` | Soft-delete a media item (30-day trash) |
180
- | `restore_media` | Restore a trashed item |
181
- | `permanently_delete_media` | Hard-delete (NOT reversible — confirm with user first) |
182
- | `move_media` | Re-assign a media item to a different project |
183
- | `bulk_delete_media` | Soft-delete up to 1000 items in one call |
184
- | `bulk_restore_media` | Restore up to 1000 trashed items |
185
- | `bulk_permanently_delete_media` | Hard-delete up to 1000 (NOT reversible) |
186
- | `bulk_move_media` | Move up to 1000 items to a project (atomic — all-or-nothing) |
187
- | `move_folder_contents` | Move every item in a folder to a project |
188
- | `get_media_stats` | Counts + storage bytes per type (optionally per project) |
189
-
190
- **Artifacts**
191
- | Tool | Description |
192
- |------|-------------|
193
- | `publish_html_artifact` | Publish an HTML page, SVG, or Mermaid diagram and get a public shareable URL on `sites.kolbo.ai`. Pass `share_token` from a prior publish to update the same URL in place (old content kept in version history). |
194
-
195
- **Music Library** (stock / production music)
196
- | Tool | Description |
197
- |------|-------------|
198
- | `search_music_library` | Search the licensed stock-music catalog by keyword + genre/mood/BPM/duration filters. Find a ready-made track (distinct from `generate_music`, which composes a new song). |
199
- | `analyze_script_for_music` | AI: turn a video/voiceover script into a music search (`query`, `mood`, `genre`, `keywords`). |
200
- | `browse_music_library` | Browse the catalog without a query (paginated). |
201
- | `get_music_library_facets` | List available genres, moods, instruments + BPM/duration ranges. |
202
- | `get_music_track_audio` | Get a track's downloadable 128/320/WAV URLs by id. |
203
- | `get_music_track_related` | Get stems + alternate versions of a track. |
204
- | `get_music_track_lyrics` | Get lyrics text, theme, and explicit flag for a track. |
205
-
206
- **Stock Library** (multi-source stock media: Pexels, Pixabay, Sketchfab 3D, Music)
207
- | Tool | Description |
208
- |------|-------------|
209
- | `search_stock_media` | Search photos/videos/illustrations/vectors/3D/music across providers. `source="all"` returns one interleaved feed. Find ready-made assets / b-roll (distinct from `generate_image`/`generate_video`). |
210
- | `get_stock_sources` | List enabled sources + which media types/filters each supports. |
211
- | `get_stock_categories` | List dynamic category/topic chips (pass `providerParam` as the `category` filter). |
212
- | `get_stock_asset` | Get one asset with all download variants, author, license, and attribution. |
213
- | `analyze_script_for_stock` | AI: turn a script into b-roll search terms (`queries[]`, `mediaType`, `keywords`). |
214
- | `import_stock_asset` | Copy a stock asset into the media library (CDN copy, stable URL). Free. |
215
-
216
- **Shorts Creator** (long video → viral vertical shorts, two-phase)
217
- | Tool | Description |
218
- |------|-------------|
219
- | `shorts_analyze` | Phase 1: analyze a long video (Kolbo media-library URL, ≤30 min) → AI-picked best moments with titles, hooks, scores, accent beats. Flat 15 credits. Polls until moments are ready (~1-3 min). |
220
- | `shorts_list_presets` | List restyle presets (identifier, name, preview video, default mode/subtitle style). |
221
- | `shorts_get_transcript` | Word-level Scribe transcript of the source video (`words`, `language`, `sourceDuration`) — the base for the Review & Edit workflow (build `delete_ranges` cuts + edited `srt_content`). |
222
- | `shorts_estimate` | Price a selection before rendering — free. Per-short credits + chunk counts. `delete_ranges` cuts shorten the effective duration (cheaper). |
223
- | `shorts_render` | Phase 2: render up to 5 shorts (15-90s each) from picked moments — `accents` mode (restyle strongest beats, cheaper) or `full` (restyle everything), optional burned-in subtitles. Per short: optional `delete_ranges` (cut dead air, absolute source seconds, ≥8s must remain) and `srt_content` (user-edited SRT, cut-timeline times, ≤200KB). Polls until done (~5-20 min), returns final URLs. Failed shorts auto-refund. |
224
- | `shorts_status` | One-shot job state read (moments / shorts / phase) — resume after a timeout. |
225
- | `shorts_cancel` | Cancel a job and refund unused credits. |
226
-
227
- **Discovery & Account**
228
- | Tool | Description |
229
- |------|-------------|
230
- | `list_models` | Current model catalog with costs and capabilities |
231
- | `list_voices` | TTS voices (presets + cloned) |
232
- | `list_presets` | Generation presets across image/video/music/text-to-video catalogs |
233
- | `list_projects` | List owned + shared projects (id, name, role, is_default) — call first to resolve a project name into the `project_id` you pass to generation tools |
234
- | `check_credits` | Check credit balance |
235
- | `get_generation_status` | Poll a generation by ID (fallback if a tool times out) |
236
-
237
- ## Environment Variables
238
-
239
- Both are optional — the local install logs in via the browser on first use.
240
-
241
- | Variable | Required | Description |
242
- |----------|----------|-------------|
243
- | `KOLBO_API_KEY` | No | Set a `kolbo_live_` key to skip the browser login (create one at [app.kolbo.ai/developer](https://app.kolbo.ai/developer)). |
244
- | `KOLBO_API_URL` | No | Custom API URL (default: `https://api.kolbo.ai/api`) |
245
-
246
- ## Links
247
-
248
- - [API Documentation](https://docs.kolbo.ai/developer-api)
249
- - [Kolbo AI Platform](https://kolbo.ai)
250
- - [Get API Key](https://app.kolbo.ai)
1
+ # @kolbo/mcp
2
+
3
+ Use [Kolbo AI](https://kolbo.ai) as native tools in Claude Code and Claude Desktop via MCP (Model Context Protocol).
4
+
5
+ Generate images, videos, music, speech, sound effects, multi-scene campaigns, and conversational chat — all from natural language in your coding environment. 100+ AI models behind Smart Select routing, with reusable Visual DNA profiles for character/style consistency.
6
+
7
+ **✨ Interactive widgets (v1.30+):** in claude.ai and Claude Desktop, generations render as live Kolbo cards — real-time progress with model + settings chips, an inline result gallery / video player, and one-click **Animate · Edit · Recreate · Download** actions. Library and model searches render as browsable grids with audio preview. Text-only clients (Claude Code, Cursor) keep the classic text responses.
8
+
9
+ ## Set up — paste one prompt, or one config block (keyless, no API key)
10
+
11
+ ### Easiest: paste this prompt to your AI
12
+
13
+ Copy this and paste it to Claude, ChatGPT, Cursor, or any AI assistant — it installs Kolbo itself (picks local config or remote connector based on what it can do):
14
+
15
+ ```
16
+ Connect the Kolbo AI MCP server (generate images, video, music and more).
17
+
18
+ - If you can run terminal commands (Claude Code, Cursor, Claude Desktop, or any local setup): run "npx -y @kolbo/mcp install" — it auto-configures Kolbo in the right place. If you can't run it, give me the command to run. Then I'll restart the app.
19
+ - If you're a browser chat (claude.ai, ChatGPT): add a custom connector with URL https://api.kolbo.ai/mcp under Settings → Connectors, then Connect → log in → Allow.
20
+
21
+ No API key needed — on first use a Kolbo login opens in my browser and I click Allow. When set up, confirm Kolbo is connected and offer to generate a test image of a sunset.
22
+ ```
23
+
24
+ ### Or set it up yourself — one command
25
+
26
+ <!--
27
+ AI ASSISTANT SETUP INSTRUCTIONS — if you are an AI agent reading this to set up Kolbo for a user, do exactly this:
28
+ 1. If you can run a terminal command (Claude Code, Cursor, Claude Desktop): run `npx -y @kolbo/mcp install` — it writes the keyless config to the right file for every installed agent. (Don't hand-edit settings.json; the installer is deterministic.) Then tell the user to restart the app. On the first generation a Kolbo login opens in the browser — they click Allow (no API key).
29
+ 2. If you're a web chat that can't run commands (claude.ai, ChatGPT): tell the user to add the connector URL https://api.kolbo.ai/mcp under Settings → Connectors instead.
30
+ The plugin below is an optional slash-command upgrade.
31
+ -->
32
+
33
+ Run this once — it sets up the **full** Kolbo experience (the MCP tools **and** the routing skill) for every installed agent (Claude Desktop, Claude Code, Cursor), keyless:
34
+
35
+ ```bash
36
+ npx -y @kolbo/mcp install
37
+ ```
38
+
39
+ Or add the config by hand — this block is identical for every MCP client and carries **no API key** (on first use it logs you in via the browser):
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "kolbo": {
45
+ "command": "npx",
46
+ "args": ["-y", "@kolbo/mcp@latest"]
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ | Client | Where the config goes |
53
+ |--------|----------------------|
54
+ | **Claude Code** | `.claude/settings.json` (or `claude mcp add kolbo -- npx -y @kolbo/mcp@latest`) |
55
+ | **Claude Desktop** | `claude_desktop_config.json` |
56
+ | **Cursor** | `.cursor/mcp.json` |
57
+ | **Kolbo Code** | configured automatically on `kolbo auth login` |
58
+
59
+ Restart your app, then ask it to generate something. The first time, a Kolbo login opens in your browser — click **Allow** (no API key to create). _Prefer an API key? Create one at [app.kolbo.ai/developer](https://app.kolbo.ai/developer) and add `"env": { "KOLBO_API_KEY": "kolbo_live_..." }` to the block above._
60
+
61
+ ### Browser-only (claude.ai / ChatGPT): the connector
62
+
63
+ No install at all — add the custom connector **`https://api.kolbo.ai/mcp`** under Settings → Connectors, then Connect → log in → Allow. Great for generating from text or URLs; to upload your own local files, use the config install above (it runs on your machine).
64
+
65
+ ### Optional upgrade: add the Kolbo skill for slash-commands + smart routing
66
+
67
+ The config above is all you need. If you want one-word slash-commands (`/kolbo:marketing-studio`, `/kolbo:product-photoshoot`, …) and automatic routing to the best tool with the right defaults, install the Kolbo skill on top — it's an enhancement layer, not a requirement:
68
+
69
+ ```bash
70
+ # Claude Code (also writes the MCP config for you, so you can skip Step 2 above)
71
+ claude plugin marketplace add Zoharvan12/kolbo-skills
72
+ claude plugin install kolbo@kolbo-skills
73
+
74
+ # Cursor / Codex / any agent (cross-agent installer)
75
+ npx skills add Zoharvan12/kolbo-skills
76
+ ```
77
+
78
+ The skill content is the same canonical routing logic that ships inside [Kolbo Code](https://github.com/Zoharvan12/kolbo-code), so however you connect, the behavior matches. See the full setup guide at [docs.kolbo.ai/developer-api/claude-code-skill](https://docs.kolbo.ai/developer-api/claude-code-skill).
79
+
80
+ ### Use it
81
+
82
+ Just ask your agent naturally:
83
+
84
+ **Generation**
85
+ - *"Generate an image of a sunset over mountains"*
86
+ - *"Create a 5-second video of waves crashing"*
87
+ - *"Build a 4-scene storyboard for a coffee shop ad"*
88
+ - *"Remove the background from this image"*
89
+ - *"Make a lo-fi hip hop beat"*
90
+ - *"Read this out loud with a British female voice"*
91
+
92
+ **Marketing & UGC**
93
+ - *"Make me a UGC ad for my sneaker brand — 9:16, talking-head style"*
94
+ - *"TV spot for my new beverage, 15 seconds, cinematic"*
95
+ - *"Unboxing video for this product photo"*
96
+
97
+ **Brand & product imagery**
98
+ - *"Pinterest pin for my candle brand, cottagecore mood"*
99
+ - *"Hero banner for my landing page, wide format"*
100
+ - *"Lifestyle shot of my product in a kitchen"*
101
+ - *"4 ad creative variants for Meta and TikTok"*
102
+
103
+ **Marketplace listings**
104
+ - *"Generate Amazon main image + 5 secondary images for my product"*
105
+ - *"Full A+ content set for my Shopify listing"*
106
+
107
+ **Analysis & utility**
108
+ - *"Ask Claude about the latest AI news with web search on"*
109
+ - *"Analyze this video and tell me what prompts are shown on screen"*
110
+ - *"What's in this image?"*
111
+ - *"Create a Visual DNA profile called 'Alex' from these images"*
112
+ - *"Use the same brand as last time"* (loads a persisted brand kit from the workspace)
113
+
114
+ Without the optional skill, the config block alone already exposes every tool — you just describe what you want. With the skill installed, each of these is also routed to the right MCP tool with the right defaults — UGC mode picks 9:16 + sound-off + no-captions, marketplace mode enforces compliance (pure white bg, no text, no props), product photoshoot mode uses the right aspect for the platform (2:3 Pinterest, 16:9 hero banner, 1:1 IG feed), etc. The routing logic is shared with [Kolbo Code](https://github.com/Zoharvan12/kolbo-code), so the behavior is identical however you connect.
115
+
116
+ ## Available Tools (86)
117
+
118
+ **Generation**
119
+ | Tool | Description |
120
+ |------|-------------|
121
+ | `generate_image` | Text → image |
122
+ | `generate_image_edit` | Existing image(s) + prompt → edited image |
123
+ | `generate_video` | Text → video |
124
+ | `generate_video_from_image` | Still image + motion prompt → video |
125
+ | `generate_video_from_video` | Input video → restyled video, or burn in subtitles (video-to-video). `prompt` optional — prompt-less models (VEED Subtitles, Act Two, Wan Animate) use `preset` / `source_language` / `translation_language`, plus `srt_content` / `srt_file_url` / `vocabulary` / `customization` for VEED |
126
+ | `generate_elements` | Reference images/videos + prompt → animated video |
127
+ | `generate_first_last_frame` | First frame + last frame → interpolated video |
128
+ | `generate_lipsync` | Source image/video + audio → lipsynced video (Sync-3 adds active-speaker selection, emotion, model mode, temperature) |
129
+ | `generate_creative_director` | One brief → N coordinated scenes (image or video) |
130
+ | `generate_music` | Text (+ optional lyrics) → song |
131
+ | `generate_speech` | Text + voice → spoken audio |
132
+ | `generate_sound` | Text → sound effect |
133
+ | `generate_3d` | Text or reference images → 3D model (GLB/FBX/OBJ/USDZ) |
134
+ | `transcribe_audio` | Audio/video URL or file → text + SRT subtitles |
135
+
136
+ Every image/video/creative-director tool accepts `visual_dna_ids` and `moodboard_id` for character/style consistency across outputs — you can compose `create_visual_dna` → `generate_image` (with the DNA applied server-side) in a single agent turn. `generate_creative_director` also accepts `moodboard_ids` plural for blending.
137
+
138
+ Every generation tool also accepts an optional `resolution` arg. Images use `"1K"` (~1024px) / `"2K"` (Full HD) / `"3K"` (QHD) / `"4K"` (UHD); videos use vertical-pixel tiers like `"720p"` / `"1080p"` / `"1440p"` / `"2160p"`. Values are model-dependent — call `list_models` and read the chosen model's `supported_resolutions` and `resolutionMultipliers`. Omit to use the model default.
139
+
140
+ Every generation tool also accepts an optional `project_id` arg that routes the generation into a specific project (owned or shared with edit+). Call `list_projects` to discover IDs. When omitted, generations land in the user's auto-created "API Generations" project. `project_id` is per-call, NOT sticky — pass it on every call once the user names a working project. Misplaced work is recoverable via `move_media` / `move_session`.
141
+
142
+ **Chat & Vision**
143
+ | Tool | Description |
144
+ |------|-------------|
145
+ | `chat_send_message` | Multi-turn chat with any Kolbo model. Pass `media_urls` to analyze images, videos, or audio — auto-routes to Gemini for vision. Supports web search and deep think. |
146
+ | `chat_list_conversations` | List past chat threads |
147
+ | `chat_get_messages` | Fetch messages in a conversation |
148
+
149
+ **Visual DNA** (reusable character/style/product profiles)
150
+ | Tool | Description |
151
+ |------|-------------|
152
+ | `create_visual_dna` | Create a profile from URLs or local files |
153
+ | `list_visual_dnas` | List your profiles |
154
+ | `get_visual_dna` | Fetch one profile |
155
+ | `delete_visual_dna` | Delete a profile |
156
+
157
+ **Moodboards**
158
+ | Tool | Description |
159
+ |------|-------------|
160
+ | `list_moodboards` | Browse presets + your moodboards |
161
+ | `get_moodboard` | Fetch one moodboard with all image URLs |
162
+
163
+ **Media Library**
164
+ | Tool | Description |
165
+ |------|-------------|
166
+ | `upload_media` | Upload a local file (or remote URL) → stable Kolbo CDN URL for reuse |
167
+ | `list_media` | Browse media library — filter by `project_id`, `folder_id`, `type`, `category` (ai / uploaded / edited / favorites / training-lab), `source_type`, `sort`, `search`, pagination |
168
+ | `list_media_folders` | List the user's media folders (owned + shared) — discover `folder_id` values to pass to `list_media` |
169
+ | `create_media_folder` | Create a new folder (name, optional description / color / icon) |
170
+ | `update_media_folder` | Rename / recolor / re-icon a folder (owner only) |
171
+ | `delete_media_folder` | Soft-delete a folder (owner only; items remain in library) |
172
+ | `add_media_to_folder` | Add up to 500 media items to a folder (idempotent) |
173
+ | `remove_media_from_folder` | Remove media items from a folder |
174
+ | `share_media_folder` | Share a folder by user email (owner only) |
175
+ | `unshare_media_folder` | Revoke a user's access to a folder (owner only) |
176
+ | `favorite_media` | Mark a media item as favorited (idempotent) — pass `media_id` from `list_media` |
177
+ | `unfavorite_media` | Remove a media item from favorites (idempotent) — pass `media_id` from `list_media` |
178
+ | `get_media` | Fetch one media item's full details by id |
179
+ | `delete_media` | Soft-delete a media item (30-day trash) |
180
+ | `restore_media` | Restore a trashed item |
181
+ | `permanently_delete_media` | Hard-delete (NOT reversible — confirm with user first) |
182
+ | `move_media` | Re-assign a media item to a different project |
183
+ | `bulk_delete_media` | Soft-delete up to 1000 items in one call |
184
+ | `bulk_restore_media` | Restore up to 1000 trashed items |
185
+ | `bulk_permanently_delete_media` | Hard-delete up to 1000 (NOT reversible) |
186
+ | `bulk_move_media` | Move up to 1000 items to a project (atomic — all-or-nothing) |
187
+ | `move_folder_contents` | Move every item in a folder to a project |
188
+ | `get_media_stats` | Counts + storage bytes per type (optionally per project) |
189
+
190
+ **Artifacts**
191
+ | Tool | Description |
192
+ |------|-------------|
193
+ | `publish_html_artifact` | Publish an HTML page, SVG, or Mermaid diagram and get a public shareable URL on `sites.kolbo.ai`. Pass `share_token` from a prior publish to update the same URL in place (old content kept in version history). |
194
+
195
+ **Music Library** (stock / production music)
196
+ | Tool | Description |
197
+ |------|-------------|
198
+ | `search_music_library` | Search the licensed stock-music catalog by keyword + genre/mood/BPM/duration filters. Find a ready-made track (distinct from `generate_music`, which composes a new song). |
199
+ | `analyze_script_for_music` | AI: turn a video/voiceover script into a music search (`query`, `mood`, `genre`, `keywords`). |
200
+ | `browse_music_library` | Browse the catalog without a query (paginated). |
201
+ | `get_music_library_facets` | List available genres, moods, instruments + BPM/duration ranges. |
202
+ | `get_music_track_audio` | Get a track's downloadable 128/320/WAV URLs by id. |
203
+ | `get_music_track_related` | Get stems + alternate versions of a track. |
204
+ | `get_music_track_lyrics` | Get lyrics text, theme, and explicit flag for a track. |
205
+
206
+ **Stock Library** (multi-source stock media: Pexels, Pixabay, Sketchfab 3D, Music)
207
+ | Tool | Description |
208
+ |------|-------------|
209
+ | `search_stock_media` | Search photos/videos/illustrations/vectors/3D/music across providers. `source="all"` returns one interleaved feed. Find ready-made assets / b-roll (distinct from `generate_image`/`generate_video`). |
210
+ | `get_stock_sources` | List enabled sources + which media types/filters each supports. |
211
+ | `get_stock_categories` | List dynamic category/topic chips (pass `providerParam` as the `category` filter). |
212
+ | `get_stock_asset` | Get one asset with all download variants, author, license, and attribution. |
213
+ | `analyze_script_for_stock` | AI: turn a script into b-roll search terms (`queries[]`, `mediaType`, `keywords`). |
214
+ | `import_stock_asset` | Copy a stock asset into the media library (CDN copy, stable URL). Free. |
215
+
216
+ **Shorts Creator** (long video → viral vertical shorts, two-phase)
217
+ | Tool | Description |
218
+ |------|-------------|
219
+ | `shorts_analyze` | Phase 1: analyze a long video (Kolbo media-library URL, ≤30 min) → AI-picked best moments with titles, hooks, scores, accent beats. Flat 15 credits. Polls until moments are ready (~1-3 min). |
220
+ | `shorts_list_presets` | List restyle presets (identifier, name, preview video, default mode/subtitle style). |
221
+ | `shorts_get_transcript` | Word-level Scribe transcript of the source video (`words`, `language`, `sourceDuration`) — the base for the Review & Edit workflow (build `delete_ranges` cuts + edited `srt_content`). |
222
+ | `shorts_estimate` | Price a selection before rendering — free. Per-short credits + chunk counts. `delete_ranges` cuts shorten the effective duration (cheaper). |
223
+ | `shorts_render` | Phase 2: render up to 5 shorts (15-90s each) from picked moments — `accents` mode (restyle strongest beats, cheaper) or `full` (restyle everything), optional burned-in subtitles. Per short: optional `delete_ranges` (cut dead air, absolute source seconds, ≥8s must remain) and `srt_content` (user-edited SRT, cut-timeline times, ≤200KB). Polls until done (~5-20 min), returns final URLs. Failed shorts auto-refund. |
224
+ | `shorts_status` | One-shot job state read (moments / shorts / phase) — resume after a timeout. |
225
+ | `shorts_cancel` | Cancel a job and refund unused credits. |
226
+
227
+ **Discovery & Account**
228
+ | Tool | Description |
229
+ |------|-------------|
230
+ | `list_models` | Current model catalog with costs and capabilities |
231
+ | `list_voices` | TTS voices (presets + cloned) |
232
+ | `list_presets` | Generation presets across image/video/music/text-to-video catalogs |
233
+ | `list_projects` | List owned + shared projects (id, name, role, is_default) — call first to resolve a project name into the `project_id` you pass to generation tools |
234
+ | `move_session` | Move a session (generation, chat, transcription…) and ALL its media to another project |
235
+ | `check_credits` | Check credit balance |
236
+ | `get_generation_status` | Poll a generation by ID (fallback if a tool times out) |
237
+
238
+ ## Environment Variables
239
+
240
+ Both are optional — the local install logs in via the browser on first use.
241
+
242
+ | Variable | Required | Description |
243
+ |----------|----------|-------------|
244
+ | `KOLBO_API_KEY` | No | Set a `kolbo_live_` key to skip the browser login (create one at [app.kolbo.ai/developer](https://app.kolbo.ai/developer)). |
245
+ | `KOLBO_API_URL` | No | Custom API URL (default: `https://api.kolbo.ai/api`) |
246
+
247
+ ## Links
248
+
249
+ - [API Documentation](https://docs.kolbo.ai/developer-api)
250
+ - [Kolbo AI Platform](https://kolbo.ai)
251
+ - [Get API Key](https://app.kolbo.ai)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.31.6",
3
+ "version": "1.32.0",
4
4
  "description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  # AUTO-GENERATED — do not edit
2
2
 
3
3
  This skill/ tree is mirrored from kolbo-code (the single source of truth)
4
- by .github/workflows/sync-skill-to-plugin.yml — synced from kolbo-code@9cf6c35.
4
+ by .github/workflows/sync-skill-to-plugin.yml — synced from kolbo-code@53720a8.
5
5
 
6
6
  It is the skill that 'npx @kolbo/mcp install' deploys into the user's agent.
7
7
  To change it, edit packages/opencode/skills/kolbo/ in kolbo-code and push;
package/skill/SKILL.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- version: 0.5.0
2
+ version: 0.5.1
3
3
  name: kolbo
4
4
  description: |
5
5
  Generate, edit, or analyze creative media via the Kolbo AI MCP server:
@@ -113,6 +113,7 @@ Each `references/models/*.md` mirrors the matching skill prompt in `kolbo-api/sr
113
113
  | `upload_media` / `list_media` / `get_media` / `get_media_stats` / `favorite_media` / `unfavorite_media` / `delete_media` / `restore_media` / `permanently_delete_media` / `move_media` / `bulk_*_media` / `*_media_folder` | Media library — see `workflows/media-library.md` |
114
114
  | `create_visual_dna` / `list_visual_dnas` / `get_visual_dna` / `delete_visual_dna` | Visual DNA — see `workflows/visual-dna.md` |
115
115
  | `list_moodboards` / `get_moodboard` / `list_presets` | Style overlays |
116
+ | `search_stock_media` / `get_stock_sources` / `get_stock_categories` / `get_stock_collections` / `get_stock_asset` / `analyze_script_for_stock` / `import_stock_asset` | Stock library (free, no credits) — EXISTING photos / videos / 3D / SFX / music. For stock **music** use `search_stock_media` with `mediaType: "music"` (semantic vibe query, e.g. "uplifting corporate background") → `get_stock_asset` for downloads. The older `*_music_library` tools are deprecated adapters over this — prefer the stock tools. |
116
117
  | `chat_send_message` / `chat_list_conversations` / `chat_get_messages` | Kolbo chat with optional `media_urls` (up to 10 per call) |
117
118
  | `app_builder_*` (9 tools) | Full React app generation — see `workflows/app-builder.md` |
118
119
  | `publish_html_artifact` | Publish HTML / SVG / Mermaid to `sites.kolbo.ai`. Server dedupes by content hash. Strict CSP. |
@@ -149,7 +150,7 @@ A user-named tool — in any language — overrides every other rule. Recognized
149
150
  1. **Check credits** ONCE per conversation (Step 0). Skip if already checked.
150
151
  2. **Discover models** with `list_models` using a `type` filter — but **skip when the user names a specific model**.
151
152
  3. **Pick the model**:
152
- - User named one → use it.
153
+ - User named one → use it. Model identifiers resolve leniently — shorthand like `"z-image"` or `"nano banana 2"` auto-resolves to the exact identifier, so don't over-engineer exact-id lookups (`list_models` is still authoritative for constraints, caps, and pricing).
153
154
  - Auto-select → only from "Auto-selectable" section (models with a `summary`). Cheapest fit. Prefer `[RECOMMENDED]` when cost is similar.
154
155
  - Never auto-select from "Named-only" section.
155
156
  4. **Validate inputs** against model caps — see `references/workflows/cost-and-validation.md`.
@@ -203,6 +204,8 @@ Existing video → modify → **single `generate_video_from_video` call** with s
203
204
 
204
205
  **Use a TRUE video-to-video model.** Image-to-video models reject with `WRONG_MODEL_TYPE`. Valid: `wan/2-7-videoedit`, `happyhorse/video-edit`, `kling-video/o3-video-to-video`, or any model whose DB `type` includes `video_to_video` (use `list_models({ type: "video_to_video" })`).
205
206
 
207
+ **Motion-control / animate-move models invert the inputs**: `reference_images[0]` = the CHARACTER IMAGE to animate, `source_video` = the driving/reference video whose motion is transferred. Omitting the character image returns a `MOTION_CONTROL_INPUTS` error.
208
+
206
209
  **Do NOT** decompose into frames. **Do NOT** re-fire if the first call returned URLs.
207
210
 
208
211
  ## ⚠️ Character-Driven Video — Frames First, Then Animate (CRITICAL)
package/skill/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
@@ -8,9 +8,12 @@ Load this file when the user wants AI-generated **music** — full songs, lyrics
8
8
 
9
9
  **Kolbo MCP routing:** call `generate_music`. Suno is a model option — use `list_models({ type: "music_gen" })` to see versions. Pass `instrumental` and `duration` as separate params; pass the Style/Description text as `style` and the Lyrics as `lyrics`.
10
10
 
11
+ **Wants an EXISTING track, not a new song?** ("background music", "stock music", "royalty-free track") → don't generate. Use `search_stock_media` with `mediaType: "music"` (semantic vibe query — "tense cinematic pulse", "uplifting corporate background") → `get_stock_asset` for download URLs. Free, no credits. The older `*_music_library` tools are deprecated adapters over the stock library — prefer the stock tools.
12
+
11
13
  ## CRITICAL Kolbo Platform Rules
12
14
 
13
15
  - **Model version, duration, and instrumental toggle are MCP-tool params.** Don't write `v4.5`, `30 seconds`, or `instrumental: true` inside the prompt fields themselves.
16
+ - **Exact track length = `duration_seconds`** (clamped 5–300s). Only length-controllable models honor it (e.g. ElevenLabs Music, `music-v1`) — without it those models default to a ~10s track, so ALWAYS pass it for jingles/beds on those models. Suno ignores it and picks its own length.
14
17
  - Suno generations have **two separate input fields**: a **Style / Description** field (`style` param) and a **Lyrics** field (`lyrics` param). Output your prompt as **TWO separate fenced code blocks** so the user (and the tool call) know exactly what goes where.
15
18
  - Tell the user to run the prompt multiple times — Suno output varies significantly between generations, that's a feature. Use `num_generations` if the tool supports it, or fire 2–4 parallel `generate_music` calls.
16
19
 
@@ -85,7 +88,7 @@ Use Suno's section tags to control structure. Each tag goes on its own line, con
85
88
  ### Jingle / ad music (15–30s)
86
89
  - `style`: short, punchy descriptor (`upbeat retail pop jingle, female vocal, claps, glossy production, summer energy`)
87
90
  - `lyrics`: 2–4 short lines max, often just chorus
88
- - Pass the shortest `duration` the tool supports.
91
+ - Pass the shortest `duration` the tool supports — or, on a length-controllable model (ElevenLabs Music), pass the exact `duration_seconds` (e.g. `15` or `30`).
89
92
 
90
93
  ### Cinematic trailer / score
91
94
  - `style`: `cinematic orchestral trailer, swelling strings, taiko drums, hybrid choir, dramatic build, modern hybrid score`
package/src/apps/theme.js CHANGED
@@ -180,17 +180,21 @@ body {
180
180
  border-radius: 12px; background: #000; border: 1px solid var(--border); cursor: zoom-in; }
181
181
  .k-viewer video { cursor: default; }
182
182
 
183
- /* ---- Fullscreen (ui/request-display-mode granted) ---- */
184
- html.k-fullscreen, html.k-fullscreen body { height: 100%; }
185
- html.k-fullscreen .k-card { height: 100%; display: flex; flex-direction: column; border-radius: 0; }
186
- html.k-fullscreen .k-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
187
- html.k-fullscreen .k-viewer { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
183
+ /* ---- Fullscreen (ui/request-display-mode granted) ----
184
+ position:fixed pins the card to the iframe viewport regardless of document
185
+ flow/host sizing quirks the media physically cannot exceed the screen. */
186
+ html.k-fullscreen, html.k-fullscreen body { height: 100%; overflow: hidden; }
187
+ html.k-fullscreen .k-card { position: fixed; inset: 0; display: flex; flex-direction: column; border-radius: 0; }
188
+ html.k-fullscreen .k-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
189
+ html.k-fullscreen .k-prompt, html.k-fullscreen .k-chips { flex: none; }
190
+ html.k-fullscreen #stage { flex: 1; min-height: 0; display: flex; flex-direction: column; }
191
+ html.k-fullscreen .k-viewer { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; margin-bottom: 6px; }
188
192
  html.k-fullscreen .k-viewer img, html.k-fullscreen .k-viewer video {
189
- /* hard viewport cap the image must NEVER exceed the screen or cover the
190
- host's chrome, whatever the host's iframe sizing does */
191
- max-height: min(100%, calc(100dvh - 130px)); max-width: 100%;
193
+ max-height: 100%; max-width: 100%; height: auto;
192
194
  width: auto; margin: 0 auto; cursor: zoom-out; object-fit: contain; }
193
- html.k-fullscreen .k-thumbs .k-thumb { width: 64px; height: 64px; }
195
+ html.k-fullscreen .k-thumbs { flex: none; }
196
+ html.k-fullscreen .k-thumbs .k-thumb { width: 56px; height: 56px; }
197
+ html.k-fullscreen .k-actions { flex: none; padding-top: 8px; }
194
198
  .k-expand-hint { display: none; }
195
199
  .k-thumbs { display: flex; gap: 6px; margin: 10px 0 2px; }
196
200
  .k-thumbs .k-thumb { width: 48px; height: 48px; border-radius: 8px; overflow: hidden; cursor: pointer;
@@ -387,7 +387,6 @@ function renderActions(sc) {
387
387
  }
388
388
  if (sc.kind === 'video') {
389
389
  a.push('<button class="k-btn primary" id="btn-download">⬇ Download</button>');
390
- a.push('<button class="k-btn" id="btn-analyze">📊 Analyze</button>');
391
390
  } else if (hasSingleUrl) {
392
391
  // Scenes (Creative Director) have no single "current" url — per-item hover
393
392
  // download buttons cover them instead.
@@ -421,9 +420,6 @@ function renderActions(sc) {
421
420
  '\\nEdit instruction: ' + text);
422
421
  });
423
422
  });
424
- bind('btn-analyze', function () {
425
- window.kolbo.sendMessage('Analyze this video and give me an engagement/virality read — hook strength, pacing, retention risks, and concrete improvement tips:\\n' + currentUrl());
426
- });
427
423
  }
428
424
  function bind(id, fn) { var b = el(id); if (b) b.onclick = fn; }
429
425
 
@@ -8,7 +8,8 @@ const { widgetPage } = require('../html');
8
8
  * structuredContent: {
9
9
  * widget: 'transcript', phase: 'completed'|'generating'|'failed',
10
10
  * generation_id, poll_tool, text, duration, audio_url, srt_url,
11
- * word_by_word_srt_url, txt_url, credits_used, error
11
+ * word_by_word_srt_url, txt_url, credits_used, error,
12
+ * open_url // "Open in Kolbo" session deep link (optional)
12
13
  * }
13
14
  */
14
15
 
@@ -34,7 +35,7 @@ const BODY = `
34
35
 
35
36
  const SCRIPT = `
36
37
  el('logo').innerHTML = KOLBO_LOGO + '<span>Kolbo</span>';
37
- el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openLink('https://app.kolbo.ai'); };
38
+ el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openLink((state && state.open_url) || 'https://app.kolbo.ai'); };
38
39
  var state = null, pollTimer = null;
39
40
 
40
41
  function boot(sc) {
package/src/index.js CHANGED
@@ -103,6 +103,18 @@ function createServer(opts = {}) {
103
103
  // Connector avatar for hosts that render server icons (claude.ai tool
104
104
  // headers show this instead of a letter monogram).
105
105
  icons: [{ src: 'https://api.kolbo.ai/assets/kolbo-ai.png', mimeType: 'image/png', sizes: ['512x512'] }]
106
+ }, {
107
+ // Server-level instructions surfaced to the host model on initialize.
108
+ // The single most common failure mode is project confusion — spell out
109
+ // the project contract here so every client gets it without a skill file.
110
+ instructions: [
111
+ 'PROJECT CONTRACT (read this before generating anything):',
112
+ 'Everything in Kolbo lives inside a PROJECT — sessions, generations, and media are all project-scoped.',
113
+ '1. When the user names a project ("in my Acme project", "for the summer campaign"), call `list_projects` ONCE to resolve the name to an id, then pass that id as `project_id` on EVERY subsequent generate_* / chat_send_message / upload_media call in the conversation. The target project is per-call, NOT sticky — any call that omits `project_id` silently lands in the default "API Generations" bucket (flagged is_default:true), which users experience as their work going to the wrong project.',
114
+ '2. `list_projects` lists the user\'s platform projects (for generations/media/chat). `app_builder_list_projects` is a DIFFERENT tool that scopes App Builder coding sessions only — never use one where the other is meant.',
115
+ '3. Misplaced work is fixable: `move_media` / `bulk_move_media` / `move_folder_contents` move media items between projects; `move_session` moves a whole session (plus its media) to another project. If the user says a generation landed in the wrong project, move it rather than regenerating.',
116
+ '4. If the user has not mentioned any project, omit `project_id` — the default bucket is correct in that case. Do not ask which project to use unless the user\'s intent is ambiguous.'
117
+ ].join('\n')
106
118
  });
107
119
 
108
120
  // Register all tools. `inlineImages` (off by default) is opt-in: only the
@@ -251,7 +251,7 @@ function creditFields(polledResult) {
251
251
  // resolve a name → ObjectId.
252
252
  const { z } = require('zod');
253
253
  const projectIdField = z.string().optional().describe(
254
- 'Project ObjectId to drop this generation into. Call `list_projects` to discover IDs (the API has no concept of project names — only ObjectIds). Omit to use the user\'s default "API Generations" project. Requires owner / edit / full permission on the project; view-only is rejected.'
254
+ 'Project ObjectId to drop this generation into. Call `list_projects` to discover IDs (the API has no concept of project names — only ObjectIds). IMPORTANT: this is per-call, NOT sticky — once the user has named a working project, pass its id on EVERY generation call in the conversation; any call that omits it silently lands in the default "API Generations" project instead. Requires owner / edit / full permission on the project; view-only is rejected.'
255
255
  );
256
256
 
257
257
  // ─── Optional inline-image content blocks ────────────────────────────────────
@@ -305,6 +305,56 @@ async function inlineImageBlocks(urls, opts = {}) {
305
305
  return blocks.filter(Boolean);
306
306
  }
307
307
 
308
+ // ─── "Open in Kolbo" deep links ───────────────────────────────────────────────
309
+ // kolbo-api submit responses include `session_id` + `project_id`. Map each MCP
310
+ // tool to the frontend page + tool slug whose session view can RESUME that
311
+ // session (mirrors kolbo-map src/constants/sessionTypes.js resumeUrl map — the
312
+ // route must match the SESSION MODEL the SDK created, per sdkSessionManager):
313
+ // ImageSession → /image-tools?tool=text-to-image
314
+ // imgEditSession (image_edit AND edit_image/global_image_edit) → /image-tools?tool=image-editing
315
+ // textToVideoSession → /video-tools?tool=text-to-video
316
+ // imgToVideoSession (video_from_image, elements, first_last_frame) → /video-tools?tool=image-to-video
317
+ // videoToVideoSession → /video-tools?tool=video-to-video
318
+ // lipsyncSession → /video-tools?tool=lipsync
319
+ // MusicGeneratorSession / TextToSpeechSession / textToSoundSession /
320
+ // speechToTextSession → /audio-tools with the matching slug
321
+ // CreativeDirectorSession → /creative-director?session=... (no tool param)
322
+ // Intentionally ABSENT (no deep-linkable session page — widget falls back to
323
+ // plain https://app.kolbo.ai): edit_video (GlobalVideoEditSession has no
324
+ // session deep-link), generate_3d (project-scoped, no session), shorts render.
325
+ const APP_BASE_URL = 'https://app.kolbo.ai';
326
+ const OPEN_URL_ROUTES = {
327
+ generate_image: { path: '/image-tools', tool: 'text-to-image' },
328
+ generate_image_edit: { path: '/image-tools', tool: 'image-editing' },
329
+ edit_image: { path: '/image-tools', tool: 'image-editing' },
330
+ generate_video: { path: '/video-tools', tool: 'text-to-video' },
331
+ generate_video_from_image: { path: '/video-tools', tool: 'image-to-video' },
332
+ generate_elements: { path: '/video-tools', tool: 'image-to-video' },
333
+ generate_first_last_frame: { path: '/video-tools', tool: 'image-to-video' },
334
+ generate_video_from_video: { path: '/video-tools', tool: 'video-to-video' },
335
+ generate_lipsync: { path: '/video-tools', tool: 'lipsync' },
336
+ generate_music: { path: '/audio-tools', tool: 'music-generator' },
337
+ generate_speech: { path: '/audio-tools', tool: 'text-to-speech' },
338
+ generate_sound: { path: '/audio-tools', tool: 'text-to-sound' },
339
+ transcribe_audio: { path: '/audio-tools', tool: 'speech-to-text' },
340
+ generate_creative_director: { path: '/creative-director' },
341
+ };
342
+
343
+ /**
344
+ * Build the "Open in Kolbo" deep link for a generation's actual session.
345
+ * Returns undefined (widget falls back to app.kolbo.ai) when the tool has no
346
+ * deep-linkable page or the submit response carried no session_id (older
347
+ * kolbo-api, shorts render, 3D).
348
+ */
349
+ function buildOpenUrl(tool, gen) {
350
+ const route = OPEN_URL_ROUTES[tool];
351
+ if (!route || !gen || !gen.session_id) return undefined;
352
+ let url = `${APP_BASE_URL}${route.path}?session=${encodeURIComponent(gen.session_id)}`;
353
+ if (route.tool) url += `&tool=${route.tool}`;
354
+ if (gen.project_id) url += `&project=${encodeURIComponent(gen.project_id)}`;
355
+ return url;
356
+ }
357
+
308
358
  // ─── MCP Apps generation widget helpers ──────────────────────────────────────
309
359
  // When the host renders MCP Apps (claude.ai via the remote connector, Claude
310
360
  // Desktop over stdio), generation tools return IMMEDIATELY after submit and the
@@ -341,6 +391,7 @@ async function uiGenerating(p) {
341
391
  count: p.count || 1,
342
392
  settings: p.settings || {},
343
393
  reference_image: p.reference_image,
394
+ open_url: buildOpenUrl(p.tool, p.gen),
344
395
  };
345
396
  const text = JSON.stringify({
346
397
  status: 'submitted',
@@ -373,6 +424,7 @@ async function uiCompleted(p, textPayload) {
373
424
  duration: p.duration,
374
425
  scenes: p.scenes,
375
426
  credits_used: p.credits_used,
427
+ open_url: buildOpenUrl(p.tool, p.gen),
376
428
  };
377
429
  return uiResult(UI.generation, textPayload, structured);
378
430
  }
@@ -389,6 +441,7 @@ module.exports = {
389
441
  creditFields,
390
442
  projectIdField,
391
443
  inlineImageBlocks,
444
+ buildOpenUrl,
392
445
  uiGenerating,
393
446
  uiCompleted,
394
447
  appsEnabled,
package/src/tools/chat.js CHANGED
@@ -70,15 +70,17 @@ function registerChatTools(server, client) {
70
70
  // ─── chat_list_conversations ───────────────────────────────
71
71
  server.tool(
72
72
  'chat_list_conversations',
73
- 'List your SDK chat conversations, most-recent first. Returns session_id, name, and activity timestamps.',
73
+ 'List the user\'s chat conversations across ALL projects, most-recent first. Returns session_id, name, project_id, and activity timestamps. Pass `project_id` to narrow to one project (resolve names via `list_projects`).',
74
74
  {
75
75
  page: z.number().optional().describe('Page number, 1-indexed. Default: 1'),
76
- limit: z.number().optional().describe('Results per page, max 50. Default: 20')
76
+ limit: z.number().optional().describe('Results per page, max 50. Default: 20'),
77
+ project_id: z.string().optional().describe('Restrict to conversations in one project (Mongo ObjectId from `list_projects`). Omit to list across all projects.')
77
78
  },
78
- async ({ page, limit }) => {
79
+ async ({ page, limit, project_id }) => {
79
80
  const params = new URLSearchParams();
80
81
  if (page) params.set('page', String(page));
81
82
  if (limit) params.set('limit', String(limit));
83
+ if (project_id) params.set('project_id', project_id);
82
84
 
83
85
  const qs = params.toString();
84
86
  const result = await client.get(`/v1/chat/conversations${qs ? '?' + qs : ''}`);
@@ -6,7 +6,7 @@
6
6
  const { z } = require('zod');
7
7
  const FormData = require('form-data');
8
8
  const { pollUntilDone } = require('../polling');
9
- const { resolveToBuffer, creditFields, projectIdField, inlineImageBlocks, uiGenerating, uiCompleted, appsEnabled } = require('./_shared');
9
+ const { resolveToBuffer, creditFields, projectIdField, inlineImageBlocks, buildOpenUrl, uiGenerating, uiCompleted, appsEnabled } = require('./_shared');
10
10
  const { UI, uiResult, canonicalModelId } = require('../apps');
11
11
 
12
12
  function registerGenerateTools(server, client, options = {}) {
@@ -178,7 +178,7 @@ function registerGenerateTools(server, client, options = {}) {
178
178
  // through get_generation_status, so it stays blocking on UI hosts too and
179
179
  // renders the completed scene gallery.
180
180
  if (ui()) return uiCompleted({
181
- tool: 'generate_creative_director', kind: 'scenes', client, model, prompt,
181
+ tool: 'generate_creative_director', kind: 'scenes', gen, client, model, prompt,
182
182
  settings: { duration, resolution, mode: workflow_type }, scenes,
183
183
  credits_used: creditFields(result).credits_used
184
184
  }, cdText);
@@ -839,6 +839,7 @@ function registerGenerateTools(server, client, options = {}) {
839
839
  generation_id: startResponse.generation_id,
840
840
  poll_tool: 'get_generation_status',
841
841
  audio_url: isUrl ? source : undefined,
842
+ open_url: buildOpenUrl('transcribe_audio', startResponse),
842
843
  });
843
844
  }
844
845
 
@@ -16,9 +16,10 @@ function registerMediaTools(server, client, options = {}) {
16
16
  'Upload a local file (or remote URL) to the user\'s Kolbo media library and get back a stable Kolbo CDN URL. Use this when the user wants to reference a local file in multiple subsequent generation calls — upload once, then pass the returned URL to generate_image / generate_video / visual_dna / etc. Auto-detects media type (image / video / audio) from the file extension. For a single-use reference where you already have a public URL, you can skip this and pass the URL directly to the generation tool.',
17
17
  {
18
18
  source: z.string().describe('URL or absolute local path to the file to upload. For local files this is the primary mode; for URLs, this re-hosts the file on Kolbo CDN for stability.'),
19
- description: z.string().optional().describe('Optional description / caption for the uploaded media')
19
+ description: z.string().optional().describe('Optional description / caption for the uploaded media'),
20
+ project_id: z.string().optional().describe('Project ObjectId to file the upload into. Call `list_projects` to resolve a name → id. When the user is working in a named project, pass it here too — omitting it files the upload outside that project.')
20
21
  },
21
- async ({ source, description }) => {
22
+ async ({ source, description, project_id }) => {
22
23
  if (!source) throw new Error('source is required (URL or absolute local path)');
23
24
 
24
25
  // Even for URL input we download-and-reupload — that's the whole point
@@ -32,6 +33,7 @@ function registerMediaTools(server, client, options = {}) {
32
33
  const form = new FormData();
33
34
  form.append('file', resolved.buffer, { filename: resolved.filename, contentType: resolved.contentType });
34
35
  if (description) form.append('description', description);
36
+ if (project_id) form.append('project_id', project_id);
35
37
 
36
38
  const result = await client.postMultipart('/v1/media/upload', form);
37
39
 
@@ -49,7 +51,7 @@ function registerMediaTools(server, client, options = {}) {
49
51
  'list_media',
50
52
  'Browse the user\'s Kolbo media library — both uploaded files AND AI-generated outputs they have saved. Powerful filtering: scope to a single project (`project_id`), a user folder (`folder_id`), a "section" / category (`category`: ai / uploaded / edited / favorites / training-lab), a media type (`type`: image / video / audio), or generation provenance (`source_type`). Combine filters freely. Use this to discover what the user already has before generating something new, to retrieve a specific past creation, or to list everything in a project for downstream batch work.',
51
53
  {
52
- project_id: z.string().optional().describe('Restrict to a single project (Mongo ObjectId). Use `app_builder_list_projects` to discover IDs. Omit to list across all the user\'s media.'),
54
+ project_id: z.string().optional().describe('Restrict to a single project (Mongo ObjectId). Use `list_projects` to discover IDs (NOT `app_builder_list_projects` — that is App Builder only). Omit to list across all the user\'s media.'),
53
55
  folder_id: z.string().optional().describe('Restrict to a user folder (Mongo ObjectId). Discover folder IDs via `list_media_folders`. Takes precedence over project_id when both are set.'),
54
56
  type: z.enum(['image', 'video', 'audio', 'all']).optional().describe('Filter by media type. Default: all types.'),
55
57
  category: z.enum(['ai', 'uploaded', 'edited', 'favorites', 'training-lab', 'all']).optional().describe('Filter by "section" (matches the Kolbo desktop app sidebar): `ai` = AI-generated, `uploaded` = files the user uploaded, `edited` = AI-edited variants, `favorites` = items the user starred, `training-lab` = training-lab assets. Default: all sections.'),
@@ -320,7 +322,7 @@ function registerMediaTools(server, client, options = {}) {
320
322
  'Move a media item to a different project. Caller must own the item AND have access to the target project. Items in shared projects from other members cannot be moved by you. Use this when the user says "move this to project X" or wants to reorganize.',
321
323
  {
322
324
  media_id: z.string().describe('MediaLibraryItem id to move.'),
323
- project_id: z.string().describe('Target project id (use `app_builder_list_projects` to discover ids).')
325
+ project_id: z.string().describe('Target project id (use `list_projects` to discover ids — NOT `app_builder_list_projects`).')
324
326
  },
325
327
  async ({ media_id, project_id }) => {
326
328
  const result = await client.patch(
@@ -9,7 +9,7 @@ function registerProjectTools(server, client) {
9
9
  // ─── list_projects ─────────────────────────────────────────
10
10
  server.tool(
11
11
  'list_projects',
12
- 'List the user\'s projects (owned + shared with edit/full/owner permission). Use this to resolve a project NAME the user mentioned ("put this in my Acme Campaign project") into the project ObjectId you pass back as `project_id` on any generation tool. The tool the user mentions a project by name OR by location, you MUST call this first — the generation tools accept only ObjectIds, not names. Returns id, name, role, and is_default. The project flagged `is_default: true` is the auto-created "API Generations" bucket every SDK generation lands in when project_id is omitted.',
12
+ 'List the user\'s platform projects (owned + shared with edit/full/owner permission). Use this to resolve a project NAME the user mentioned ("put this in my Acme Campaign project") into the project ObjectId you pass back as `project_id` on generation / chat / upload / move tools. Whenever the user mentions a project by name OR location, you MUST call this first — those tools accept only ObjectIds, not names — and then pass the resolved `project_id` on EVERY subsequent call in the conversation (it is per-call, not sticky; omitting it drops work into the default bucket). Returns id, name, role, and is_default. The project flagged `is_default: true` is the auto-created "API Generations" bucket every SDK generation lands in when project_id is omitted. NOT the same as `app_builder_list_projects`, which scopes App Builder coding sessions only.',
13
13
  {},
14
14
  async () => {
15
15
  const result = await client.get('/v1/projects');
@@ -31,6 +31,31 @@ function registerProjectTools(server, client) {
31
31
  };
32
32
  }
33
33
  );
34
+
35
+ // ─── move_session ──────────────────────────────────────────
36
+ server.tool(
37
+ 'move_session',
38
+ 'Move a session — and ALL of its media library items — to another project. Works for any session type: generation sessions (the `session_id` returned by generate_* tools), chat conversations, transcription sessions, etc. Use this when work landed in the wrong project (e.g. the default "API Generations" bucket) and the user wants it in a named project — moving is always better than regenerating. Caller must own the session and have edit/full/owner permission on the target project. Resolve the target project id with `list_projects` first.',
39
+ {
40
+ session_id: z.string().describe('The session ObjectId to move (from a generation submit response, chat_list_conversations, or an "Open in Kolbo" link).'),
41
+ project_id: z.string().describe('Target project ObjectId. Call `list_projects` to resolve a project name to its id.'),
42
+ type: z.string().optional().describe('Optional session type hint to speed up the lookup: image, video, video_from_image, music, speech, sound, image_edit, creative_director, chat, elements, first_last_frame, lipsync, video_from_video, transcription, global_image_edit, global_video_edit, shorts. Omit if unsure — the server probes all types.')
43
+ },
44
+ async ({ session_id, project_id, type }) => {
45
+ const body = { project_id };
46
+ if (type) body.type = type;
47
+ const result = await client.patch(`/v1/sessions/${encodeURIComponent(session_id)}/project`, body);
48
+ return {
49
+ content: [{
50
+ type: 'text',
51
+ text: JSON.stringify({
52
+ session: result.session,
53
+ _hint: 'The session and its media now live in the new project. Future generations still need `project_id` passed explicitly on each call.'
54
+ }, null, 2)
55
+ }]
56
+ };
57
+ }
58
+ );
34
59
  }
35
60
 
36
61
  module.exports = { registerProjectTools };