verbo-mcp-server 0.1.1 → 0.1.2
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/dist/client.js +32 -10
- package/dist/client.js.map +1 -1
- package/dist/setup-tools.js +16 -4
- package/dist/setup-tools.js.map +1 -1
- package/dist/tools.js +6 -3
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +40 -11
- package/src/setup-tools.ts +16 -4
- package/src/tools.ts +6 -3
package/dist/client.js
CHANGED
|
@@ -11,17 +11,39 @@ class VerboClient {
|
|
|
11
11
|
}
|
|
12
12
|
async request(path, options = {}) {
|
|
13
13
|
const url = `${this.baseUrl}/api/v1${path}`;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
let res;
|
|
15
|
+
try {
|
|
16
|
+
res = await fetch(url, {
|
|
17
|
+
...options,
|
|
18
|
+
headers: {
|
|
19
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
...options.headers,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
throw new Error(`Could not connect to Verbo API at ${this.baseUrl}. Check your internet connection or VERBO_API_URL setting.`);
|
|
27
|
+
}
|
|
28
|
+
let data;
|
|
29
|
+
try {
|
|
30
|
+
data = await res.json();
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error(`Verbo API returned invalid response (HTTP ${res.status}). The server may be temporarily unavailable — try again in a moment.`);
|
|
34
|
+
}
|
|
23
35
|
if (!res.ok) {
|
|
24
|
-
|
|
36
|
+
const errorMsg = data.error || "Unknown error";
|
|
37
|
+
if (res.status === 401) {
|
|
38
|
+
throw new Error(`API key is invalid or revoked. Create a new key at ${this.baseUrl}/developers`);
|
|
39
|
+
}
|
|
40
|
+
if (res.status === 403) {
|
|
41
|
+
throw new Error(`Subscription expired or inactive. Upgrade at ${this.baseUrl}/settings/billing — ${errorMsg}`);
|
|
42
|
+
}
|
|
43
|
+
if (res.status === 429) {
|
|
44
|
+
throw new Error(`Rate limit exceeded. ${errorMsg}`);
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`Verbo API error (${res.status}): ${errorMsg}`);
|
|
25
47
|
}
|
|
26
48
|
return data;
|
|
27
49
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;AAEpC,MAAa,WAAW;IACd,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YAAY,MAAc,EAAE,OAAgB;QAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,UAAuB,EAAE;QAC3D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,UAAU,IAAI,EAAE,CAAC;QAC5C,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-tools.js
CHANGED
|
@@ -28,19 +28,31 @@ async function executeSetupTool(client, name, args) {
|
|
|
28
28
|
switch (name) {
|
|
29
29
|
case "verbo_setup_crawl": {
|
|
30
30
|
const result = await client.setupCrawl(args.url);
|
|
31
|
-
return JSON.stringify(result, null, 2)
|
|
31
|
+
return JSON.stringify(result, null, 2) +
|
|
32
|
+
"\n\n→ Business configured from website. Next: run verbo_setup_connect to connect WhatsApp.";
|
|
32
33
|
}
|
|
33
34
|
case "verbo_setup_connect": {
|
|
34
35
|
const result = await client.setupConnect();
|
|
35
|
-
|
|
36
|
+
const data = result;
|
|
37
|
+
const connectUrl = data.connectUrl || "";
|
|
38
|
+
return JSON.stringify(result, null, 2) +
|
|
39
|
+
`\n\n→ WhatsApp instance created. IMPORTANT: Tell the user to open ${connectUrl} in their browser and scan the QR code with their phone. After scanning, run verbo_setup_status to confirm the connection.`;
|
|
36
40
|
}
|
|
37
41
|
case "verbo_setup_status": {
|
|
38
42
|
const result = await client.setupStatus();
|
|
39
|
-
|
|
43
|
+
const data = result;
|
|
44
|
+
const ready = data.ready;
|
|
45
|
+
if (ready) {
|
|
46
|
+
return JSON.stringify(result, null, 2) +
|
|
47
|
+
"\n\n→ All set! The AI agent is live and will respond to incoming WhatsApp messages automatically. Use verbo_send_message to send a test message.";
|
|
48
|
+
}
|
|
49
|
+
return JSON.stringify(result, null, 2) +
|
|
50
|
+
"\n\n→ Setup incomplete. Check the steps above and run the missing ones.";
|
|
40
51
|
}
|
|
41
52
|
case "verbo_setup_disconnect": {
|
|
42
53
|
const result = await client.setupDisconnect();
|
|
43
|
-
return JSON.stringify(result, null, 2)
|
|
54
|
+
return JSON.stringify(result, null, 2) +
|
|
55
|
+
"\n\n→ WhatsApp disconnected. The phone number is free to use elsewhere.";
|
|
44
56
|
}
|
|
45
57
|
default:
|
|
46
58
|
return JSON.stringify({ error: `Unknown setup tool: ${name}` });
|
package/dist/setup-tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-tools.js","sourceRoot":"","sources":["../src/setup-tools.ts"],"names":[],"mappings":";;;AA+BA,
|
|
1
|
+
{"version":3,"file":"setup-tools.js","sourceRoot":"","sources":["../src/setup-tools.ts"],"names":[],"mappings":";;;AA+BA,4CAqCC;AApED,yCAAyC;AACzC,6BAAwB;AAGX,QAAA,oBAAoB,GAAG;IAClC,iBAAiB,EAAE;QACjB,WAAW,EACT,mNAAmN;QACrN,MAAM,EAAE;YACN,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;SACjE;KACF;IACD,mBAAmB,EAAE;QACnB,WAAW,EACT,+QAA+Q;QACjR,MAAM,EAAE,EAAE;KACX;IACD,kBAAkB,EAAE;QAClB,WAAW,EACT,uHAAuH;QACzH,MAAM,EAAE,EAAE;KACX;IACD,sBAAsB,EAAE;QACtB,WAAW,EACT,kKAAkK;QACpK,MAAM,EAAE,EAAE;KACX;CACO,CAAC;AAIJ,KAAK,UAAU,gBAAgB,CACpC,MAAmB,EACnB,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;YAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,4FAA4F,CAAC;QACjG,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAiC,CAAC;YAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,qEAAqE,UAAU,4HAA4H,CAAC;QAChN,CAAC;QACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAiC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACpC,kJAAkJ,CAAC;YACvJ,CAAC;YACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,yEAAyE,CAAC;QAC9E,CAAC;QACD,KAAK,wBAAwB,CAAC,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,yEAAyE,CAAC;QAC9E,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
|
package/dist/tools.js
CHANGED
|
@@ -66,14 +66,16 @@ async function executeTool(client, name, args) {
|
|
|
66
66
|
switch (name) {
|
|
67
67
|
case "verbo_send_message": {
|
|
68
68
|
const result = await client.sendMessage(args.to, args.message, args.image_url);
|
|
69
|
-
return JSON.stringify(result, null, 2)
|
|
69
|
+
return JSON.stringify(result, null, 2) +
|
|
70
|
+
"\n\n→ Message sent. Use verbo_list_conversations to see the conversation.";
|
|
70
71
|
}
|
|
71
72
|
case "verbo_list_conversations": {
|
|
72
73
|
const result = await client.listConversations({
|
|
73
74
|
status: args.status,
|
|
74
75
|
limit: args.limit,
|
|
75
76
|
});
|
|
76
|
-
return JSON.stringify(result, null, 2)
|
|
77
|
+
return JSON.stringify(result, null, 2) +
|
|
78
|
+
"\n\n→ Use verbo_get_conversation with a conversation ID to see full messages.";
|
|
77
79
|
}
|
|
78
80
|
case "verbo_get_conversation": {
|
|
79
81
|
const result = await client.getConversation(args.conversation_id);
|
|
@@ -89,7 +91,8 @@ async function executeTool(client, name, args) {
|
|
|
89
91
|
faqData: args.faq,
|
|
90
92
|
businessHours: args.business_hours,
|
|
91
93
|
});
|
|
92
|
-
return JSON.stringify(result, null, 2)
|
|
94
|
+
return JSON.stringify(result, null, 2) +
|
|
95
|
+
"\n\n→ Agent updated. Use verbo_setup_status to verify the full setup.";
|
|
93
96
|
}
|
|
94
97
|
default:
|
|
95
98
|
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":";;;AA0EA,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":";;;AA0EA,kCA+CC;AAzHD,mCAAmC;AACnC,6BAAwB;AAGX,QAAA,eAAe,GAAG;IAC7B,kBAAkB,EAAE;QAClB,WAAW,EACT,sEAAsE;QACxE,MAAM,EAAE;YACN,EAAE,EAAE,OAAC;iBACF,MAAM,EAAE;iBACR,QAAQ,CAAC,oCAAoC,CAAC;YACjD,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,SAAS,EAAE,OAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,sBAAsB,CAAC;SACpC;KACF;IACD,wBAAwB,EAAE;QACxB,WAAW,EACT,gEAAgE;QAClE,MAAM,EAAE;YACN,MAAM,EAAE,OAAC;iBACN,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;iBACxB,QAAQ,EAAE;iBACV,QAAQ,CAAC,kBAAkB,CAAC;YAC/B,KAAK,EAAE,OAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iCAAiC,CAAC;SAC/C;KACF;IACD,sBAAsB,EAAE;QACtB,WAAW,EACT,wDAAwD;QAC1D,MAAM,EAAE;YACN,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;SACxD;KACF;IACD,kBAAkB,EAAE;QAClB,WAAW,EACT,uEAAuE;QACzE,MAAM,EAAE,EAAE;KACX;IACD,qBAAqB,EAAE;QACrB,WAAW,EACT,iFAAiF;QACnF,MAAM,EAAE;YACN,gBAAgB,EAAE,OAAC;iBAChB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,oCAAoC,CAAC;YACjD,GAAG,EAAE,OAAC;iBACH,KAAK,CACJ,OAAC,CAAC,MAAM,CAAC;gBACP,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;gBACpB,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;aACnB,CAAC,CACH;iBACA,QAAQ,EAAE;iBACV,QAAQ,CAAC,4BAA4B,CAAC;YACzC,cAAc,EAAE,OAAC;iBACd,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC;iBAC9B,QAAQ,EAAE;iBACV,QAAQ,CACP,gDAAgD,CACjD;SACJ;KACF;CACO,CAAC;AAIJ,KAAK,UAAU,WAAW,CAC/B,MAAmB,EACnB,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,oBAAoB,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CACrC,IAAI,CAAC,EAAY,EACjB,IAAI,CAAC,OAAiB,EACtB,IAAI,CAAC,SAA+B,CACrC,CAAC;YACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,2EAA2E,CAAC;QAChF,CAAC;QACD,KAAK,0BAA0B,CAAC,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC;gBAC5C,MAAM,EAAE,IAAI,CAAC,MAA4B;gBACzC,KAAK,EAAE,IAAI,CAAC,KAA2B;aACxC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,+EAA+E,CAAC;QACpF,CAAC;QACD,KAAK,wBAAwB,CAAC,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CACzC,IAAI,CAAC,eAAyB,CAC/B,CAAC;YACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC;gBACzC,eAAe,EAAE,IAAI,CAAC,gBAAsC;gBAC5D,OAAO,EAAE,IAAI,CAAC,GAA2C;gBACzD,aAAa,EAAE,IAAI,CAAC,cAEP;aACd,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,uEAAuE,CAAC;QAC5E,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -11,21 +11,50 @@ export class VerboClient {
|
|
|
11
11
|
|
|
12
12
|
private async request(path: string, options: RequestInit = {}): Promise<unknown> {
|
|
13
13
|
const url = `${this.baseUrl}/api/v1${path}`;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
let res: Response;
|
|
15
|
+
try {
|
|
16
|
+
res = await fetch(url, {
|
|
17
|
+
...options,
|
|
18
|
+
headers: {
|
|
19
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
...options.headers,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
} catch (err) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Could not connect to Verbo API at ${this.baseUrl}. Check your internet connection or VERBO_API_URL setting.`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
let data: unknown;
|
|
31
|
+
try {
|
|
32
|
+
data = await res.json();
|
|
33
|
+
} catch {
|
|
25
34
|
throw new Error(
|
|
26
|
-
`Verbo API
|
|
35
|
+
`Verbo API returned invalid response (HTTP ${res.status}). The server may be temporarily unavailable — try again in a moment.`
|
|
27
36
|
);
|
|
28
37
|
}
|
|
38
|
+
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const errorMsg = (data as { error?: string }).error || "Unknown error";
|
|
41
|
+
if (res.status === 401) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`API key is invalid or revoked. Create a new key at ${this.baseUrl}/developers`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (res.status === 403) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Subscription expired or inactive. Upgrade at ${this.baseUrl}/settings/billing — ${errorMsg}`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (res.status === 429) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Rate limit exceeded. ${errorMsg}`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`Verbo API error (${res.status}): ${errorMsg}`);
|
|
57
|
+
}
|
|
29
58
|
return data;
|
|
30
59
|
}
|
|
31
60
|
|
package/src/setup-tools.ts
CHANGED
|
@@ -37,19 +37,31 @@ export async function executeSetupTool(
|
|
|
37
37
|
switch (name) {
|
|
38
38
|
case "verbo_setup_crawl": {
|
|
39
39
|
const result = await client.setupCrawl(args.url as string);
|
|
40
|
-
return JSON.stringify(result, null, 2)
|
|
40
|
+
return JSON.stringify(result, null, 2) +
|
|
41
|
+
"\n\n→ Business configured from website. Next: run verbo_setup_connect to connect WhatsApp.";
|
|
41
42
|
}
|
|
42
43
|
case "verbo_setup_connect": {
|
|
43
44
|
const result = await client.setupConnect();
|
|
44
|
-
|
|
45
|
+
const data = result as Record<string, unknown>;
|
|
46
|
+
const connectUrl = data.connectUrl || "";
|
|
47
|
+
return JSON.stringify(result, null, 2) +
|
|
48
|
+
`\n\n→ WhatsApp instance created. IMPORTANT: Tell the user to open ${connectUrl} in their browser and scan the QR code with their phone. After scanning, run verbo_setup_status to confirm the connection.`;
|
|
45
49
|
}
|
|
46
50
|
case "verbo_setup_status": {
|
|
47
51
|
const result = await client.setupStatus();
|
|
48
|
-
|
|
52
|
+
const data = result as Record<string, unknown>;
|
|
53
|
+
const ready = data.ready;
|
|
54
|
+
if (ready) {
|
|
55
|
+
return JSON.stringify(result, null, 2) +
|
|
56
|
+
"\n\n→ All set! The AI agent is live and will respond to incoming WhatsApp messages automatically. Use verbo_send_message to send a test message.";
|
|
57
|
+
}
|
|
58
|
+
return JSON.stringify(result, null, 2) +
|
|
59
|
+
"\n\n→ Setup incomplete. Check the steps above and run the missing ones.";
|
|
49
60
|
}
|
|
50
61
|
case "verbo_setup_disconnect": {
|
|
51
62
|
const result = await client.setupDisconnect();
|
|
52
|
-
return JSON.stringify(result, null, 2)
|
|
63
|
+
return JSON.stringify(result, null, 2) +
|
|
64
|
+
"\n\n→ WhatsApp disconnected. The phone number is free to use elsewhere.";
|
|
53
65
|
}
|
|
54
66
|
default:
|
|
55
67
|
return JSON.stringify({ error: `Unknown setup tool: ${name}` });
|
package/src/tools.ts
CHANGED
|
@@ -84,14 +84,16 @@ export async function executeTool(
|
|
|
84
84
|
args.message as string,
|
|
85
85
|
args.image_url as string | undefined,
|
|
86
86
|
);
|
|
87
|
-
return JSON.stringify(result, null, 2)
|
|
87
|
+
return JSON.stringify(result, null, 2) +
|
|
88
|
+
"\n\n→ Message sent. Use verbo_list_conversations to see the conversation.";
|
|
88
89
|
}
|
|
89
90
|
case "verbo_list_conversations": {
|
|
90
91
|
const result = await client.listConversations({
|
|
91
92
|
status: args.status as string | undefined,
|
|
92
93
|
limit: args.limit as number | undefined,
|
|
93
94
|
});
|
|
94
|
-
return JSON.stringify(result, null, 2)
|
|
95
|
+
return JSON.stringify(result, null, 2) +
|
|
96
|
+
"\n\n→ Use verbo_get_conversation with a conversation ID to see full messages.";
|
|
95
97
|
}
|
|
96
98
|
case "verbo_get_conversation": {
|
|
97
99
|
const result = await client.getConversation(
|
|
@@ -111,7 +113,8 @@ export async function executeTool(
|
|
|
111
113
|
| Record<string, unknown>
|
|
112
114
|
| undefined,
|
|
113
115
|
});
|
|
114
|
-
return JSON.stringify(result, null, 2)
|
|
116
|
+
return JSON.stringify(result, null, 2) +
|
|
117
|
+
"\n\n→ Agent updated. Use verbo_setup_status to verify the full setup.";
|
|
115
118
|
}
|
|
116
119
|
default:
|
|
117
120
|
return JSON.stringify({ error: `Unknown tool: ${name}` });
|