@kolbo/mcp 1.47.0 → 1.48.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/package.json +1 -1
- package/src/tools/_shared.js +9 -0
- package/src/tools/moodboards.js +5 -2
- package/src/tools/visual_dna.js +11 -7
package/package.json
CHANGED
package/src/tools/_shared.js
CHANGED
|
@@ -254,6 +254,14 @@ const projectIdField = z.string().optional().describe(
|
|
|
254
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
|
+
// Read-scope variant for list/get tools that can surface a SHARED project's
|
|
258
|
+
// assets (a teammate's Visual DNAs / moodboards). Pass a project id you have
|
|
259
|
+
// edit+ on to also see that project owner's shared assets; omit to see only your
|
|
260
|
+
// own + global/org. View-only members and non-members get nothing extra.
|
|
261
|
+
const projectScopeReadField = z.string().optional().describe(
|
|
262
|
+
"Project ObjectId (from `list_projects`) to ALSO surface that shared project's assets (a teammate's, when the project is shared with you). Requires edit / full / owner on the project — view-only members and non-members get only their own. Omit to see just your own + global/org."
|
|
263
|
+
);
|
|
264
|
+
|
|
257
265
|
// ─── Optional inline-image content blocks ────────────────────────────────────
|
|
258
266
|
// When a host opts in (the remote HTTP connector sets inlineImages:true), turn
|
|
259
267
|
// generated IMAGE urls into MCP `image` content blocks so clients render them
|
|
@@ -440,6 +448,7 @@ module.exports = {
|
|
|
440
448
|
resolveToBuffer,
|
|
441
449
|
creditFields,
|
|
442
450
|
projectIdField,
|
|
451
|
+
projectScopeReadField,
|
|
443
452
|
inlineImageBlocks,
|
|
444
453
|
buildOpenUrl,
|
|
445
454
|
uiGenerating,
|
package/src/tools/moodboards.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { z } = require('zod');
|
|
7
7
|
const { UI, uiResult, appsEnabled } = require('../apps');
|
|
8
|
+
const { projectScopeReadField } = require('./_shared');
|
|
8
9
|
|
|
9
10
|
function registerMoodboardTools(server, client, options = {}) {
|
|
10
11
|
const ui = () => appsEnabled(server, options);
|
|
@@ -13,11 +14,13 @@ function registerMoodboardTools(server, client, options = {}) {
|
|
|
13
14
|
'list_moodboards',
|
|
14
15
|
'List moodboards. By default returns ALL (personal + system presets + organization). Use "scope" to filter: "personal" (user\'s own), "preset" or "global" (system presets), or "organization" (org-shared). Returns id, name, master_prompt, thumbnail, and image URLs for each.',
|
|
15
16
|
{
|
|
16
|
-
scope: z.enum(['all', 'personal', 'preset', 'global', 'organization']).optional().describe('Filter by scope. Default: "all" (everything accessible). "personal" = only your own. "preset"/"global" = system presets. "organization" = org-shared.')
|
|
17
|
+
scope: z.enum(['all', 'personal', 'preset', 'global', 'organization']).optional().describe('Filter by scope. Default: "all" (everything accessible). "personal" = only your own. "preset"/"global" = system presets. "organization" = org-shared.'),
|
|
18
|
+
project_id: projectScopeReadField
|
|
17
19
|
},
|
|
18
|
-
async ({ scope } = {}) => {
|
|
20
|
+
async ({ scope, project_id } = {}) => {
|
|
19
21
|
const params = new URLSearchParams();
|
|
20
22
|
if (scope && scope !== 'all') params.set('scope', scope);
|
|
23
|
+
if (project_id) params.set('project_id', project_id);
|
|
21
24
|
const qs = params.toString();
|
|
22
25
|
const result = await client.get(`/v1/moodboards${qs ? '?' + qs : ''}`);
|
|
23
26
|
const moodboards = result.moodboards || [];
|
package/src/tools/visual_dna.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { z } = require('zod');
|
|
7
7
|
const FormData = require('form-data');
|
|
8
|
-
const { resolveToBuffer: sharedResolveToBuffer, VISUAL_DNA_MAX_BYTES } = require('./_shared');
|
|
8
|
+
const { resolveToBuffer: sharedResolveToBuffer, VISUAL_DNA_MAX_BYTES, projectScopeReadField } = require('./_shared');
|
|
9
9
|
const { UI, uiResult, appsEnabled } = require('../apps');
|
|
10
10
|
|
|
11
11
|
// Visual DNA caps reference media at 25MB per file (stricter than the
|
|
@@ -85,14 +85,16 @@ function registerVisualDnaTools(server, client, options = {}) {
|
|
|
85
85
|
scope: z.enum(['all', 'personal', 'global', 'organization']).optional().describe('Filter by scope. Default: "all" (everything accessible). "personal" = only your own. "global" = system presets/cast. "organization" = org-shared.'),
|
|
86
86
|
search: z.string().optional().describe('Search by name, tags, or description (case-insensitive)'),
|
|
87
87
|
collection: z.string().optional().describe('Filter global presets by collection: cast, influencers, props, locations, styles, glamour, street'),
|
|
88
|
-
tags: z.string().optional().describe('Comma-separated tags to filter by (OR logic)')
|
|
88
|
+
tags: z.string().optional().describe('Comma-separated tags to filter by (OR logic)'),
|
|
89
|
+
project_id: projectScopeReadField
|
|
89
90
|
},
|
|
90
|
-
async ({ scope, search, collection, tags } = {}) => {
|
|
91
|
+
async ({ scope, search, collection, tags, project_id } = {}) => {
|
|
91
92
|
const params = new URLSearchParams();
|
|
92
93
|
if (scope && scope !== 'all') params.set('scope', scope);
|
|
93
94
|
if (search) params.set('search', search);
|
|
94
95
|
if (collection) params.set('collection', collection);
|
|
95
96
|
if (tags) params.set('tags', tags);
|
|
97
|
+
if (project_id) params.set('project_id', project_id);
|
|
96
98
|
const qs = params.toString();
|
|
97
99
|
const result = await client.get(`/v1/visual-dna${qs ? '?' + qs : ''}`);
|
|
98
100
|
const dnas = result.visual_dnas || [];
|
|
@@ -125,12 +127,14 @@ function registerVisualDnaTools(server, client, options = {}) {
|
|
|
125
127
|
// ─── get_visual_dna ────────────────────────────────────────
|
|
126
128
|
server.tool(
|
|
127
129
|
'get_visual_dna',
|
|
128
|
-
'Fetch a single Visual DNA profile by ID. Returns the full profile including system_prompt and all reference images.',
|
|
130
|
+
'Fetch a single Visual DNA profile by ID. Returns the full profile including system_prompt and all reference images. To fetch a teammate\'s Visual DNA that lives in a shared project, pass project_id (you need edit+ on it).',
|
|
129
131
|
{
|
|
130
|
-
visual_dna_id: z.string().describe('The Visual DNA profile ID')
|
|
132
|
+
visual_dna_id: z.string().describe('The Visual DNA profile ID'),
|
|
133
|
+
project_id: projectScopeReadField
|
|
131
134
|
},
|
|
132
|
-
async ({ visual_dna_id }) => {
|
|
133
|
-
const
|
|
135
|
+
async ({ visual_dna_id, project_id }) => {
|
|
136
|
+
const suffix = project_id ? `?project_id=${encodeURIComponent(project_id)}` : '';
|
|
137
|
+
const result = await client.get(`/v1/visual-dna/${encodeURIComponent(visual_dna_id)}` + suffix);
|
|
134
138
|
return {
|
|
135
139
|
content: [{
|
|
136
140
|
type: 'text',
|