@kolbo/mcp 1.30.3 → 1.30.5
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/apps/index.js +36 -11
- package/src/apps/widgets/generation.js +1 -1
- package/src/index.js +6 -1
package/package.json
CHANGED
package/src/apps/index.js
CHANGED
|
@@ -48,16 +48,29 @@ function widgetHtml(uri) {
|
|
|
48
48
|
// img/script/style/font/media-src; connectDomains to connect-src.
|
|
49
49
|
const WIDGET_CSP = {
|
|
50
50
|
resourceDomains: [
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'https
|
|
51
|
+
// Exact hosts FIRST — not every host CSP implementation honors wildcards,
|
|
52
|
+
// and a declared-but-unmatched allowlist blocks harder than no declaration.
|
|
53
|
+
'https://api.kolbo.ai', // model icons (/assets)
|
|
54
|
+
'https://app.kolbo.ai',
|
|
55
|
+
'https://media.kolbo.ai', // media CDN (prod)
|
|
56
|
+
'https://media-staging.kolbo.ai',
|
|
57
|
+
'https://media-dev.kolbo.ai',
|
|
58
|
+
'https://kolboai-production.ams3.digitaloceanspaces.com',
|
|
59
|
+
'https://kolboai-production.ams3.cdn.digitaloceanspaces.com',
|
|
60
|
+
'https://kolboai-development.ams3.digitaloceanspaces.com',
|
|
61
|
+
'https://kolboai-development.ams3.cdn.digitaloceanspaces.com',
|
|
62
|
+
'https://kolbo-general-media.fra1.cdn.digitaloceanspaces.com',
|
|
54
63
|
'https://fonts.googleapis.com', // Inter / JetBrains Mono stylesheet
|
|
55
64
|
'https://fonts.gstatic.com', // font files
|
|
56
65
|
'https://images.pexels.com', // stock thumbnails
|
|
66
|
+
// Wildcards as a second layer for hosts that do support them.
|
|
67
|
+
'https://*.kolbo.ai',
|
|
68
|
+
'https://*.digitaloceanspaces.com',
|
|
69
|
+
'https://*.cdn.digitaloceanspaces.com',
|
|
57
70
|
'https://*.pexels.com',
|
|
58
71
|
'https://*.pixabay.com',
|
|
59
72
|
'https://*.sketchfab.com',
|
|
60
|
-
'https://*.cloudfront.net',
|
|
73
|
+
'https://*.cloudfront.net',
|
|
61
74
|
],
|
|
62
75
|
connectDomains: [],
|
|
63
76
|
};
|
|
@@ -125,6 +138,23 @@ function uiResult(uri, text, structured) {
|
|
|
125
138
|
const ICON_TTL_MS = 10 * 60 * 1000;
|
|
126
139
|
const infoCache = new Map(); // apiBase → { at, byKey: Map<lowername, {icon, eta}> }
|
|
127
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Resolve a Model.avatar value to an absolute URL. Avatars are bare filenames
|
|
143
|
+
* (sometimes with spaces) living in the BACKEND's public assets folder —
|
|
144
|
+
* `<api origin>/assets/<file>`. Do NOT use app.kolbo.ai for this: it's the SPA,
|
|
145
|
+
* whose catch-all returns 200 text/html for any missing file, which renders as
|
|
146
|
+
* a broken image in widgets.
|
|
147
|
+
*/
|
|
148
|
+
function resolveAvatarUrl(avatar, apiBase) {
|
|
149
|
+
if (!avatar) return null;
|
|
150
|
+
if (/^https?:\/\//i.test(avatar)) return avatar;
|
|
151
|
+
let origin = 'https://api.kolbo.ai';
|
|
152
|
+
try {
|
|
153
|
+
origin = new URL(apiBase || 'https://api.kolbo.ai/api').origin;
|
|
154
|
+
} catch (_) { /* keep default */ }
|
|
155
|
+
return `${origin}/assets/${encodeURIComponent(avatar)}`;
|
|
156
|
+
}
|
|
157
|
+
|
|
128
158
|
async function modelInfoMap(client) {
|
|
129
159
|
const cacheKey = client.apiBase || 'default';
|
|
130
160
|
const hit = infoCache.get(cacheKey);
|
|
@@ -135,13 +165,7 @@ async function modelInfoMap(client) {
|
|
|
135
165
|
const models = res?.models || res?.data?.models || [];
|
|
136
166
|
for (const m of models) {
|
|
137
167
|
if (!m) continue;
|
|
138
|
-
|
|
139
|
-
// deployments / internal calls) resolve against the app's public icon dir.
|
|
140
|
-
const icon = m.avatar
|
|
141
|
-
? (/^https?:\/\//i.test(m.avatar)
|
|
142
|
-
? m.avatar
|
|
143
|
-
: `https://app.kolbo.ai/models_icons/${encodeURIComponent(m.avatar)}`)
|
|
144
|
-
: null;
|
|
168
|
+
const icon = resolveAvatarUrl(m.avatar, client.apiBase);
|
|
145
169
|
// Real p75 wall-clock estimate mined from production creditUsages —
|
|
146
170
|
// the same source the in-app countdowns use. No estimate → no ETA shown.
|
|
147
171
|
const eta = Number(m.estimatedDurationSeconds || m.estimated_duration_seconds) || null;
|
|
@@ -232,5 +256,6 @@ module.exports = {
|
|
|
232
256
|
modelIcon,
|
|
233
257
|
modelInfo,
|
|
234
258
|
modelInfoMap,
|
|
259
|
+
resolveAvatarUrl,
|
|
235
260
|
widgetHtml, // exported for smoke tests
|
|
236
261
|
};
|
|
@@ -92,7 +92,7 @@ function renderChips(sc) {
|
|
|
92
92
|
if (s.voice) h += chip('🎤 ' + esc(s.voice));
|
|
93
93
|
if (s.mode) h += chip(esc(s.mode));
|
|
94
94
|
if (sc.count > 1) h += chip('×' + sc.count);
|
|
95
|
-
if (sc.reference_image) h += '<img class="k-ref-thumb" src="' + esc(sc.reference_image) + '" alt="" title="Reference image" onerror="this.style.display
|
|
95
|
+
if (sc.reference_image) h += '<img class="k-ref-thumb" src="' + esc(sc.reference_image) + '" alt="" title="Reference image" onerror="this.style.display=\\'none\\'">';
|
|
96
96
|
el('chips').innerHTML = h;
|
|
97
97
|
}
|
|
98
98
|
function chip(inner) { return '<span class="k-chip">' + inner + '</span>'; }
|
package/src/index.js
CHANGED
|
@@ -97,7 +97,12 @@ function createServer(opts = {}) {
|
|
|
97
97
|
|
|
98
98
|
const server = new McpServer({
|
|
99
99
|
name: 'kolbo',
|
|
100
|
-
|
|
100
|
+
title: 'Kolbo',
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
websiteUrl: 'https://kolbo.ai',
|
|
103
|
+
// Connector avatar for hosts that render server icons (claude.ai tool
|
|
104
|
+
// headers show this instead of a letter monogram).
|
|
105
|
+
icons: [{ src: 'https://api.kolbo.ai/assets/kolbo-ai.png', mimeType: 'image/png', sizes: ['512x512'] }]
|
|
101
106
|
});
|
|
102
107
|
|
|
103
108
|
// Register all tools. `inlineImages` (off by default) is opt-in: only the
|