@velaro/mcp-server 0.6.67 → 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.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/server.js +50 -0
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.67",
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?"',
@@ -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);