@velaro/mcp-server 0.6.74 → 0.6.76
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 +98 -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.76",
|
|
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
|
@@ -187,6 +187,18 @@ function execInsightsRange(days) {
|
|
|
187
187
|
|
|
188
188
|
const messagingDel = (path) => messagingRequest('DELETE', path);
|
|
189
189
|
|
|
190
|
+
// Skill-based routing CRUD helper for SkillRouting/{Skills|Assignments|Requirements}.
|
|
191
|
+
async function skillRoutingCrud(resource, args, fields) {
|
|
192
|
+
const body = Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== undefined));
|
|
193
|
+
switch (args.action) {
|
|
194
|
+
case 'list': return await messagingGet('/SkillRouting/' + resource);
|
|
195
|
+
case 'create': return await messagingPost('/SkillRouting/' + resource, body);
|
|
196
|
+
case 'update': return await messagingPut('/SkillRouting/' + resource + '/' + args.id, body);
|
|
197
|
+
case 'delete': return await messagingDel('/SkillRouting/' + resource + '/' + args.id);
|
|
198
|
+
default: throw new Error('action must be list|create|update|delete');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
190
202
|
async function api(method, path, body, base = API_BASE) {
|
|
191
203
|
// Normalize: a path without a leading slash would glue onto the host ("...comScraperJobs/...") and fail as "fetch failed".
|
|
192
204
|
if (!path.startsWith('/')) path = '/' + path;
|
|
@@ -288,6 +300,7 @@ const MESSAGING_ADMIN_TOOLS = new Set([
|
|
|
288
300
|
'workflow_create', 'workflow_list', 'workflow_get', 'workflow_toggle',
|
|
289
301
|
'bot_create', 'bot_list', 'bot_get', 'bot_update_prompt', 'bot_set_knowledge',
|
|
290
302
|
'ai_config_attach_index', 'call_pop_settings_get', 'call_pop_settings_set',
|
|
303
|
+
'crm_mobile_fields_get', 'crm_mobile_fields_set',
|
|
291
304
|
'agent_list', 'team_list', 'conversation_list', 'conversation_get', 'conversation_search',
|
|
292
305
|
'contact_search', 'contact_get', 'routing_list', 'routing_get', 'site_info',
|
|
293
306
|
'ms_bookings_cancel_appointment', 'ms_bookings_check_availability_range', 'ms_bookings_reschedule_appointment',
|
|
@@ -771,6 +784,8 @@ const TOOLS = [
|
|
|
771
784
|
startDate: { type: 'string', description: 'ISO date (defaults to 90 days ago)' },
|
|
772
785
|
endDate: { type: 'string', description: 'ISO date (defaults to today)' },
|
|
773
786
|
groupBy: { type: 'string', description: '"month" or "week" (default month)' },
|
|
787
|
+
deploymentId: { type: 'number', description: 'Optional website (deployment row id) filter' },
|
|
788
|
+
teamId: { type: 'number', description: 'Optional team filter' },
|
|
774
789
|
},
|
|
775
790
|
},
|
|
776
791
|
},
|
|
@@ -4986,6 +5001,21 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
|
|
|
4986
5001
|
description: 'Get the Focus Inbox draft-pregeneration usage/cap report for this site -- whether the "Always Learning" background draft-pregeneration addon is entitled (EnableFocusDraftPregeneration), plus the live usage snapshot (used/max/percent) against the site\'s monthly draft-pregeneration cap. Use to check whether the addon is active and how close the site is to its cap.',
|
|
4987
5002
|
inputSchema: { type: 'object', properties: {} },
|
|
4988
5003
|
},
|
|
5004
|
+
{"name":"sentiment_report","description":"Sentiment report (v20). kind = overview | breakdown | conversation-overview | conversation-breakdown | contact-overview | agent-breakdown. Optional deploymentId (website) and teamId filters, verified server-side against your site.","inputSchema":{"type":"object","properties":{"kind":{"type":"string","description":"overview (default), breakdown, conversation-overview, conversation-breakdown, contact-overview, agent-breakdown"},"startDate":{"type":"string","description":"ISO date (default 30 days ago)"},"endDate":{"type":"string","description":"ISO date (default now)"},"groupBy":{"type":"string","description":"day (default), week, month"},"excludeBots":{"type":"boolean"},"deploymentId":{"type":"number","description":"Optional website (deployment row id) filter; must belong to your site"},"teamId":{"type":"number","description":"Optional team filter"}}}},
|
|
5005
|
+
{"name":"quality_agent_performance","description":"Conversation Quality agent performance (AI scores per agent). Optional deploymentId (website) and teamId filters.","inputSchema":{"type":"object","properties":{"days":{"type":"number","description":"Window in days (default 30)"},"deploymentId":{"type":"number","description":"Optional website (deployment row id) filter; must belong to your site"},"teamId":{"type":"number","description":"Optional team filter"}}}},
|
|
5006
|
+
{"name":"keyword_intelligence_top","description":"Top keywords/phrases customers use over a date range. Optional groupBy, ngram size, limit, teamId, agentId, website.","inputSchema":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"groupBy":{"type":"string","description":"none (default) or a grouping dimension"},"ngram":{"type":"number","description":"Phrase length 1-3 (default 3)"},"limit":{"type":"number","description":"Default 50"},"teamId":{"type":"number"},"agentId":{"type":"number"},"website":{"type":"string"}},"required":["from","to"]}},
|
|
5007
|
+
{"name":"keyword_intelligence_conversations","description":"Drill-down: conversations containing a keyword in a date range.","inputSchema":{"type":"object","properties":{"keyword":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"teamId":{"type":"number"},"agentId":{"type":"number"}},"required":["keyword","from","to"]}},
|
|
5008
|
+
{"name":"skill_routing_skills","description":"Skill-based routing: manage the skill catalog. action = list | create | update | delete. Requires the EnableSkillBasedRouting entitlement (403 otherwise).","inputSchema":{"type":"object","properties":{"action":{"type":"string"},"id":{"type":"number"},"name":{"type":"string"},"description":{"type":"string"}},"required":["action"]}},
|
|
5009
|
+
{"name":"skill_routing_assignments","description":"Skill-based routing: assign skills to agents with proficiency 1-5. action = list | create | update | delete.","inputSchema":{"type":"object","properties":{"action":{"type":"string"},"id":{"type":"number"},"workspaceUserId":{"type":"number"},"agentSkillId":{"type":"number"},"proficiency":{"type":"number"}},"required":["action"]}},
|
|
5010
|
+
{"name":"skill_routing_requirements","description":"Skill-based routing: required/preferred skills per deployment and/or team. action = list | create | update | delete. Update is partial. Requirements are disabled by default; set isEnabled true to turn on.","inputSchema":{"type":"object","properties":{"action":{"type":"string"},"id":{"type":"number"},"deploymentId":{"type":"number"},"teamId":{"type":"number"},"requiredSkillIds":{"type":"array","items":{"type":"number"}},"preferredSkillIds":{"type":"array","items":{"type":"number"}},"overflowWaitSeconds":{"type":"number"},"isEnabled":{"type":"boolean"}},"required":["action"]}},
|
|
5011
|
+
{"name":"skill_routing_simulate","description":"Dry-run skill routing for a team: shows which agents would be narrowed to and why. Never assigns a conversation or writes the decision log.","inputSchema":{"type":"object","properties":{"teamId":{"type":"number"},"waitedSeconds":{"type":"number"}}}},
|
|
5012
|
+
{"name":"qa_rubric","description":"Conversation Quality QA rubrics. action = list | get | default | create | update | delete. Pass rubric fields in \"rubric\". Requires EnableConversationQuality.","inputSchema":{"type":"object","properties":{"action":{"type":"string"},"id":{"type":"number"},"rubric":{"type":"object"}},"required":["action"]}},
|
|
5013
|
+
{"name":"qa_low_scores","description":"Conversations scoring below the rubric threshold, for QA review.","inputSchema":{"type":"object","properties":{"threshold":{"type":"number"},"days":{"type":"number"},"agentId":{"type":"number"},"skip":{"type":"number"},"take":{"type":"number"}}}},
|
|
5014
|
+
{"name":"ai_field_extraction_get_config","description":"Get the AI field extraction config (opt-in, default off; monthly cap). Requires the ai_field_extraction entitlement.","inputSchema":{"type":"object","properties":{}}},
|
|
5015
|
+
{"name":"ai_field_extraction_update_config","description":"Update AI field extraction config (partial). enabled, monthlyCap (null = 500 default, hard ceiling 50000), createThemeTags.","inputSchema":{"type":"object","properties":{"enabled":{"type":"boolean"},"monthlyCap":{"type":"number"},"createThemeTags":{"type":"boolean"}}}},
|
|
5016
|
+
{"name":"ai_field_extraction_correct_field","description":"Agent correction of an extracted field on a conversation.","inputSchema":{"type":"object","properties":{"conversationId":{"type":"number"},"fieldName":{"type":"string"},"value":{"type":"string"}},"required":["conversationId","fieldName","value"]}},
|
|
5017
|
+
{"name":"qa_calibration","description":"QA calibration report (AI score vs human review) for the last N days.","inputSchema":{"type":"object","properties":{"days":{"type":"number"}}}},
|
|
5018
|
+
{"name":"qa_alert_settings","description":"Get or set quality alert settings. Omit \"settings\" to read; pass it to update.","inputSchema":{"type":"object","properties":{"settings":{"type":"object"}}}},
|
|
4989
5019
|
];
|
|
4990
5020
|
|
|
4991
5021
|
// ── IVR business-hours helper ─────────────────────────────────────────────────
|
|
@@ -5469,6 +5499,8 @@ async function handleTool(name, args) {
|
|
|
5469
5499
|
if (args.startDate) qs.set('startDate', args.startDate);
|
|
5470
5500
|
if (args.endDate) qs.set('endDate', args.endDate);
|
|
5471
5501
|
qs.set('groupBy', args.groupBy ?? 'month');
|
|
5502
|
+
if (args.deploymentId != null) qs.set('deploymentId', String(args.deploymentId));
|
|
5503
|
+
if (args.teamId != null) qs.set('teamId', String(args.teamId));
|
|
5472
5504
|
return await messagingGet(`/Reports/chat-intelligence/themes?${qs.toString()}`);
|
|
5473
5505
|
}
|
|
5474
5506
|
case 'chat_intelligence_recommendations':
|
|
@@ -9859,6 +9891,72 @@ async function handleTool(name, args) {
|
|
|
9859
9891
|
return JSON.stringify(result, null, 2);
|
|
9860
9892
|
}
|
|
9861
9893
|
|
|
9894
|
+
|
|
9895
|
+
// -- Wave: sentiment / quality / keyword intelligence / skill routing / QA rubric --
|
|
9896
|
+
case 'sentiment_report': {
|
|
9897
|
+
const routes = { 'overview': 'sentiment-overview', 'breakdown': 'sentiment-breakdown', 'conversation-overview': 'conversation-sentiment-overview', 'conversation-breakdown': 'conversation-sentiment-breakdown', 'contact-overview': 'contact-sentiment-overview', 'agent-breakdown': 'agent-sentiment-breakdown' };
|
|
9898
|
+
const kind = args.kind ?? 'overview';
|
|
9899
|
+
if (!routes[kind]) throw new Error('kind must be one of: ' + Object.keys(routes).join(', '));
|
|
9900
|
+
const end = args.endDate ? new Date(args.endDate) : new Date();
|
|
9901
|
+
const start = args.startDate ? new Date(args.startDate) : new Date(end.getTime() - 30 * 86400000);
|
|
9902
|
+
const body = { Start: start.toISOString(), End: end.toISOString(), GroupBy: args.groupBy ?? 'day', ExcludeBots: args.excludeBots === true };
|
|
9903
|
+
if (args.deploymentId != null) body.DeploymentId = args.deploymentId;
|
|
9904
|
+
if (args.teamId != null) body.TeamId = args.teamId;
|
|
9905
|
+
return await messagingPost('/Reports/' + routes[kind], body);
|
|
9906
|
+
}
|
|
9907
|
+
case 'quality_agent_performance': {
|
|
9908
|
+
const qs = new URLSearchParams({ days: String(args.days ?? 30) });
|
|
9909
|
+
if (args.deploymentId != null) qs.set('deploymentId', String(args.deploymentId));
|
|
9910
|
+
if (args.teamId != null) qs.set('teamId', String(args.teamId));
|
|
9911
|
+
return await messagingGet('/api/admin/Reports/AgentPerformance?' + qs.toString());
|
|
9912
|
+
}
|
|
9913
|
+
case 'keyword_intelligence_top': {
|
|
9914
|
+
const qs = new URLSearchParams({ from: args.from, to: args.to, groupBy: args.groupBy ?? 'none', ngram: String(args.ngram ?? 3), limit: String(args.limit ?? 50) });
|
|
9915
|
+
for (const k of ['teamId', 'agentId', 'website']) if (args[k] != null) qs.set(k, String(args[k]));
|
|
9916
|
+
return await messagingGet('/api/keyword-intelligence/top?' + qs.toString());
|
|
9917
|
+
}
|
|
9918
|
+
case 'keyword_intelligence_conversations': {
|
|
9919
|
+
const qs = new URLSearchParams({ keyword: args.keyword, from: args.from, to: args.to });
|
|
9920
|
+
for (const k of ['teamId', 'agentId']) if (args[k] != null) qs.set(k, String(args[k]));
|
|
9921
|
+
return await messagingGet('/api/keyword-intelligence/conversations?' + qs.toString());
|
|
9922
|
+
}
|
|
9923
|
+
case 'skill_routing_skills':
|
|
9924
|
+
return await skillRoutingCrud('Skills', args, { Name: args.name, Description: args.description });
|
|
9925
|
+
case 'skill_routing_assignments':
|
|
9926
|
+
return await skillRoutingCrud('Assignments', args, { WorkspaceUserId: args.workspaceUserId, AgentSkillId: args.agentSkillId, Proficiency: args.proficiency });
|
|
9927
|
+
case 'skill_routing_requirements':
|
|
9928
|
+
return await skillRoutingCrud('Requirements', args, { DeploymentId: args.deploymentId, TeamId: args.teamId, RequiredSkillIds: args.requiredSkillIds, PreferredSkillIds: args.preferredSkillIds, OverflowWaitSeconds: args.overflowWaitSeconds, IsEnabled: args.isEnabled });
|
|
9929
|
+
case 'skill_routing_simulate':
|
|
9930
|
+
return await messagingPost('/SkillRouting/Simulate', { TeamId: args.teamId ?? null, WaitedSeconds: args.waitedSeconds ?? null });
|
|
9931
|
+
case 'qa_rubric': {
|
|
9932
|
+
const a = args.action;
|
|
9933
|
+
if (a === 'list') return await messagingGet('/api/admin/QualityQa/rubrics');
|
|
9934
|
+
if (a === 'default') return await messagingGet('/api/admin/QualityQa/rubrics/default');
|
|
9935
|
+
if (a === 'get') return await messagingGet('/api/admin/QualityQa/rubrics/' + args.id);
|
|
9936
|
+
if (a === 'create') return await messagingPost('/api/admin/QualityQa/rubrics', args.rubric ?? {});
|
|
9937
|
+
if (a === 'update') return await messagingPut('/api/admin/QualityQa/rubrics/' + args.id, args.rubric ?? {});
|
|
9938
|
+
if (a === 'delete') return await messagingDel('/api/admin/QualityQa/rubrics/' + args.id);
|
|
9939
|
+
throw new Error('action must be list|get|default|create|update|delete');
|
|
9940
|
+
}
|
|
9941
|
+
case 'qa_low_scores': {
|
|
9942
|
+
const qs = new URLSearchParams({ days: String(args.days ?? 30), skip: String(args.skip ?? 0), take: String(args.take ?? 50) });
|
|
9943
|
+
if (args.threshold != null) qs.set('threshold', String(args.threshold));
|
|
9944
|
+
if (args.agentId != null) qs.set('agentId', String(args.agentId));
|
|
9945
|
+
return await messagingGet('/api/admin/QualityQa/low-scores?' + qs.toString());
|
|
9946
|
+
}
|
|
9947
|
+
case 'ai_field_extraction_get_config':
|
|
9948
|
+
return await messagingGet('/AiFieldExtraction/Config');
|
|
9949
|
+
case 'ai_field_extraction_update_config': {
|
|
9950
|
+
const body = Object.fromEntries(Object.entries({ Enabled: args.enabled, MonthlyCap: args.monthlyCap, CreateThemeTags: args.createThemeTags }).filter(([, v]) => v !== undefined));
|
|
9951
|
+
return await messagingPut('/AiFieldExtraction/Config', body);
|
|
9952
|
+
}
|
|
9953
|
+
case 'ai_field_extraction_correct_field':
|
|
9954
|
+
return await messagingPut('/AiFieldExtraction/Conversation/' + args.conversationId + '/Fields/' + encodeURIComponent(args.fieldName), { Value: args.value });
|
|
9955
|
+
case 'qa_calibration':
|
|
9956
|
+
return await messagingGet('/api/admin/QualityQa/calibration?days=' + (args.days ?? 90));
|
|
9957
|
+
case 'qa_alert_settings':
|
|
9958
|
+
return args.settings ? await messagingPut('/api/admin/QualityQa/alert-settings', args.settings) : await messagingGet('/api/admin/QualityQa/alert-settings');
|
|
9959
|
+
|
|
9862
9960
|
default:
|
|
9863
9961
|
throw new Error(`Unknown tool: ${name}`);
|
|
9864
9962
|
}
|