@velaro/mcp-server 0.6.66 → 0.6.68
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 +2 -0
- package/package.json +1 -1
- package/server.js +63 -6
package/README.md
CHANGED
|
@@ -132,6 +132,8 @@ This works with any MCP client that supports HTTP/SSE transport — including Cl
|
|
|
132
132
|
| `team_list` | List all teams for this site |
|
|
133
133
|
| `routing_list` | List all routing rules ordered by priority |
|
|
134
134
|
| `routing_get` | Get routing rule details including rule and value JSON |
|
|
135
|
+
| `routing_team_get_config` | Team-level routing config (routing type, queue timeout, idle alerts); omit teamId for site default |
|
|
136
|
+
| `routing_team_update_config` | Partial update of team-level routing config; unknown fields pass through |
|
|
135
137
|
| `routing_get_policy` | Site auto-routing policy including reassignment mode and the agent inactivity chain |
|
|
136
138
|
| `routing_update_policy` | Update the policy, reassignment mode and inactivity chain (mode is always sent back) |
|
|
137
139
|
| `routing_simulate_inactivity` | DRY RUN of the inactivity chain for a mocked scenario, nothing is sent |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velaro/mcp-server",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.68",
|
|
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
|
@@ -166,6 +166,12 @@ const MCP_SUBMISSION_LIMIT = 50;
|
|
|
166
166
|
const messagingGet = (path) => messagingRequest('GET', path);
|
|
167
167
|
const messagingPost = (path, body) => messagingRequest('POST', path, body);
|
|
168
168
|
const messagingPut = (path, body) => messagingRequest('PUT', path, body);
|
|
169
|
+
function teamRoutingConfigPath(teamId) {
|
|
170
|
+
if (teamId === undefined || teamId === null || teamId === '') return '/RoutingConfig';
|
|
171
|
+
const n = Number(teamId);
|
|
172
|
+
if (!Number.isInteger(n) || n <= 0) throw new Error('teamId must be a positive integer.');
|
|
173
|
+
return `/RoutingConfig?teamId=${n}`;
|
|
174
|
+
}
|
|
169
175
|
const messagingPatch = (path, body) => messagingRequest('PATCH', path, body);
|
|
170
176
|
const messagingDel = (path) => messagingRequest('DELETE', path);
|
|
171
177
|
|
|
@@ -1571,6 +1577,35 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
|
|
|
1571
1577
|
required: [],
|
|
1572
1578
|
},
|
|
1573
1579
|
},
|
|
1580
|
+
{
|
|
1581
|
+
name: 'routing_team_get_config',
|
|
1582
|
+
description: 'Get team-level routing config (routing type roundRobin/leastBusy/longestIdle, routing action, queue timeout, idle queue alert settings, schedule-aware routing). Pass teamId for a team row, omit for the site default row. Site is taken from auth.',
|
|
1583
|
+
inputSchema: { type: 'object', properties: { teamId: { type: 'number', description: 'Team (group) id; omit for the site default row' } }, required: [] },
|
|
1584
|
+
},
|
|
1585
|
+
{
|
|
1586
|
+
name: 'routing_team_update_config',
|
|
1587
|
+
description: 'Partially update team-level routing config. Only fields you pass change; null means inherit. Any extra field in `config` is passed through to messaging unchanged (new routing types and fields work without an MCP release).',
|
|
1588
|
+
inputSchema: {
|
|
1589
|
+
type: 'object',
|
|
1590
|
+
properties: {
|
|
1591
|
+
teamId: { type: 'number', description: 'Team (group) id; omit for the site default row' },
|
|
1592
|
+
routingType: { type: 'string', description: 'roundRobin | leastBusy | longestIdle (validated by messaging)' },
|
|
1593
|
+
routingAction: { type: 'string', description: 'Routing action (validated by messaging)' },
|
|
1594
|
+
queueTimeoutEnabled: { type: ['boolean', 'null'] },
|
|
1595
|
+
queueTimeoutMinutes: { type: ['number', 'null'] },
|
|
1596
|
+
prioritizeAgents: { type: ['boolean', 'null'] },
|
|
1597
|
+
idleQueueAlertEnabled: { type: ['boolean', 'null'] },
|
|
1598
|
+
idleQueueAlertAfterMinutes: { type: ['number', 'null'] },
|
|
1599
|
+
idleQueueAlertRepeatMinutes: { type: ['number', 'null'] },
|
|
1600
|
+
idleQueueAlertMaxPerConversation: { type: ['number', 'null'] },
|
|
1601
|
+
idleQueueAlertTitle: { type: ['string', 'null'] },
|
|
1602
|
+
idleQueueAlertBody: { type: ['string', 'null'] },
|
|
1603
|
+
scheduleAwareRoutingEnabled: { type: ['boolean', 'null'] },
|
|
1604
|
+
config: { type: 'object', additionalProperties: true, description: 'Any other RoutingConfig fields, passed through as-is' },
|
|
1605
|
+
},
|
|
1606
|
+
required: [],
|
|
1607
|
+
},
|
|
1608
|
+
},
|
|
1574
1609
|
{
|
|
1575
1610
|
name: 'routing_get_decision_log',
|
|
1576
1611
|
description: 'Get the routing decision log for a specific conversation — shows every routing step, reroute attempt, agent assignments, terminal action, and rule source. Use to diagnose "why was this conversation handled this way?"',
|
|
@@ -3989,15 +4024,16 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
|
|
|
3989
4024
|
// Moshky AI safety rule and ConversationTriageService's prompt assembly (velaro-messaging).
|
|
3990
4025
|
{
|
|
3991
4026
|
name: 'focus_get_triage_rules',
|
|
3992
|
-
description: 'Get this site\'s current AI triage rules: which of the 5 fixed labels (urgent, needs_reply, offer, fyi, waiting) are enabled, plus the per-channel triage-on-off and priority weight already owned by the channel-config endpoint, shown here for context. A label missing/never configured defaults to enabled.',
|
|
4027
|
+
description: 'Get this site\'s current AI triage rules: which of the 5 fixed labels (urgent, needs_reply, offer, fyi, waiting) are enabled, plus the per-channel triage-on-off and priority weight already owned by the channel-config endpoint, shown here for context. A label missing/never configured defaults to enabled. Also returns triageMode ("off" or "economy").',
|
|
3993
4028
|
inputSchema: { type: 'object', properties: {} },
|
|
3994
4029
|
},
|
|
3995
4030
|
{
|
|
3996
4031
|
name: 'focus_update_triage_rules',
|
|
3997
|
-
description: 'Enable or disable one or more of the 5 fixed AI triage labels (urgent, needs_reply, offer, fyi, waiting) for this site. Apply-if-present -- only labels included are changed. Rejects any label name outside the fixed set. Disabling all 5 fails safe back to all-enabled server-side rather than breaking triage.',
|
|
4032
|
+
description: 'Enable or disable one or more of the 5 fixed AI triage labels (urgent, needs_reply, offer, fyi, waiting) for this site. Apply-if-present -- only labels included are changed. Rejects any label name outside the fixed set. Disabling all 5 fails safe back to all-enabled server-side rather than breaking triage. Optionally set triageMode: "economy" classifies obvious messages (auto-replies, clear urgency) without an AI call, lowering AI usage; "off" keeps current behavior. Unspecified fields are preserved.',
|
|
3998
4033
|
inputSchema: {
|
|
3999
4034
|
type: 'object',
|
|
4000
4035
|
properties: {
|
|
4036
|
+
triageMode: { type: 'string', enum: ['off', 'economy'], description: 'Optional. "economy" skips the AI call for obvious messages; "off" (default) keeps current behavior.' },
|
|
4001
4037
|
labels: {
|
|
4002
4038
|
type: 'array',
|
|
4003
4039
|
description: 'Labels to update.',
|
|
@@ -4011,7 +4047,6 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
|
|
|
4011
4047
|
},
|
|
4012
4048
|
},
|
|
4013
4049
|
},
|
|
4014
|
-
required: ['labels'],
|
|
4015
4050
|
},
|
|
4016
4051
|
},
|
|
4017
4052
|
|
|
@@ -5635,6 +5670,21 @@ async function handleTool(name, args) {
|
|
|
5635
5670
|
return 'Circuit breaker reset. Smart routing is now active again.';
|
|
5636
5671
|
}
|
|
5637
5672
|
|
|
5673
|
+
case 'routing_team_get_config': {
|
|
5674
|
+
return JSON.stringify(await messagingGet(teamRoutingConfigPath(args.teamId)), null, 2);
|
|
5675
|
+
}
|
|
5676
|
+
|
|
5677
|
+
case 'routing_team_update_config': {
|
|
5678
|
+
const { teamId, config, ...rest } = args;
|
|
5679
|
+
const body = {};
|
|
5680
|
+
for (const [k, v] of Object.entries({ ...(config && typeof config === 'object' ? config : {}), ...rest })) {
|
|
5681
|
+
if (v !== undefined) body[k] = v;
|
|
5682
|
+
}
|
|
5683
|
+
if (!Object.keys(body).length) throw new Error('No fields to update. Pass at least one field.');
|
|
5684
|
+
await messagingPut(teamRoutingConfigPath(teamId), body);
|
|
5685
|
+
return `Team routing config updated (${teamId ? `team ${teamId}` : 'site default'}): ${Object.keys(body).join(', ')}.`;
|
|
5686
|
+
}
|
|
5687
|
+
|
|
5638
5688
|
case 'routing_get_policy': {
|
|
5639
5689
|
const p = await messagingGet('/AutoRoutingPolicy');
|
|
5640
5690
|
const terminalLabel = terminalActionLabel(p.terminalActionOverride);
|
|
@@ -8776,10 +8826,17 @@ async function handleTool(name, args) {
|
|
|
8776
8826
|
case 'focus_get_triage_rules':
|
|
8777
8827
|
return await messagingGet('/Focus/triage-rules');
|
|
8778
8828
|
case 'focus_update_triage_rules': {
|
|
8779
|
-
|
|
8780
|
-
|
|
8829
|
+
const hasLabels = Array.isArray(args.labels) && args.labels.length > 0;
|
|
8830
|
+
const hasMode = args.triageMode !== undefined && args.triageMode !== null;
|
|
8831
|
+
if (!hasLabels && !hasMode) {
|
|
8832
|
+
throw new Error('Provide labels (non-empty array) and/or triageMode.');
|
|
8833
|
+
}
|
|
8834
|
+
if (hasMode && !['off', 'economy'].includes(args.triageMode)) {
|
|
8835
|
+
throw new Error('triageMode must be "off" or "economy".');
|
|
8781
8836
|
}
|
|
8782
|
-
const
|
|
8837
|
+
const labels = hasLabels ? args.labels.map((l) => ({ Label: l.label, Enabled: l.enabled })) : undefined;
|
|
8838
|
+
// Legacy array body when only labels are sent; object body when triageMode is involved.
|
|
8839
|
+
const body = hasMode ? { ...(labels ? { labels } : {}), triageMode: args.triageMode } : labels;
|
|
8783
8840
|
return await messagingPut('/Focus/triage-rules', body);
|
|
8784
8841
|
}
|
|
8785
8842
|
|