@kolbo/mcp 1.31.7 → 1.33.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 +252 -250
- package/package.json +1 -1
- package/skill/GENERATED.md +1 -1
- package/skill/SKILL.md +8 -5
- package/skill/references/workflows/cost-and-validation.md +2 -0
- package/skill/references/workflows/troubleshooting.md +4 -0
- package/src/index.js +15 -0
- package/src/tools/_shared.js +2 -2
- package/src/tools/chat.js +5 -3
- package/src/tools/docs.js +119 -0
- package/src/tools/generate.js +60 -6
- package/src/tools/media.js +6 -4
- package/src/tools/projects.js +26 -1
package/README.md
CHANGED
|
@@ -1,250 +1,252 @@
|
|
|
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
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
- [
|
|
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
|
+
| `create_doc` / `list_docs` / `get_doc` / `update_doc` / `share_doc` / `delete_doc` | AI Docs (Magic Pad): author project-scoped HTML documents, edit them, get public share links |
|
|
236
|
+
| `check_credits` | Check credit balance |
|
|
237
|
+
| `get_generation_status` | Check one or many generations (`generation_ids`); `wait=true` blocks server-side until done — replaces client polling loops |
|
|
238
|
+
|
|
239
|
+
## Environment Variables
|
|
240
|
+
|
|
241
|
+
Both are optional — the local install logs in via the browser on first use.
|
|
242
|
+
|
|
243
|
+
| Variable | Required | Description |
|
|
244
|
+
|----------|----------|-------------|
|
|
245
|
+
| `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)). |
|
|
246
|
+
| `KOLBO_API_URL` | No | Custom API URL (default: `https://api.kolbo.ai/api`) |
|
|
247
|
+
|
|
248
|
+
## Links
|
|
249
|
+
|
|
250
|
+
- [API Documentation](https://docs.kolbo.ai/developer-api)
|
|
251
|
+
- [Kolbo AI Platform](https://kolbo.ai)
|
|
252
|
+
- [Get API Key](https://app.kolbo.ai)
|
package/package.json
CHANGED
package/skill/GENERATED.md
CHANGED
|
@@ -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@
|
|
4
|
+
by .github/workflows/sync-skill-to-plugin.yml — synced from kolbo-code@17e585e.
|
|
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
|
@@ -35,7 +35,7 @@ Once per conversation, before any other Kolbo tool call:
|
|
|
35
35
|
|
|
36
36
|
1. **Run `check_credits`.** If it fails with "Session expired" / "Not authenticated", ask the user to run `kolbo auth login` (or their branded CLI command like `sapir auth login`) and reload the editor.
|
|
37
37
|
2. **If `list_models` returns empty**, MCP isn't wired — same fix.
|
|
38
|
-
3.
|
|
38
|
+
3. Use the balance ONLY for the low-balance check at this moment. **Never quote a "credits remaining" number later in the session** — coding/chat usage also deducts credits, so any remembered or computed balance is stale. Report only what each generation cost (`credits_used`); if the user asks what's left, run `check_credits` fresh right then.
|
|
39
39
|
|
|
40
40
|
If the user is on a whitelabel build (`sapir`, etc.), they must use their branded command — not `kolbo`. See `references/workflows/troubleshooting.md`.
|
|
41
41
|
|
|
@@ -154,8 +154,9 @@ A user-named tool — in any language — overrides every other rule. Recognized
|
|
|
154
154
|
- Auto-select → only from "Auto-selectable" section (models with a `summary`). Cheapest fit. Prefer `[RECOMMENDED]` when cost is similar.
|
|
155
155
|
- Never auto-select from "Named-only" section.
|
|
156
156
|
4. **Validate inputs** against model caps — see `references/workflows/cost-and-validation.md`.
|
|
157
|
-
5. **How calls work**: each tool blocks until generation is fully complete. Images: seconds. Video: minutes. Multiple tool calls in one response run concurrently.
|
|
158
|
-
6. **
|
|
157
|
+
5. **How calls work**: each tool blocks until generation is fully complete. Images: seconds. Video: minutes. Multiple tool calls in one response run concurrently. On hosts with live widgets the tool instead returns `submitted` instantly — the card updates on its own; you only need `get_generation_status` when a follow-up step needs the output URLs.
|
|
158
|
+
6. **Checking status — NEVER poll in a loop**: `get_generation_status` takes `wait=true` (blocks server-side until done, ~3 min) and `generation_ids` (check MANY generations in ONE call — returns `all_done` + which are still running). One `wait=true` call replaces any polling loop. If it comes back with some still processing, call it ONCE more with `wait=true` and the remaining ids.
|
|
159
|
+
7. **Share the URL** after success. Never fabricate URLs.
|
|
159
160
|
|
|
160
161
|
Model types for `list_models`: `text_to_img`, `image_editing`, `text_to_video`, `img_to_video`, `draw_to_video`, `video_to_video`, `elements`, `firstlastgenerations`, `lipsync-image`, `lipsync-video`, `music_gen`, `text_to_speech`, `text_to_sound`, `stt`, `text`, `3d_text_to_model`, `3d_image_to_model`, `3d_multi_image_to_model`, `3d_world`.
|
|
161
162
|
|
|
@@ -167,11 +168,13 @@ Full tables + formulas in `references/workflows/cost-and-validation.md`. Quick r
|
|
|
167
168
|
- **Otherwise confirm** via the labeled-question card: the parameters + the credit cost, suggest a cheaper alternative if one fits, wait for the user's pick. Never fire on defaults the user didn't choose.
|
|
168
169
|
- **Batch totalling 100+ credits**: run `check_credits` first.
|
|
169
170
|
- **Quote real cost**: after firing, log `credits_used` (from the tool result) to `.kolbo/production.md` — never `base × count`.
|
|
171
|
+
- **Never state "credits remaining" from arithmetic** (opening balance − generation costs). Coding/chat usage deducts credits too, so the math is always wrong. Report cost only; if the user asks for their balance, call `check_credits` fresh at that moment.
|
|
170
172
|
|
|
171
173
|
## Rate Limiting & Batch Generation
|
|
172
174
|
|
|
173
175
|
- `generate_image`: 30/min. All other generation tools: 10/min per type. 300/min global. `upload_media`: 300/min, no credit cost.
|
|
174
|
-
- **⚠️ NEVER re-fire a generation you already called.** Aborted / timed-out calls still process server-side. Run `get_generation_status` before retrying.
|
|
176
|
+
- **⚠️ NEVER re-fire a generation you already called.** Aborted / timed-out calls still process server-side. Run `get_generation_status` (with `wait=true`) before retrying.
|
|
177
|
+
- **Tracking a batch**: check ALL in-flight ids in ONE `get_generation_status` call with `generation_ids` + `wait=true`. Read `all_done` / `still_processing` from the response — do not check ids one by one, and never re-call without `wait`.
|
|
175
178
|
- **Batch ≤10 items**: output ALL tool calls in one response — they run concurrently.
|
|
176
179
|
- **Bulk >10 items**: real-world ceilings — `generate_image` 8–10 in-flight, image-edit 5–8, video tools 3–5, `generate_video_from_video` 3, music/speech/sound 5–8. Fire one batch → wait → fire next. Persist every `generation_id` in `.kolbo/production.md`.
|
|
177
180
|
- **`upload_media` external URLs first.** `files`/`source_images`/`image_url` only accept Kolbo-hosted URLs reliably; external URLs cause `400`.
|
|
@@ -224,7 +227,7 @@ A generation can fail three ways. Treat ALL as failure:
|
|
|
224
227
|
|
|
225
228
|
1. **Tool returns `error`** — explicit. Surface, suggest retry, log `generation_id`.
|
|
226
229
|
2. **Tool returns `completed` but `urls` is empty** — silent failure (NSFW filter, model OOM, upstream 5xx). Tell user "completed without an output — retrying" and re-fire ONCE. Do NOT log to `.kolbo/production.md`. Do NOT claim it worked.
|
|
227
|
-
3. **Tool hangs / never returns** — MCP poll timed out. Call `get_generation_status(generation_id)` IMMEDIATELY. The server might be done.
|
|
230
|
+
3. **Tool hangs / never returns** — MCP poll timed out. Call `get_generation_status(generation_id, wait=true)` IMMEDIATELY. The server might be done.
|
|
228
231
|
|
|
229
232
|
**Always:**
|
|
230
233
|
- Don't celebrate before reading the result. Verify `urls` is non-empty.
|
|
@@ -48,6 +48,8 @@ Apply when confirming cost before firing:
|
|
|
48
48
|
|
|
49
49
|
**Batch totalling 100+ credits:** run `check_credits` first and include the available balance in the summary.
|
|
50
50
|
|
|
51
|
+
**After generating, report cost only — never "credits remaining".** Coding/chat usage also deducts credits, so any balance you compute (opening balance − generation costs) is wrong by the time you say it. Quote `credits_used` per generation / batch total; if the user asks what's left, run `check_credits` fresh at that moment and quote that number.
|
|
52
|
+
|
|
51
53
|
## ⚠️ Quote Real Cost, Never Estimates (CRITICAL)
|
|
52
54
|
|
|
53
55
|
Pre-flight formulas above are for **preview only**. After firing, every generation returns `credits_used` (multiplier-adjusted total) and `credits_breakdown` (per-model attribution).
|
|
@@ -30,6 +30,10 @@ This re-wires the MCP configuration automatically. Then restart the session.
|
|
|
30
30
|
|
|
31
31
|
Wait 60s for the window to reset, retry only the failed calls. For batch image work prefer `generate_creative_director` over multiple `generate_image` calls. Full rate-limit details + retry sequence: see SKILL.md "Rate Limiting & Batch Generation".
|
|
32
32
|
|
|
33
|
+
## Checking generation status without spinning
|
|
34
|
+
|
|
35
|
+
`get_generation_status` supports `wait=true` (blocks server-side until the generation reaches a final state, up to ~3 min) and `generation_ids` (many ids in one call → returns `all_done`, `still_processing`, and per-generation results). **Never call it repeatedly in a loop** — one `wait=true` call replaces the loop. If some generations are still running after the wait window, call it ONCE more with `wait=true` and only the `still_processing` ids.
|
|
36
|
+
|
|
33
37
|
## Failure envelope from `get_generation_status`
|
|
34
38
|
|
|
35
39
|
When a generation fails, `get_generation_status` returns a structured `failure` field alongside `error`:
|
package/src/index.js
CHANGED
|
@@ -69,6 +69,7 @@ const { registerPresetTools } = require('./tools/presets');
|
|
|
69
69
|
const { registerAppBuilderTools } = require('./tools/app_builder');
|
|
70
70
|
const { registerArtifactTools } = require('./tools/artifacts');
|
|
71
71
|
const { registerProjectTools } = require('./tools/projects');
|
|
72
|
+
const { registerDocTools } = require('./tools/docs');
|
|
72
73
|
const { registerVoiceTools } = require('./tools/voices');
|
|
73
74
|
const { registerMusicLibraryTools } = require('./tools/music_library');
|
|
74
75
|
const { registerStockLibraryTools } = require('./tools/stock_library');
|
|
@@ -103,6 +104,19 @@ function createServer(opts = {}) {
|
|
|
103
104
|
// Connector avatar for hosts that render server icons (claude.ai tool
|
|
104
105
|
// headers show this instead of a letter monogram).
|
|
105
106
|
icons: [{ src: 'https://api.kolbo.ai/assets/kolbo-ai.png', mimeType: 'image/png', sizes: ['512x512'] }]
|
|
107
|
+
}, {
|
|
108
|
+
// Server-level instructions surfaced to the host model on initialize.
|
|
109
|
+
// The single most common failure mode is project confusion — spell out
|
|
110
|
+
// the project contract here so every client gets it without a skill file.
|
|
111
|
+
instructions: [
|
|
112
|
+
'PROJECT CONTRACT (read this before generating anything):',
|
|
113
|
+
'Everything in Kolbo lives inside a PROJECT — sessions, generations, and media are all project-scoped.',
|
|
114
|
+
'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.',
|
|
115
|
+
'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.',
|
|
116
|
+
'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.',
|
|
117
|
+
'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.',
|
|
118
|
+
'5. Written deliverables (plans, briefs, scripts, research summaries) can live in Kolbo too: author them as AI Docs with `create_doc` (project-scoped, editable in the app, shareable via `share_doc`).'
|
|
119
|
+
].join('\n')
|
|
106
120
|
});
|
|
107
121
|
|
|
108
122
|
// Register all tools. `inlineImages` (off by default) is opt-in: only the
|
|
@@ -121,6 +135,7 @@ function createServer(opts = {}) {
|
|
|
121
135
|
registerAppBuilderTools(server, client, toolOptions);
|
|
122
136
|
registerArtifactTools(server, client, toolOptions);
|
|
123
137
|
registerProjectTools(server, client, toolOptions);
|
|
138
|
+
registerDocTools(server, client, toolOptions);
|
|
124
139
|
registerMusicLibraryTools(server, client, toolOptions);
|
|
125
140
|
registerStockLibraryTools(server, client, toolOptions);
|
|
126
141
|
registerShortsCreatorTools(server, client, toolOptions);
|
package/src/tools/_shared.js
CHANGED
|
@@ -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).
|
|
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 ────────────────────────────────────
|
|
@@ -396,7 +396,7 @@ async function uiGenerating(p) {
|
|
|
396
396
|
const text = JSON.stringify({
|
|
397
397
|
status: 'submitted',
|
|
398
398
|
generation_id: p.gen.generation_id,
|
|
399
|
-
_widget_note: 'A live Kolbo widget is rendering this generation for the user (progress + final result + action buttons). Tell the user it is generating and the card above will update — do NOT poll in a loop. If you
|
|
399
|
+
_widget_note: 'A live Kolbo widget is rendering this generation for the user (progress + final result + action buttons). Tell the user it is generating and the card above will update — do NOT poll in a loop. If you need the output URLs (e.g. for a follow-up edit or a report), call get_generation_status ONCE with wait=true — it blocks until done. Tracking several generations? Pass ALL their ids in generation_ids in that one call.',
|
|
400
400
|
}, null, 2);
|
|
401
401
|
return uiResult(UI.generation, text, structured);
|
|
402
402
|
}
|
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
|
|
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 : ''}`);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* ⛔ BACKWARD COMPATIBILITY: Tool names and arg names below are a PUBLIC
|
|
2
|
+
* CONTRACT. Never rename, remove, or break an existing tool/arg — old cached
|
|
3
|
+
* `npx @kolbo/mcp` installs in the wild will break silently. Add new tools or
|
|
4
|
+
* new OPTIONAL args only. Full rules: ../index.js top-of-file and CLAUDE.md. */
|
|
5
|
+
|
|
6
|
+
const { z } = require('zod');
|
|
7
|
+
const { projectIdField } = require('./_shared');
|
|
8
|
+
|
|
9
|
+
const CONTENT_GUIDE = 'HTML body content. Use clean semantic HTML the in-app editor understands: <h1>-<h3>, <p>, <ul>/<ol>/<li>, <table>, <blockquote>, <strong>/<em>, <a>. No <script>/<style>/<iframe> (stripped server-side). Write the FULL document yourself — this is where you author the doc.';
|
|
10
|
+
|
|
11
|
+
function registerDocTools(server, client) {
|
|
12
|
+
// ─── create_doc ────────────────────────────────────────────
|
|
13
|
+
server.tool(
|
|
14
|
+
'create_doc',
|
|
15
|
+
'Create an AI Doc (Magic Pad document) in the user\'s Kolbo workspace. YOU author the document: write complete, well-structured HTML content (plans, briefs, scripts, research summaries, meeting notes…) and save it here so the user can read and edit it in the Kolbo app. Docs are project-scoped — when the user is working in a named project, resolve it with `list_projects` and pass `project_id`. Returns the doc id; use `share_doc` afterwards if the user wants a public link.',
|
|
16
|
+
{
|
|
17
|
+
title: z.string().describe('Document title (shown in the app sidebar).'),
|
|
18
|
+
content: z.string().describe(CONTENT_GUIDE),
|
|
19
|
+
project_id: projectIdField
|
|
20
|
+
},
|
|
21
|
+
async ({ title, content, project_id }) => {
|
|
22
|
+
const body = { title, content };
|
|
23
|
+
if (project_id) body.project_id = project_id;
|
|
24
|
+
const result = await client.post('/v1/docs', body);
|
|
25
|
+
return {
|
|
26
|
+
content: [{
|
|
27
|
+
type: 'text',
|
|
28
|
+
text: JSON.stringify({
|
|
29
|
+
doc: result.doc,
|
|
30
|
+
_hint: 'Doc created. The user can open it in the Kolbo app under the project\'s AI Docs. Call share_doc with shared:true to get a public link.'
|
|
31
|
+
}, null, 2)
|
|
32
|
+
}]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// ─── list_docs ─────────────────────────────────────────────
|
|
38
|
+
server.tool(
|
|
39
|
+
'list_docs',
|
|
40
|
+
'List the user\'s AI Docs (Magic Pad documents) across all projects, most recently updated first. Pass `project_id` (from `list_projects`) to narrow to one project. Returns id, title, project_id, share state, and timestamps — use `get_doc` to read a doc\'s content.',
|
|
41
|
+
{
|
|
42
|
+
project_id: z.string().optional().describe('Restrict to docs in one project (ObjectId from `list_projects`). Omit to list across all projects.'),
|
|
43
|
+
page: z.number().optional().describe('Page number, 1-indexed. Default: 1'),
|
|
44
|
+
limit: z.number().optional().describe('Results per page, max 50. Default: 20')
|
|
45
|
+
},
|
|
46
|
+
async ({ project_id, page, limit }) => {
|
|
47
|
+
const params = new URLSearchParams();
|
|
48
|
+
if (project_id) params.set('project_id', project_id);
|
|
49
|
+
if (page) params.set('page', String(page));
|
|
50
|
+
if (limit) params.set('limit', String(limit));
|
|
51
|
+
const qs = params.toString();
|
|
52
|
+
const result = await client.get(`/v1/docs${qs ? '?' + qs : ''}`);
|
|
53
|
+
return { content: [{ type: 'text', text: JSON.stringify({ docs: result.docs || [], pagination: result.pagination || null }, null, 2) }] };
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// ─── get_doc ───────────────────────────────────────────────
|
|
58
|
+
server.tool(
|
|
59
|
+
'get_doc',
|
|
60
|
+
'Fetch one AI Doc including its full HTML content. Use before editing an existing doc (read → modify → `update_doc`).',
|
|
61
|
+
{
|
|
62
|
+
doc_id: z.string().describe('The doc ObjectId (from create_doc or list_docs).')
|
|
63
|
+
},
|
|
64
|
+
async ({ doc_id }) => {
|
|
65
|
+
const result = await client.get(`/v1/docs/${encodeURIComponent(doc_id)}`);
|
|
66
|
+
return { content: [{ type: 'text', text: JSON.stringify(result.doc, null, 2) }] };
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// ─── update_doc ────────────────────────────────────────────
|
|
71
|
+
server.tool(
|
|
72
|
+
'update_doc',
|
|
73
|
+
'Update an AI Doc\'s title and/or content. Content REPLACES the whole document — call `get_doc` first, apply the user\'s edits to the full HTML, and send the complete result back.',
|
|
74
|
+
{
|
|
75
|
+
doc_id: z.string().describe('The doc ObjectId to update.'),
|
|
76
|
+
title: z.string().optional().describe('New title. Omit to keep the current one.'),
|
|
77
|
+
content: z.string().optional().describe('Full replacement ' + CONTENT_GUIDE)
|
|
78
|
+
},
|
|
79
|
+
async ({ doc_id, title, content }) => {
|
|
80
|
+
const body = {};
|
|
81
|
+
if (title !== undefined) body.title = title;
|
|
82
|
+
if (content !== undefined) body.content = content;
|
|
83
|
+
const result = await client.put(`/v1/docs/${encodeURIComponent(doc_id)}`, body);
|
|
84
|
+
return { content: [{ type: 'text', text: JSON.stringify(result.doc, null, 2) }] };
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// ─── share_doc ─────────────────────────────────────────────
|
|
89
|
+
server.tool(
|
|
90
|
+
'share_doc',
|
|
91
|
+
'Enable or disable public sharing of an AI Doc. When enabling, returns a stable public link (app.kolbo.ai/shared/magicpad/…) anyone can open — give it to the user. Set `editable` to also let link visitors edit the doc.',
|
|
92
|
+
{
|
|
93
|
+
doc_id: z.string().describe('The doc ObjectId.'),
|
|
94
|
+
shared: z.boolean().describe('true = publicly shared, false = private again (the link stops working).'),
|
|
95
|
+
editable: z.boolean().optional().describe('Whether link visitors can edit. Default: unchanged (false for new shares).')
|
|
96
|
+
},
|
|
97
|
+
async ({ doc_id, shared, editable }) => {
|
|
98
|
+
const body = { shared };
|
|
99
|
+
if (editable !== undefined) body.editable = editable;
|
|
100
|
+
const result = await client.patch(`/v1/docs/${encodeURIComponent(doc_id)}/share`, body);
|
|
101
|
+
return { content: [{ type: 'text', text: JSON.stringify(result.doc, null, 2) }] };
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// ─── delete_doc ────────────────────────────────────────────
|
|
106
|
+
server.tool(
|
|
107
|
+
'delete_doc',
|
|
108
|
+
'Delete an AI Doc (soft delete — recoverable from the app\'s trash flow). Owner only. Confirm with the user before deleting anything they did not just create in this conversation.',
|
|
109
|
+
{
|
|
110
|
+
doc_id: z.string().describe('The doc ObjectId to delete.')
|
|
111
|
+
},
|
|
112
|
+
async ({ doc_id }) => {
|
|
113
|
+
const result = await client.delete(`/v1/docs/${encodeURIComponent(doc_id)}`);
|
|
114
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = { registerDocTools };
|
package/src/tools/generate.js
CHANGED
|
@@ -418,17 +418,71 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
418
418
|
// ─── get_generation_status ─────────────────────────────────
|
|
419
419
|
server.tool(
|
|
420
420
|
'get_generation_status',
|
|
421
|
-
'Check the status of
|
|
421
|
+
'Check the status of one or more generations. Use after a generation tool returned "submitted" (widget hosts) or timed out. Tracking SEVERAL concurrent generations? Pass them ALL in generation_ids — one call returns an all_done summary. Need the final result? Set wait=true and the server blocks until every generation finishes (up to ~3 min). NEVER call this tool repeatedly in a loop — one wait=true call replaces the whole loop.',
|
|
422
422
|
{
|
|
423
|
-
generation_id: z.string().describe('
|
|
423
|
+
generation_id: z.string().optional().describe('A single generation ID to check'),
|
|
424
|
+
generation_ids: z.array(z.string()).optional().describe('Multiple generation IDs to check in ONE call. Returns { all_done, pending, generations[] } — always prefer this over checking IDs one by one.'),
|
|
425
|
+
wait: z.boolean().optional().describe('If true, block until every generation reaches a terminal state (completed/failed), up to ~3 minutes, then return the final results. Use this instead of re-calling the tool in a loop.')
|
|
424
426
|
},
|
|
425
|
-
async ({ generation_id }) => {
|
|
426
|
-
const
|
|
427
|
+
async ({ generation_id, generation_ids, wait }) => {
|
|
428
|
+
const ids = (generation_ids && generation_ids.length > 0)
|
|
429
|
+
? generation_ids
|
|
430
|
+
: (generation_id ? [generation_id] : []);
|
|
431
|
+
if (ids.length === 0) throw new Error('Provide generation_id or generation_ids');
|
|
432
|
+
|
|
433
|
+
// One status check (or blocking poll) per id. Never let one bad id
|
|
434
|
+
// reject the whole batch — surface it as a failed entry instead.
|
|
435
|
+
const checkOne = async (id) => {
|
|
436
|
+
try {
|
|
437
|
+
if (wait) {
|
|
438
|
+
const result = await pollUntilDone(client, id, { interval: 5000, timeout: 180000 });
|
|
439
|
+
return { generation_id: id, ...result };
|
|
440
|
+
}
|
|
441
|
+
const result = await client.get(`/v1/generate/${encodeURIComponent(id)}/status`);
|
|
442
|
+
return { generation_id: id, ...result };
|
|
443
|
+
} catch (err) {
|
|
444
|
+
if (err.timedOut) {
|
|
445
|
+
return { generation_id: id, state: 'processing', note: 'Still running after 3 min of waiting — call get_generation_status again with wait=true.' };
|
|
446
|
+
}
|
|
447
|
+
if (err.name === 'GenerationFailedError') {
|
|
448
|
+
return { generation_id: id, state: 'failed', error: err.message };
|
|
449
|
+
}
|
|
450
|
+
return { generation_id: id, state: 'unknown', error: err.message };
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const results = await Promise.all(ids.map(checkOne));
|
|
455
|
+
|
|
456
|
+
const pending = results.filter(r => r.state !== 'completed' && r.state !== 'failed' && r.state !== 'cancelled');
|
|
457
|
+
const doneHint = 'ALL generations are in a final state — do NOT poll again. Report the results to the user.';
|
|
458
|
+
const pendingHint = wait
|
|
459
|
+
? 'Some generations are still running after the wait window. Call get_generation_status ONCE more with wait=true and the remaining generation_ids — do not spin without wait.'
|
|
460
|
+
: 'Some generations are still processing. Do NOT re-call this tool in a loop — call it ONCE with wait=true (and all pending generation_ids) to block until they finish.';
|
|
461
|
+
|
|
462
|
+
// Single-id calls keep the original flat shape — the generation widget
|
|
463
|
+
// polls this tool with { generation_id } and reads state/result at the
|
|
464
|
+
// top level.
|
|
465
|
+
if (!generation_ids || generation_ids.length === 0) {
|
|
466
|
+
const single = results[0];
|
|
467
|
+
single._hint = pending.length === 0
|
|
468
|
+
? 'This generation is in a FINAL state — do not poll it again.'
|
|
469
|
+
: pendingHint;
|
|
470
|
+
return {
|
|
471
|
+
content: [{ type: 'text', text: JSON.stringify(single, null, 2) }]
|
|
472
|
+
};
|
|
473
|
+
}
|
|
427
474
|
|
|
428
475
|
return {
|
|
429
476
|
content: [{
|
|
430
477
|
type: 'text',
|
|
431
|
-
text: JSON.stringify(
|
|
478
|
+
text: JSON.stringify({
|
|
479
|
+
all_done: pending.length === 0,
|
|
480
|
+
completed: results.filter(r => r.state === 'completed').length,
|
|
481
|
+
failed: results.filter(r => r.state === 'failed' || r.state === 'cancelled').length,
|
|
482
|
+
still_processing: pending.map(r => r.generation_id),
|
|
483
|
+
_hint: pending.length === 0 ? doneHint : pendingHint,
|
|
484
|
+
generations: results
|
|
485
|
+
}, null, 2)
|
|
432
486
|
}]
|
|
433
487
|
};
|
|
434
488
|
}
|
|
@@ -833,7 +887,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
833
887
|
return uiResult(UI.transcript, JSON.stringify({
|
|
834
888
|
status: 'submitted',
|
|
835
889
|
generation_id: startResponse.generation_id,
|
|
836
|
-
_widget_note: 'A live Kolbo transcription widget is rendering above — it shows progress, the transcript text, and SRT/TXT download buttons. Tell the user it is transcribing. If you need the transcript text for a follow-up step, call get_generation_status with this generation_id
|
|
890
|
+
_widget_note: 'A live Kolbo transcription widget is rendering above — it shows progress, the transcript text, and SRT/TXT download buttons. Tell the user it is transcribing. If you need the transcript text for a follow-up step, call get_generation_status ONCE with this generation_id and wait=true — it blocks until done; do NOT poll in a loop.',
|
|
837
891
|
}, null, 2), {
|
|
838
892
|
widget: 'transcript', phase: 'generating',
|
|
839
893
|
generation_id: startResponse.generation_id,
|
package/src/tools/media.js
CHANGED
|
@@ -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 `
|
|
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 `
|
|
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(
|
package/src/tools/projects.js
CHANGED
|
@@ -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
|
|
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 };
|