@velaro/mcp-server 0.6.67 → 0.6.69

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 +120 -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.69",
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?"',
@@ -2721,6 +2756,59 @@ For multiSelect dynamic options: the variable named in dynamicOptionsVariable mu
2721
2756
  },
2722
2757
  },
2723
2758
 
2759
+ // ── Velaro Avatar (first-party provider) — library, personalities, site/group inheritance ──
2760
+ {
2761
+ name: 'avatar_list_library',
2762
+ description: 'List Velaro Avatar library entries (realistic and character) with id slug, name, kind, hasImage, default personality. Lives in velaro-messaging — requires VELARO_MESSAGING_API.',
2763
+ inputSchema: { type: 'object', properties: { kind: { type: 'string', description: '"realistic" or "character". Omit for all.' } } },
2764
+ },
2765
+ {
2766
+ name: 'avatar_list_personalities',
2767
+ description: 'List Velaro Avatar personality presets (tone/style) that can be selected at site or group level.',
2768
+ inputSchema: { type: 'object', properties: {} },
2769
+ },
2770
+ {
2771
+ name: 'avatar_set_site_default',
2772
+ description: 'Set the calling site\'s default avatar provider, avatar and personality (applies to all groups without an override). Provider "velaro" is the default Velaro-owned avatar; "simli", "d-id", "heygen", "none" also valid.',
2773
+ inputSchema: {
2774
+ type: 'object',
2775
+ properties: {
2776
+ providerSlug: { type: 'string', description: 'velaro | simli | d-id | heygen | none' },
2777
+ avatarId: { type: 'string', description: 'Library slug when provider is velaro, else the provider avatar id.' },
2778
+ personalityPresetSlug: { type: 'string', description: 'Personality preset slug.' },
2779
+ },
2780
+ },
2781
+ },
2782
+ {
2783
+ name: 'avatar_get_group_effective',
2784
+ description: 'Show the effective avatar settings for a group (group override field, else site default) and whether an override exists.',
2785
+ inputSchema: { type: 'object', properties: { groupId: { type: 'number' } }, required: ['groupId'] },
2786
+ },
2787
+ {
2788
+ name: 'avatar_set_group_override',
2789
+ description: 'Override avatar/personality/provider for one group. Omitted fields inherit the site default.',
2790
+ inputSchema: {
2791
+ type: 'object',
2792
+ properties: {
2793
+ groupId: { type: 'number' },
2794
+ providerSlug: { type: 'string' },
2795
+ avatarId: { type: 'string' },
2796
+ personalityPresetSlug: { type: 'string' },
2797
+ },
2798
+ required: ['groupId'],
2799
+ },
2800
+ },
2801
+ {
2802
+ name: 'avatar_reset_group',
2803
+ description: 'Reset one group to the site default avatar settings (removes its override).',
2804
+ inputSchema: { type: 'object', properties: { groupId: { type: 'number' } }, required: ['groupId'] },
2805
+ },
2806
+ {
2807
+ name: 'avatar_reset_all_overrides',
2808
+ description: 'Reset ALL group overrides for the calling site back to the site default.',
2809
+ inputSchema: { type: 'object', properties: {} },
2810
+ },
2811
+
2724
2812
  // ── Calendly integration management (superadmin) ──────────────────────────
2725
2813
  {
2726
2814
  name: 'calendly_get_status',
@@ -5635,6 +5723,21 @@ async function handleTool(name, args) {
5635
5723
  return 'Circuit breaker reset. Smart routing is now active again.';
5636
5724
  }
5637
5725
 
5726
+ case 'routing_team_get_config': {
5727
+ return JSON.stringify(await messagingGet(teamRoutingConfigPath(args.teamId)), null, 2);
5728
+ }
5729
+
5730
+ case 'routing_team_update_config': {
5731
+ const { teamId, config, ...rest } = args;
5732
+ const body = {};
5733
+ for (const [k, v] of Object.entries({ ...(config && typeof config === 'object' ? config : {}), ...rest })) {
5734
+ if (v !== undefined) body[k] = v;
5735
+ }
5736
+ if (!Object.keys(body).length) throw new Error('No fields to update. Pass at least one field.');
5737
+ await messagingPut(teamRoutingConfigPath(teamId), body);
5738
+ return `Team routing config updated (${teamId ? `team ${teamId}` : 'site default'}): ${Object.keys(body).join(', ')}.`;
5739
+ }
5740
+
5638
5741
  case 'routing_get_policy': {
5639
5742
  const p = await messagingGet('/AutoRoutingPolicy');
5640
5743
  const terminalLabel = terminalActionLabel(p.terminalActionOverride);
@@ -7438,6 +7541,23 @@ async function handleTool(name, args) {
7438
7541
  return `✓ AI Video Avatar updated for site ${args.siteId}. Provider: ${res.providerSlug}, enabled: ${res.enabled}`;
7439
7542
  }
7440
7543
 
7544
+ case 'avatar_list_library':
7545
+ return JSON.stringify(await messagingRequest('GET', `/avatar/library${args.kind ? `?kind=${encodeURIComponent(args.kind)}` : ''}`), null, 2);
7546
+ case 'avatar_list_personalities':
7547
+ return JSON.stringify(await messagingRequest('GET', '/avatar/personalities'), null, 2);
7548
+ case 'avatar_set_site_default':
7549
+ return JSON.stringify(await messagingRequest('POST', '/avatar/site-default', {
7550
+ providerSlug: args.providerSlug, avatarId: args.avatarId, personalityPresetSlug: args.personalityPresetSlug }), null, 2);
7551
+ case 'avatar_get_group_effective':
7552
+ return JSON.stringify(await messagingRequest('GET', `/avatar/groups/${Number(args.groupId)}/effective`), null, 2);
7553
+ case 'avatar_set_group_override':
7554
+ return JSON.stringify(await messagingRequest('PUT', `/avatar/groups/${Number(args.groupId)}/override`, {
7555
+ providerSlug: args.providerSlug, avatarId: args.avatarId, personalityPresetSlug: args.personalityPresetSlug }), null, 2);
7556
+ case 'avatar_reset_group':
7557
+ return JSON.stringify(await messagingRequest('DELETE', `/avatar/groups/${Number(args.groupId)}/override`), null, 2);
7558
+ case 'avatar_reset_all_overrides':
7559
+ return JSON.stringify(await messagingRequest('POST', '/avatar/group-overrides/reset-all', {}), null, 2);
7560
+
7441
7561
  case 'calendly_get_status': {
7442
7562
  // `env`, when given, targets one specific admin API environment instead of whatever
7443
7563
  // VELARO_ADMIN_API this server process happens to be configured with — see ADMIN_API_HOSTS