@velaro/mcp-server 0.6.75 → 0.6.77
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 +6 -0
- package/package.json +1 -1
- package/server.js +19 -0
package/README.md
CHANGED
|
@@ -119,6 +119,12 @@ This works with any MCP client that supports HTTP/SSE transport — including Cl
|
|
|
119
119
|
| `bot_get` | Get full bot config including system prompt |
|
|
120
120
|
| `bot_update_prompt` | Update a bot's system prompt |
|
|
121
121
|
|
|
122
|
+
### CRM Mobile Fields
|
|
123
|
+
| Tool | What It Does |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| `crm_mobile_fields_get` | Show which CRM fields the mobile app displays for NetSuite, Dynamics, Salesforce or HubSpot (mode, custom list, inherited info-panel list) |
|
|
126
|
+
| `crm_mobile_fields_set` | Set the mode (inherit or custom) and the ordered custom field list; validated and audit-logged. Dynamics and HubSpot require the plan that includes them |
|
|
127
|
+
|
|
122
128
|
### Contacts
|
|
123
129
|
| Tool | What It Does |
|
|
124
130
|
|------|-------------|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velaro/mcp-server",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.77",
|
|
4
4
|
"description": "Velaro MCP server — connect Claude and other AI agents directly to your Velaro account: KB, workflows, bots, conversations, contacts, routing, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/server.js
CHANGED
|
@@ -300,6 +300,7 @@ const MESSAGING_ADMIN_TOOLS = new Set([
|
|
|
300
300
|
'workflow_create', 'workflow_list', 'workflow_get', 'workflow_toggle',
|
|
301
301
|
'bot_create', 'bot_list', 'bot_get', 'bot_update_prompt', 'bot_set_knowledge',
|
|
302
302
|
'ai_config_attach_index', 'call_pop_settings_get', 'call_pop_settings_set',
|
|
303
|
+
'crm_mobile_fields_get', 'crm_mobile_fields_set',
|
|
303
304
|
'agent_list', 'team_list', 'conversation_list', 'conversation_get', 'conversation_search',
|
|
304
305
|
'contact_search', 'contact_get', 'routing_list', 'routing_get', 'site_info',
|
|
305
306
|
'ms_bookings_cancel_appointment', 'ms_bookings_check_availability_range', 'ms_bookings_reschedule_appointment',
|
|
@@ -4150,6 +4151,7 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
|
|
|
4150
4151
|
description: { type: 'string', description: 'New description' },
|
|
4151
4152
|
contactSales: { type: 'boolean', description: 'Set true to hide price and show "Contact sales"' },
|
|
4152
4153
|
isActive: { type: 'boolean', description: 'Set false to deactivate (hide from catalog)' },
|
|
4154
|
+
limits: { type: 'object', description: 'Plan limit keys merged into MetadataJson (numbers): aiTokensPerMonth, includedMcpCalls, apiCallsPerMonth, webhookInvocationsPerMonth, httpActionsPerMonth, emailSendsPerMonth, blobUploadMbPerMonth. Other keys are preserved.' },
|
|
4153
4155
|
},
|
|
4154
4156
|
required: ['packageKey'],
|
|
4155
4157
|
},
|
|
@@ -9280,6 +9282,13 @@ async function handleTool(name, args) {
|
|
|
9280
9282
|
for (const p of items) {
|
|
9281
9283
|
const price = p.contactSales ? 'Contact sales' : (p.monthlyPriceCents ? `$${(p.monthlyPriceCents/100).toFixed(0)}${p.unitLabel||'/mo'}` : 'Free');
|
|
9282
9284
|
lines.push(` ${p.packageKey.padEnd(40)} ${price.padEnd(18)} v${p.version} ${p.displayName}`);
|
|
9285
|
+
if (p.packageType === 'plan' && p.metadataJson) {
|
|
9286
|
+
try {
|
|
9287
|
+
const m = JSON.parse(p.metadataJson);
|
|
9288
|
+
const lim = ['aiTokensPerMonth','includedMcpCalls','apiCallsPerMonth','webhookInvocationsPerMonth','httpActionsPerMonth','emailSendsPerMonth','blobUploadMbPerMonth'].filter(k => m[k] != null).map(k => `${k}=${m[k]}`);
|
|
9289
|
+
if (lim.length) lines.push(` limits: ${lim.join(' ')}`);
|
|
9290
|
+
} catch { /* ignore bad metadata */ }
|
|
9291
|
+
}
|
|
9283
9292
|
}
|
|
9284
9293
|
}
|
|
9285
9294
|
return lines.join('\n');
|
|
@@ -9294,6 +9303,16 @@ async function handleTool(name, args) {
|
|
|
9294
9303
|
if (args.description) payload.description = args.description;
|
|
9295
9304
|
if (args.contactSales != null) payload.contactSales = args.contactSales;
|
|
9296
9305
|
if (args.isActive != null) payload.isActive = args.isActive;
|
|
9306
|
+
if (args.limits && typeof args.limits === 'object') {
|
|
9307
|
+
const LIMIT_KEYS = ['aiTokensPerMonth','includedMcpCalls','apiCallsPerMonth','webhookInvocationsPerMonth','httpActionsPerMonth','emailSendsPerMonth','blobUploadMbPerMonth'];
|
|
9308
|
+
const bad = Object.keys(args.limits).filter(k => !LIMIT_KEYS.includes(k));
|
|
9309
|
+
if (bad.length) throw new Error(`Unknown limit keys: ${bad.join(', ')}`);
|
|
9310
|
+
const all = await api('GET', '/Pricing/catalog');
|
|
9311
|
+
const cur = (Array.isArray(all) ? all : []).find(p => p.packageKey === args.packageKey);
|
|
9312
|
+
let meta = {};
|
|
9313
|
+
try { meta = cur?.metadataJson ? JSON.parse(cur.metadataJson) : {}; } catch { meta = {}; }
|
|
9314
|
+
payload.metadataJson = JSON.stringify({ ...meta, ...args.limits });
|
|
9315
|
+
}
|
|
9297
9316
|
const result = await api('PUT', `/Pricing/catalog/${args.packageKey}`, payload);
|
|
9298
9317
|
return `✅ Package '${result.packageKey}' updated to v${result.version}.`;
|
|
9299
9318
|
}
|