verbo-mcp-server 0.1.4 → 0.2.1

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.d.ts CHANGED
@@ -14,9 +14,22 @@ export declare class VerboClient {
14
14
  greetingMessage?: string;
15
15
  faqData?: Record<string, string>[];
16
16
  businessHours?: Record<string, unknown>;
17
+ agentName?: string;
18
+ systemInstructions?: string;
19
+ tone?: "professional" | "friendly" | "formal" | "casual";
20
+ language?: string;
21
+ rules?: string[];
17
22
  }): Promise<unknown>;
18
23
  setupCrawl(url: string): Promise<unknown>;
19
24
  setupConnect(): Promise<unknown>;
20
25
  setupStatus(): Promise<unknown>;
21
26
  setupDisconnect(): Promise<unknown>;
27
+ knowledgeCrawl(url: string): Promise<unknown>;
28
+ knowledgeAdd(title: string, content: string): Promise<unknown>;
29
+ knowledgeList(): Promise<unknown>;
30
+ knowledgeDelete(id: string): Promise<unknown>;
31
+ webhookRegister(url: string, events: string[]): Promise<unknown>;
32
+ webhookList(): Promise<unknown>;
33
+ webhookDelete(id: string): Promise<unknown>;
34
+ getUsage(): Promise<unknown>;
22
35
  }
package/dist/client.js CHANGED
@@ -7,43 +7,21 @@ class VerboClient {
7
7
  apiKey;
8
8
  constructor(apiKey, baseUrl) {
9
9
  this.apiKey = apiKey;
10
- this.baseUrl = (baseUrl || "https://www.verbolab.co").replace(/\/$/, "");
10
+ this.baseUrl = (baseUrl || "https://verbolab.co").replace(/\/$/, "");
11
11
  }
12
12
  async request(path, options = {}) {
13
13
  const url = `${this.baseUrl}/api/v1${path}`;
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
- }
14
+ const res = await fetch(url, {
15
+ ...options,
16
+ headers: {
17
+ "Authorization": `Bearer ${this.apiKey}`,
18
+ "Content-Type": "application/json",
19
+ ...options.headers,
20
+ },
21
+ });
22
+ const data = await res.json();
35
23
  if (!res.ok) {
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}`);
24
+ throw new Error(`Verbo API error (${res.status}): ${data.error || "Unknown error"}`);
47
25
  }
48
26
  return data;
49
27
  }
@@ -95,6 +73,45 @@ class VerboClient {
95
73
  body: JSON.stringify({}),
96
74
  });
97
75
  }
76
+ async knowledgeCrawl(url) {
77
+ return this.request("/knowledge/crawl", {
78
+ method: "POST",
79
+ body: JSON.stringify({ url }),
80
+ });
81
+ }
82
+ async knowledgeAdd(title, content) {
83
+ return this.request("/knowledge", {
84
+ method: "POST",
85
+ body: JSON.stringify({ title, content }),
86
+ });
87
+ }
88
+ async knowledgeList() {
89
+ return this.request("/knowledge");
90
+ }
91
+ async knowledgeDelete(id) {
92
+ return this.request("/knowledge", {
93
+ method: "DELETE",
94
+ body: JSON.stringify({ id }),
95
+ });
96
+ }
97
+ async webhookRegister(url, events) {
98
+ return this.request("/webhooks", {
99
+ method: "POST",
100
+ body: JSON.stringify({ url, events }),
101
+ });
102
+ }
103
+ async webhookList() {
104
+ return this.request("/webhooks");
105
+ }
106
+ async webhookDelete(id) {
107
+ return this.request("/webhooks", {
108
+ method: "DELETE",
109
+ body: JSON.stringify({ id }),
110
+ });
111
+ }
112
+ async getUsage() {
113
+ return this.request("/usage");
114
+ }
98
115
  }
99
116
  exports.VerboClient = VerboClient;
100
117
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -7,6 +7,9 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
7
7
  const client_js_1 = require("./client.js");
8
8
  const tools_js_1 = require("./tools.js");
9
9
  const setup_tools_js_1 = require("./setup-tools.js");
10
+ const knowledge_tools_js_1 = require("./knowledge-tools.js");
11
+ const webhook_tools_js_1 = require("./webhook-tools.js");
12
+ const usage_tools_js_1 = require("./usage-tools.js");
10
13
  const apiKey = process.env.VERBO_API_KEY;
11
14
  if (!apiKey) {
12
15
  console.error("VERBO_API_KEY environment variable is required");
@@ -17,26 +20,6 @@ const client = new client_js_1.VerboClient(apiKey, baseUrl);
17
20
  const server = new mcp_js_1.McpServer({
18
21
  name: "Verbo",
19
22
  version: "0.1.0",
20
- }, {
21
- instructions: `Verbo is an AI-powered WhatsApp customer service agent. You plug it into your product and it handles customer conversations automatically — answers questions, classifies intent, escalates complaints, follows up.
22
-
23
- ## Setup workflow (run in order):
24
- 1. verbo_setup_crawl — Crawl the business website to auto-extract name, products, FAQ, hours, tone. This configures the agent.
25
- 2. verbo_setup_connect — Creates a WhatsApp instance. Returns a URL to scan a QR code in the browser.
26
- 3. verbo_setup_status — Check if all steps are done. Shows what's missing.
27
-
28
- ## After setup:
29
- - verbo_send_message — Send a WhatsApp message to any number
30
- - verbo_list_conversations — See recent customer conversations
31
- - verbo_get_conversation — Read messages in a specific conversation
32
- - verbo_agent_status — Check WhatsApp connection and business config
33
- - verbo_configure_agent — Update greeting, FAQ, or business hours
34
- - verbo_setup_disconnect — Disconnect WhatsApp when done
35
-
36
- ## Important:
37
- - Do NOT search the web for information about Verbo. Everything you need is in these tools.
38
- - The crawl step takes 15-30 seconds. This is normal — it fetches multiple pages and uses AI extraction.
39
- - After connecting WhatsApp, the agent starts responding to incoming messages automatically.`,
40
23
  });
41
24
  for (const [name, tool] of Object.entries(tools_js_1.toolDefinitions)) {
42
25
  server.tool(name, tool.description, tool.schema, async (args) => {
@@ -68,6 +51,51 @@ for (const [name, tool] of Object.entries(setup_tools_js_1.setupToolDefinitions)
68
51
  }
69
52
  });
70
53
  }
54
+ for (const [name, tool] of Object.entries(knowledge_tools_js_1.knowledgeToolDefinitions)) {
55
+ server.tool(name, tool.description, tool.schema, async (args) => {
56
+ try {
57
+ const result = await (0, knowledge_tools_js_1.executeKnowledgeTool)(client, name, args);
58
+ return { content: [{ type: "text", text: result }] };
59
+ }
60
+ catch (err) {
61
+ const message = err instanceof Error ? err.message : "Unknown error";
62
+ return {
63
+ content: [{ type: "text", text: `Error: ${message}` }],
64
+ isError: true,
65
+ };
66
+ }
67
+ });
68
+ }
69
+ for (const [name, tool] of Object.entries(webhook_tools_js_1.webhookToolDefinitions)) {
70
+ server.tool(name, tool.description, tool.schema, async (args) => {
71
+ try {
72
+ const result = await (0, webhook_tools_js_1.executeWebhookTool)(client, name, args);
73
+ return { content: [{ type: "text", text: result }] };
74
+ }
75
+ catch (err) {
76
+ const message = err instanceof Error ? err.message : "Unknown error";
77
+ return {
78
+ content: [{ type: "text", text: `Error: ${message}` }],
79
+ isError: true,
80
+ };
81
+ }
82
+ });
83
+ }
84
+ for (const [name, tool] of Object.entries(usage_tools_js_1.usageToolDefinitions)) {
85
+ server.tool(name, tool.description, tool.schema, async (args) => {
86
+ try {
87
+ const result = await (0, usage_tools_js_1.executeUsageTool)(client, name, args);
88
+ return { content: [{ type: "text", text: result }] };
89
+ }
90
+ catch (err) {
91
+ const message = err instanceof Error ? err.message : "Unknown error";
92
+ return {
93
+ content: [{ type: "text", text: `Error: ${message}` }],
94
+ isError: true,
95
+ };
96
+ }
97
+ });
98
+ }
71
99
  async function main() {
72
100
  const transport = new stdio_js_1.StdioServerTransport();
73
101
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import { type VerboClient } from "./client.js";
3
+ export declare const knowledgeToolDefinitions: {
4
+ readonly verbo_knowledge_crawl: {
5
+ readonly description: "Crawl a URL and add the extracted content to the agent's knowledge base. Use this to teach the agent about specific pages, documentation, or product details beyond the initial setup crawl. Rate limited to 3 calls per 10 minutes.";
6
+ readonly schema: {
7
+ readonly url: z.ZodString;
8
+ };
9
+ };
10
+ readonly verbo_knowledge_add: {
11
+ readonly description: "Manually add a knowledge entry to the agent's knowledge base. Use this to add custom FAQs, policies, product details, or any structured information the agent should know.";
12
+ readonly schema: {
13
+ readonly title: z.ZodString;
14
+ readonly content: z.ZodString;
15
+ };
16
+ };
17
+ readonly verbo_knowledge_list: {
18
+ readonly description: "List all entries in the agent's knowledge base. Shows titles and IDs of all stored knowledge.";
19
+ readonly schema: {};
20
+ };
21
+ readonly verbo_knowledge_delete: {
22
+ readonly description: "Delete a knowledge entry from the agent's knowledge base by its ID. Use verbo_knowledge_list to find the ID.";
23
+ readonly schema: {
24
+ readonly id: z.ZodString;
25
+ };
26
+ };
27
+ };
28
+ export type KnowledgeToolName = keyof typeof knowledgeToolDefinitions;
29
+ export declare function executeKnowledgeTool(client: VerboClient, name: string, args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.knowledgeToolDefinitions = void 0;
4
+ exports.executeKnowledgeTool = executeKnowledgeTool;
5
+ // packages/mcp-server/src/knowledge-tools.ts
6
+ const zod_1 = require("zod");
7
+ exports.knowledgeToolDefinitions = {
8
+ verbo_knowledge_crawl: {
9
+ description: "Crawl a URL and add the extracted content to the agent's knowledge base. Use this to teach the agent about specific pages, documentation, or product details beyond the initial setup crawl. Rate limited to 3 calls per 10 minutes.",
10
+ schema: {
11
+ url: zod_1.z.string().describe("URL to crawl and extract content from"),
12
+ },
13
+ },
14
+ verbo_knowledge_add: {
15
+ description: "Manually add a knowledge entry to the agent's knowledge base. Use this to add custom FAQs, policies, product details, or any structured information the agent should know.",
16
+ schema: {
17
+ title: zod_1.z.string().describe("Title or topic of the knowledge entry"),
18
+ content: zod_1.z.string().describe("Full content of the knowledge entry"),
19
+ },
20
+ },
21
+ verbo_knowledge_list: {
22
+ description: "List all entries in the agent's knowledge base. Shows titles and IDs of all stored knowledge.",
23
+ schema: {},
24
+ },
25
+ verbo_knowledge_delete: {
26
+ description: "Delete a knowledge entry from the agent's knowledge base by its ID. Use verbo_knowledge_list to find the ID.",
27
+ schema: {
28
+ id: zod_1.z.string().describe("ID of the knowledge entry to delete"),
29
+ },
30
+ },
31
+ };
32
+ async function executeKnowledgeTool(client, name, args) {
33
+ switch (name) {
34
+ case "verbo_knowledge_crawl": {
35
+ const result = await client.knowledgeCrawl(args.url);
36
+ return JSON.stringify(result, null, 2) +
37
+ "\n\n→ Content extracted and added to knowledge base. Use verbo_knowledge_list to see all entries.";
38
+ }
39
+ case "verbo_knowledge_add": {
40
+ const result = await client.knowledgeAdd(args.title, args.content);
41
+ return JSON.stringify(result, null, 2) +
42
+ "\n\n→ Knowledge entry added. Use verbo_knowledge_list to see all entries.";
43
+ }
44
+ case "verbo_knowledge_list": {
45
+ const result = await client.knowledgeList();
46
+ return JSON.stringify(result, null, 2) +
47
+ "\n\n→ Use verbo_knowledge_delete with an ID to remove an entry.";
48
+ }
49
+ case "verbo_knowledge_delete": {
50
+ const result = await client.knowledgeDelete(args.id);
51
+ return JSON.stringify(result, null, 2) +
52
+ "\n\n→ Knowledge entry deleted.";
53
+ }
54
+ default:
55
+ return JSON.stringify({ error: `Unknown knowledge tool: ${name}` });
56
+ }
57
+ }
58
+ //# sourceMappingURL=knowledge-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-tools.js","sourceRoot":"","sources":["../src/knowledge-tools.ts"],"names":[],"mappings":";;;AAoCA,oDAgCC;AApED,6CAA6C;AAC7C,6BAAwB;AAGX,QAAA,wBAAwB,GAAG;IACtC,qBAAqB,EAAE;QACrB,WAAW,EACT,sOAAsO;QACxO,MAAM,EAAE;YACN,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;SAClE;KACF;IACD,mBAAmB,EAAE;QACnB,WAAW,EACT,4KAA4K;QAC9K,MAAM,EAAE;YACN,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YACnE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SACpE;KACF;IACD,oBAAoB,EAAE;QACpB,WAAW,EACT,+FAA+F;QACjG,MAAM,EAAE,EAAE;KACX;IACD,sBAAsB,EAAE;QACtB,WAAW,EACT,8GAA8G;QAChH,MAAM,EAAE;YACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SAC/D;KACF;CACO,CAAC;AAIJ,KAAK,UAAU,oBAAoB,CACxC,MAAmB,EACnB,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,mGAAmG,CAAC;QACxG,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CACtC,IAAI,CAAC,KAAe,EACpB,IAAI,CAAC,OAAiB,CACvB,CAAC;YACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,2EAA2E,CAAC;QAChF,CAAC;QACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,iEAAiE,CAAC;QACtE,CAAC;QACD,KAAK,wBAAwB,CAAC,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,EAAY,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,gCAAgC,CAAC;QACrC,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,2BAA2B,IAAI,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC"}
@@ -27,41 +27,20 @@ exports.setupToolDefinitions = {
27
27
  async function executeSetupTool(client, name, args) {
28
28
  switch (name) {
29
29
  case "verbo_setup_crawl": {
30
- try {
31
- const result = await client.setupCrawl(args.url);
32
- return JSON.stringify(result, null, 2) +
33
- "\n\n→ Business configured from website. Next: run verbo_setup_connect to connect WhatsApp.";
34
- }
35
- catch (err) {
36
- const msg = err instanceof Error ? err.message : String(err);
37
- if (msg.includes("422") || msg.includes("enough content") || msg.includes("SPA")) {
38
- return `Crawl failed: the website appears to be a Single Page App (React, Vue, Angular) that renders via JavaScript. The crawler can only read server-rendered HTML.\n\n→ Use verbo_configure_agent instead to set up the agent manually. Ask the user about their business and set greeting_message, faq (array of {question, answer}), and business_hours.`;
39
- }
40
- throw err;
41
- }
30
+ const result = await client.setupCrawl(args.url);
31
+ return JSON.stringify(result, null, 2);
42
32
  }
43
33
  case "verbo_setup_connect": {
44
34
  const result = await client.setupConnect();
45
- const data = result;
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.`;
35
+ return JSON.stringify(result, null, 2);
49
36
  }
50
37
  case "verbo_setup_status": {
51
38
  const result = await client.setupStatus();
52
- const data = result;
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.";
39
+ return JSON.stringify(result, null, 2);
60
40
  }
61
41
  case "verbo_setup_disconnect": {
62
42
  const result = await client.setupDisconnect();
63
- return JSON.stringify(result, null, 2) +
64
- "\n\n→ WhatsApp disconnected. The phone number is free to use elsewhere.";
43
+ return JSON.stringify(result, null, 2);
65
44
  }
66
45
  default:
67
46
  return JSON.stringify({ error: `Unknown setup tool: ${name}` });
@@ -1 +1 @@
1
- {"version":3,"file":"setup-tools.js","sourceRoot":"","sources":["../src/setup-tools.ts"],"names":[],"mappings":";;;AA+BA,4CA6CC;AA5ED,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,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;gBAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACpC,4FAA4F,CAAC;YACjG,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjF,OAAO,sVAAsV,CAAC;gBAChW,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,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"}
1
+ {"version":3,"file":"setup-tools.js","sourceRoot":"","sources":["../src/setup-tools.ts"],"names":[],"mappings":";;;AA+BA,4CAyBC;AAxDD,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,CAAC;QACzC,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;YAC3C,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,WAAW,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,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,CAAC;QACzC,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
package/dist/tools.d.ts CHANGED
@@ -30,7 +30,7 @@ export declare const toolDefinitions: {
30
30
  readonly schema: {};
31
31
  };
32
32
  readonly verbo_configure_agent: {
33
- readonly description: "Configure the AI agent behavior. Use this to manually set up the agent when verbo_setup_crawl can't extract info (e.g. SPA sites). You can set any combination of greeting, FAQ, and hours.";
33
+ readonly description: "Configure the AI agent behavior. Set greeting message, FAQ, business hours, agent name, system instructions, tone, language, and custom rules.";
34
34
  readonly schema: {
35
35
  readonly greeting_message: z.ZodOptional<z.ZodString>;
36
36
  readonly faq: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -38,6 +38,16 @@ export declare const toolDefinitions: {
38
38
  answer: z.ZodString;
39
39
  }, z.core.$strip>>>;
40
40
  readonly business_hours: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
41
+ readonly agent_name: z.ZodOptional<z.ZodString>;
42
+ readonly system_instructions: z.ZodOptional<z.ZodString>;
43
+ readonly tone: z.ZodOptional<z.ZodEnum<{
44
+ professional: "professional";
45
+ friendly: "friendly";
46
+ formal: "formal";
47
+ casual: "casual";
48
+ }>>;
49
+ readonly language: z.ZodOptional<z.ZodString>;
50
+ readonly rules: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
51
  };
42
52
  };
43
53
  };
package/dist/tools.js CHANGED
@@ -42,23 +42,43 @@ exports.toolDefinitions = {
42
42
  schema: {},
43
43
  },
44
44
  verbo_configure_agent: {
45
- description: "Configure the AI agent behavior. Use this to manually set up the agent when verbo_setup_crawl can't extract info (e.g. SPA sites). You can set any combination of greeting, FAQ, and hours.",
45
+ description: "Configure the AI agent behavior. Set greeting message, FAQ, business hours, agent name, system instructions, tone, language, and custom rules.",
46
46
  schema: {
47
47
  greeting_message: zod_1.z
48
48
  .string()
49
49
  .optional()
50
- .describe("Greeting message the AI sends to new customers on WhatsApp (e.g. 'Olá! Bem-vindo à Scinti. Como posso ajudar?')"),
50
+ .describe("Greeting message for new customers"),
51
51
  faq: zod_1.z
52
52
  .array(zod_1.z.object({
53
- question: zod_1.z.string().describe("A question customers commonly ask"),
54
- answer: zod_1.z.string().describe("The answer the AI should give"),
53
+ question: zod_1.z.string(),
54
+ answer: zod_1.z.string(),
55
55
  }))
56
56
  .optional()
57
- .describe("List of FAQ entries the AI uses to answer customer questions"),
57
+ .describe("Frequently asked questions"),
58
58
  business_hours: zod_1.z
59
59
  .record(zod_1.z.string(), zod_1.z.string())
60
60
  .optional()
61
- .describe("Business hours per weekday (e.g. { monday: '9:00-18:00', saturday: '9:00-13:00' })"),
61
+ .describe("Business hours (e.g. { monday: '9:00-18:00' })"),
62
+ agent_name: zod_1.z
63
+ .string()
64
+ .optional()
65
+ .describe("Display name for the AI agent (e.g. 'Sofia', 'Assistente Verbo')"),
66
+ system_instructions: zod_1.z
67
+ .string()
68
+ .optional()
69
+ .describe("Custom system instructions that define how the agent behaves and responds"),
70
+ tone: zod_1.z
71
+ .enum(["professional", "friendly", "formal", "casual"])
72
+ .optional()
73
+ .describe("Tone of voice for the agent's responses"),
74
+ language: zod_1.z
75
+ .string()
76
+ .optional()
77
+ .describe("Primary language for responses (e.g. 'pt-BR', 'en-US', 'es')"),
78
+ rules: zod_1.z
79
+ .array(zod_1.z.string())
80
+ .optional()
81
+ .describe("List of custom rules the agent must follow (e.g. 'Never mention competitors')"),
62
82
  },
63
83
  },
64
84
  };
@@ -66,16 +86,14 @@ async function executeTool(client, name, args) {
66
86
  switch (name) {
67
87
  case "verbo_send_message": {
68
88
  const result = await client.sendMessage(args.to, args.message, args.image_url);
69
- return JSON.stringify(result, null, 2) +
70
- "\n\n→ Message sent. Use verbo_list_conversations to see the conversation.";
89
+ return JSON.stringify(result, null, 2);
71
90
  }
72
91
  case "verbo_list_conversations": {
73
92
  const result = await client.listConversations({
74
93
  status: args.status,
75
94
  limit: args.limit,
76
95
  });
77
- return JSON.stringify(result, null, 2) +
78
- "\n\n→ Use verbo_get_conversation with a conversation ID to see full messages.";
96
+ return JSON.stringify(result, null, 2);
79
97
  }
80
98
  case "verbo_get_conversation": {
81
99
  const result = await client.getConversation(args.conversation_id);
@@ -90,9 +108,13 @@ async function executeTool(client, name, args) {
90
108
  greetingMessage: args.greeting_message,
91
109
  faqData: args.faq,
92
110
  businessHours: args.business_hours,
111
+ agentName: args.agent_name,
112
+ systemInstructions: args.system_instructions,
113
+ tone: args.tone,
114
+ language: args.language,
115
+ rules: args.rules,
93
116
  });
94
- return JSON.stringify(result, null, 2) +
95
- "\n\n→ Agent updated. Use verbo_setup_status to verify the full setup.";
117
+ return JSON.stringify(result, null, 2);
96
118
  }
97
119
  default:
98
120
  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,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,6LAA6L;QAC/L,MAAM,EAAE;YACN,gBAAgB,EAAE,OAAC;iBAChB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iHAAiH,CAAC;YAC9H,GAAG,EAAE,OAAC;iBACH,KAAK,CACJ,OAAC,CAAC,MAAM,CAAC;gBACP,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;gBAClE,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;aAC7D,CAAC,CACH;iBACA,QAAQ,EAAE;iBACV,QAAQ,CAAC,8DAA8D,CAAC;YAC3E,cAAc,EAAE,OAAC;iBACd,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC;iBAC9B,QAAQ,EAAE;iBACV,QAAQ,CACP,oFAAoF,CACrF;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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type VerboClient } from "./client.js";
2
+ export declare const usageToolDefinitions: {
3
+ readonly verbo_usage: {
4
+ readonly description: "Get usage statistics for the current billing period. Shows messages sent, conversations handled, AI calls made, and remaining quota.";
5
+ readonly schema: {};
6
+ };
7
+ };
8
+ export type UsageToolName = keyof typeof usageToolDefinitions;
9
+ export declare function executeUsageTool(client: VerboClient, name: string, _args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usageToolDefinitions = void 0;
4
+ exports.executeUsageTool = executeUsageTool;
5
+ exports.usageToolDefinitions = {
6
+ verbo_usage: {
7
+ description: "Get usage statistics for the current billing period. Shows messages sent, conversations handled, AI calls made, and remaining quota.",
8
+ schema: {},
9
+ },
10
+ };
11
+ async function executeUsageTool(client, name, _args) {
12
+ switch (name) {
13
+ case "verbo_usage": {
14
+ const result = await client.getUsage();
15
+ return JSON.stringify(result, null, 2);
16
+ }
17
+ default:
18
+ return JSON.stringify({ error: `Unknown usage tool: ${name}` });
19
+ }
20
+ }
21
+ //# sourceMappingURL=usage-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-tools.js","sourceRoot":"","sources":["../src/usage-tools.ts"],"names":[],"mappings":";;;AAaA,4CAaC;AAvBY,QAAA,oBAAoB,GAAG;IAClC,WAAW,EAAE;QACX,WAAW,EACT,sIAAsI;QACxI,MAAM,EAAE,EAAE;KACX;CACO,CAAC;AAIJ,KAAK,UAAU,gBAAgB,CACpC,MAAmB,EACnB,IAAY,EACZ,KAA8B;IAE9B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import { type VerboClient } from "./client.js";
3
+ export declare const webhookToolDefinitions: {
4
+ readonly verbo_webhook_register: {
5
+ readonly description: "Register a webhook URL to receive real-time events from Verbo. Supported events: message.received, message.sent, conversation.opened, escalation.created.";
6
+ readonly schema: {
7
+ readonly url: z.ZodString;
8
+ readonly events: z.ZodArray<z.ZodString>;
9
+ };
10
+ };
11
+ readonly verbo_webhook_list: {
12
+ readonly description: "List all registered webhooks. Shows URLs, subscribed events, and IDs.";
13
+ readonly schema: {};
14
+ };
15
+ readonly verbo_webhook_delete: {
16
+ readonly description: "Delete a registered webhook by its ID. Use verbo_webhook_list to find the ID.";
17
+ readonly schema: {
18
+ readonly id: z.ZodString;
19
+ };
20
+ };
21
+ };
22
+ export type WebhookToolName = keyof typeof webhookToolDefinitions;
23
+ export declare function executeWebhookTool(client: VerboClient, name: string, args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webhookToolDefinitions = void 0;
4
+ exports.executeWebhookTool = executeWebhookTool;
5
+ // packages/mcp-server/src/webhook-tools.ts
6
+ const zod_1 = require("zod");
7
+ exports.webhookToolDefinitions = {
8
+ verbo_webhook_register: {
9
+ description: "Register a webhook URL to receive real-time events from Verbo. Supported events: message.received, message.sent, conversation.opened, escalation.created.",
10
+ schema: {
11
+ url: zod_1.z.string().describe("HTTPS URL to receive webhook POST requests"),
12
+ events: zod_1.z
13
+ .array(zod_1.z.string())
14
+ .describe("List of events to subscribe to (e.g. ['message.received', 'conversation.opened'])"),
15
+ },
16
+ },
17
+ verbo_webhook_list: {
18
+ description: "List all registered webhooks. Shows URLs, subscribed events, and IDs.",
19
+ schema: {},
20
+ },
21
+ verbo_webhook_delete: {
22
+ description: "Delete a registered webhook by its ID. Use verbo_webhook_list to find the ID.",
23
+ schema: {
24
+ id: zod_1.z.string().describe("ID of the webhook to delete"),
25
+ },
26
+ },
27
+ };
28
+ async function executeWebhookTool(client, name, args) {
29
+ switch (name) {
30
+ case "verbo_webhook_register": {
31
+ const result = await client.webhookRegister(args.url, args.events);
32
+ return JSON.stringify(result, null, 2) +
33
+ "\n\n→ Webhook registered. Verbo will POST events to your URL. Use verbo_webhook_list to see all webhooks.";
34
+ }
35
+ case "verbo_webhook_list": {
36
+ const result = await client.webhookList();
37
+ return JSON.stringify(result, null, 2) +
38
+ "\n\n→ Use verbo_webhook_delete with an ID to remove a webhook.";
39
+ }
40
+ case "verbo_webhook_delete": {
41
+ const result = await client.webhookDelete(args.id);
42
+ return JSON.stringify(result, null, 2) +
43
+ "\n\n→ Webhook deleted. No more events will be sent to that URL.";
44
+ }
45
+ default:
46
+ return JSON.stringify({ error: `Unknown webhook tool: ${name}` });
47
+ }
48
+ }
49
+ //# sourceMappingURL=webhook-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-tools.js","sourceRoot":"","sources":["../src/webhook-tools.ts"],"names":[],"mappings":";;;AAiCA,gDA2BC;AA5DD,2CAA2C;AAC3C,6BAAwB;AAGX,QAAA,sBAAsB,GAAG;IACpC,sBAAsB,EAAE;QACtB,WAAW,EACT,2JAA2J;QAC7J,MAAM,EAAE;YACN,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;YACtE,MAAM,EAAE,OAAC;iBACN,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,CACP,mFAAmF,CACpF;SACJ;KACF;IACD,kBAAkB,EAAE;QAClB,WAAW,EACT,uEAAuE;QACzE,MAAM,EAAE,EAAE;KACX;IACD,oBAAoB,EAAE;QACpB,WAAW,EACT,+EAA+E;QACjF,MAAM,EAAE;YACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;SACvD;KACF;CACO,CAAC;AAIJ,KAAK,UAAU,kBAAkB,CACtC,MAAmB,EACnB,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,wBAAwB,CAAC,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CACzC,IAAI,CAAC,GAAa,EAClB,IAAI,CAAC,MAAkB,CACxB,CAAC;YACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,2GAA2G,CAAC;QAChH,CAAC;QACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,gEAAgE,CAAC;QACrE,CAAC;QACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAY,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpC,iEAAiE,CAAC;QACtE,CAAC;QACD;YACE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,yBAAyB,IAAI,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verbo-mcp-server",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "Verbo MCP Server — AI WhatsApp agent for developers",
5
5
  "bin": {
6
6
  "verbo-mcp": "./dist/index.js"
package/src/client.ts CHANGED
@@ -6,55 +6,26 @@ export class VerboClient {
6
6
 
7
7
  constructor(apiKey: string, baseUrl?: string) {
8
8
  this.apiKey = apiKey;
9
- this.baseUrl = (baseUrl || "https://www.verbolab.co").replace(/\/$/, "");
9
+ this.baseUrl = (baseUrl || "https://verbolab.co").replace(/\/$/, "");
10
10
  }
11
11
 
12
12
  private async request(path: string, options: RequestInit = {}): Promise<unknown> {
13
13
  const url = `${this.baseUrl}/api/v1${path}`;
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
- }
14
+ const res = await fetch(url, {
15
+ ...options,
16
+ headers: {
17
+ "Authorization": `Bearer ${this.apiKey}`,
18
+ "Content-Type": "application/json",
19
+ ...options.headers,
20
+ },
21
+ });
29
22
 
30
- let data: unknown;
31
- try {
32
- data = await res.json();
33
- } catch {
23
+ const data = await res.json();
24
+ if (!res.ok) {
34
25
  throw new Error(
35
- `Verbo API returned invalid response (HTTP ${res.status}). The server may be temporarily unavailable try again in a moment.`
26
+ `Verbo API error (${res.status}): ${(data as { error?: string }).error || "Unknown error"}`
36
27
  );
37
28
  }
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
- }
58
29
  return data;
59
30
  }
60
31
 
@@ -85,6 +56,11 @@ export class VerboClient {
85
56
  greetingMessage?: string;
86
57
  faqData?: Record<string, string>[];
87
58
  businessHours?: Record<string, unknown>;
59
+ agentName?: string;
60
+ systemInstructions?: string;
61
+ tone?: "professional" | "friendly" | "formal" | "casual";
62
+ language?: string;
63
+ rules?: string[];
88
64
  }) {
89
65
  return this.request("/agent/configure", {
90
66
  method: "POST",
@@ -116,4 +92,51 @@ export class VerboClient {
116
92
  body: JSON.stringify({}),
117
93
  });
118
94
  }
95
+
96
+ async knowledgeCrawl(url: string) {
97
+ return this.request("/knowledge/crawl", {
98
+ method: "POST",
99
+ body: JSON.stringify({ url }),
100
+ });
101
+ }
102
+
103
+ async knowledgeAdd(title: string, content: string) {
104
+ return this.request("/knowledge", {
105
+ method: "POST",
106
+ body: JSON.stringify({ title, content }),
107
+ });
108
+ }
109
+
110
+ async knowledgeList() {
111
+ return this.request("/knowledge");
112
+ }
113
+
114
+ async knowledgeDelete(id: string) {
115
+ return this.request("/knowledge", {
116
+ method: "DELETE",
117
+ body: JSON.stringify({ id }),
118
+ });
119
+ }
120
+
121
+ async webhookRegister(url: string, events: string[]) {
122
+ return this.request("/webhooks", {
123
+ method: "POST",
124
+ body: JSON.stringify({ url, events }),
125
+ });
126
+ }
127
+
128
+ async webhookList() {
129
+ return this.request("/webhooks");
130
+ }
131
+
132
+ async webhookDelete(id: string) {
133
+ return this.request("/webhooks", {
134
+ method: "DELETE",
135
+ body: JSON.stringify({ id }),
136
+ });
137
+ }
138
+
139
+ async getUsage() {
140
+ return this.request("/usage");
141
+ }
119
142
  }
package/src/index.ts CHANGED
@@ -5,6 +5,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
5
5
  import { VerboClient } from "./client.js";
6
6
  import { toolDefinitions, executeTool, type ToolName } from "./tools.js";
7
7
  import { setupToolDefinitions, executeSetupTool } from "./setup-tools.js";
8
+ import { knowledgeToolDefinitions, executeKnowledgeTool } from "./knowledge-tools.js";
9
+ import { webhookToolDefinitions, executeWebhookTool } from "./webhook-tools.js";
10
+ import { usageToolDefinitions, executeUsageTool } from "./usage-tools.js";
8
11
 
9
12
  const apiKey = process.env.VERBO_API_KEY;
10
13
  if (!apiKey) {
@@ -15,33 +18,10 @@ if (!apiKey) {
15
18
  const baseUrl = process.env.VERBO_API_URL;
16
19
  const client = new VerboClient(apiKey, baseUrl);
17
20
 
18
- const server = new McpServer(
19
- {
20
- name: "Verbo",
21
- version: "0.1.0",
22
- },
23
- {
24
- instructions: `Verbo is an AI-powered WhatsApp customer service agent. You plug it into your product and it handles customer conversations automatically — answers questions, classifies intent, escalates complaints, follows up.
25
-
26
- ## Setup workflow (run in order):
27
- 1. verbo_setup_crawl — Crawl the business website to auto-extract name, products, FAQ, hours, tone. This configures the agent.
28
- 2. verbo_setup_connect — Creates a WhatsApp instance. Returns a URL to scan a QR code in the browser.
29
- 3. verbo_setup_status — Check if all steps are done. Shows what's missing.
30
-
31
- ## After setup:
32
- - verbo_send_message — Send a WhatsApp message to any number
33
- - verbo_list_conversations — See recent customer conversations
34
- - verbo_get_conversation — Read messages in a specific conversation
35
- - verbo_agent_status — Check WhatsApp connection and business config
36
- - verbo_configure_agent — Update greeting, FAQ, or business hours
37
- - verbo_setup_disconnect — Disconnect WhatsApp when done
38
-
39
- ## Important:
40
- - Do NOT search the web for information about Verbo. Everything you need is in these tools.
41
- - The crawl step takes 15-30 seconds. This is normal — it fetches multiple pages and uses AI extraction.
42
- - After connecting WhatsApp, the agent starts responding to incoming messages automatically.`,
43
- },
44
- );
21
+ const server = new McpServer({
22
+ name: "Verbo",
23
+ version: "0.1.0",
24
+ });
45
25
 
46
26
  for (const [name, tool] of Object.entries(toolDefinitions)) {
47
27
  server.tool(name, tool.description, tool.schema, async (args: Record<string, unknown>) => {
@@ -79,6 +59,54 @@ for (const [name, tool] of Object.entries(setupToolDefinitions)) {
79
59
  });
80
60
  }
81
61
 
62
+ for (const [name, tool] of Object.entries(knowledgeToolDefinitions)) {
63
+ server.tool(name, tool.description, tool.schema, async (args: Record<string, unknown>) => {
64
+ try {
65
+ const result = await executeKnowledgeTool(client, name, args);
66
+ return { content: [{ type: "text" as const, text: result }] };
67
+ } catch (err) {
68
+ const message =
69
+ err instanceof Error ? err.message : "Unknown error";
70
+ return {
71
+ content: [{ type: "text" as const, text: `Error: ${message}` }],
72
+ isError: true,
73
+ };
74
+ }
75
+ });
76
+ }
77
+
78
+ for (const [name, tool] of Object.entries(webhookToolDefinitions)) {
79
+ server.tool(name, tool.description, tool.schema, async (args: Record<string, unknown>) => {
80
+ try {
81
+ const result = await executeWebhookTool(client, name, args);
82
+ return { content: [{ type: "text" as const, text: result }] };
83
+ } catch (err) {
84
+ const message =
85
+ err instanceof Error ? err.message : "Unknown error";
86
+ return {
87
+ content: [{ type: "text" as const, text: `Error: ${message}` }],
88
+ isError: true,
89
+ };
90
+ }
91
+ });
92
+ }
93
+
94
+ for (const [name, tool] of Object.entries(usageToolDefinitions)) {
95
+ server.tool(name, tool.description, tool.schema, async (args: Record<string, unknown>) => {
96
+ try {
97
+ const result = await executeUsageTool(client, name, args);
98
+ return { content: [{ type: "text" as const, text: result }] };
99
+ } catch (err) {
100
+ const message =
101
+ err instanceof Error ? err.message : "Unknown error";
102
+ return {
103
+ content: [{ type: "text" as const, text: `Error: ${message}` }],
104
+ isError: true,
105
+ };
106
+ }
107
+ });
108
+ }
109
+
82
110
  async function main() {
83
111
  const transport = new StdioServerTransport();
84
112
  await server.connect(transport);
@@ -0,0 +1,69 @@
1
+ // packages/mcp-server/src/knowledge-tools.ts
2
+ import { z } from "zod";
3
+ import { type VerboClient } from "./client.js";
4
+
5
+ export const knowledgeToolDefinitions = {
6
+ verbo_knowledge_crawl: {
7
+ description:
8
+ "Crawl a URL and add the extracted content to the agent's knowledge base. Use this to teach the agent about specific pages, documentation, or product details beyond the initial setup crawl. Rate limited to 3 calls per 10 minutes.",
9
+ schema: {
10
+ url: z.string().describe("URL to crawl and extract content from"),
11
+ },
12
+ },
13
+ verbo_knowledge_add: {
14
+ description:
15
+ "Manually add a knowledge entry to the agent's knowledge base. Use this to add custom FAQs, policies, product details, or any structured information the agent should know.",
16
+ schema: {
17
+ title: z.string().describe("Title or topic of the knowledge entry"),
18
+ content: z.string().describe("Full content of the knowledge entry"),
19
+ },
20
+ },
21
+ verbo_knowledge_list: {
22
+ description:
23
+ "List all entries in the agent's knowledge base. Shows titles and IDs of all stored knowledge.",
24
+ schema: {},
25
+ },
26
+ verbo_knowledge_delete: {
27
+ description:
28
+ "Delete a knowledge entry from the agent's knowledge base by its ID. Use verbo_knowledge_list to find the ID.",
29
+ schema: {
30
+ id: z.string().describe("ID of the knowledge entry to delete"),
31
+ },
32
+ },
33
+ } as const;
34
+
35
+ export type KnowledgeToolName = keyof typeof knowledgeToolDefinitions;
36
+
37
+ export async function executeKnowledgeTool(
38
+ client: VerboClient,
39
+ name: string,
40
+ args: Record<string, unknown>,
41
+ ): Promise<string> {
42
+ switch (name) {
43
+ case "verbo_knowledge_crawl": {
44
+ const result = await client.knowledgeCrawl(args.url as string);
45
+ return JSON.stringify(result, null, 2) +
46
+ "\n\n→ Content extracted and added to knowledge base. Use verbo_knowledge_list to see all entries.";
47
+ }
48
+ case "verbo_knowledge_add": {
49
+ const result = await client.knowledgeAdd(
50
+ args.title as string,
51
+ args.content as string,
52
+ );
53
+ return JSON.stringify(result, null, 2) +
54
+ "\n\n→ Knowledge entry added. Use verbo_knowledge_list to see all entries.";
55
+ }
56
+ case "verbo_knowledge_list": {
57
+ const result = await client.knowledgeList();
58
+ return JSON.stringify(result, null, 2) +
59
+ "\n\n→ Use verbo_knowledge_delete with an ID to remove an entry.";
60
+ }
61
+ case "verbo_knowledge_delete": {
62
+ const result = await client.knowledgeDelete(args.id as string);
63
+ return JSON.stringify(result, null, 2) +
64
+ "\n\n→ Knowledge entry deleted.";
65
+ }
66
+ default:
67
+ return JSON.stringify({ error: `Unknown knowledge tool: ${name}` });
68
+ }
69
+ }
@@ -36,40 +36,20 @@ export async function executeSetupTool(
36
36
  ): Promise<string> {
37
37
  switch (name) {
38
38
  case "verbo_setup_crawl": {
39
- try {
40
- const result = await client.setupCrawl(args.url as string);
41
- return JSON.stringify(result, null, 2) +
42
- "\n\n→ Business configured from website. Next: run verbo_setup_connect to connect WhatsApp.";
43
- } catch (err) {
44
- const msg = err instanceof Error ? err.message : String(err);
45
- if (msg.includes("422") || msg.includes("enough content") || msg.includes("SPA")) {
46
- return `Crawl failed: the website appears to be a Single Page App (React, Vue, Angular) that renders via JavaScript. The crawler can only read server-rendered HTML.\n\n→ Use verbo_configure_agent instead to set up the agent manually. Ask the user about their business and set greeting_message, faq (array of {question, answer}), and business_hours.`;
47
- }
48
- throw err;
49
- }
39
+ const result = await client.setupCrawl(args.url as string);
40
+ return JSON.stringify(result, null, 2);
50
41
  }
51
42
  case "verbo_setup_connect": {
52
43
  const result = await client.setupConnect();
53
- const data = result as Record<string, unknown>;
54
- const connectUrl = data.connectUrl || "";
55
- return JSON.stringify(result, null, 2) +
56
- `\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.`;
44
+ return JSON.stringify(result, null, 2);
57
45
  }
58
46
  case "verbo_setup_status": {
59
47
  const result = await client.setupStatus();
60
- const data = result as Record<string, unknown>;
61
- const ready = data.ready;
62
- if (ready) {
63
- return JSON.stringify(result, null, 2) +
64
- "\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.";
65
- }
66
- return JSON.stringify(result, null, 2) +
67
- "\n\n→ Setup incomplete. Check the steps above and run the missing ones.";
48
+ return JSON.stringify(result, null, 2);
68
49
  }
69
50
  case "verbo_setup_disconnect": {
70
51
  const result = await client.setupDisconnect();
71
- return JSON.stringify(result, null, 2) +
72
- "\n\n→ WhatsApp disconnected. The phone number is free to use elsewhere.";
52
+ return JSON.stringify(result, null, 2);
73
53
  }
74
54
  default:
75
55
  return JSON.stringify({ error: `Unknown setup tool: ${name}` });
package/src/tools.ts CHANGED
@@ -45,27 +45,47 @@ export const toolDefinitions = {
45
45
  },
46
46
  verbo_configure_agent: {
47
47
  description:
48
- "Configure the AI agent behavior. Use this to manually set up the agent when verbo_setup_crawl can't extract info (e.g. SPA sites). You can set any combination of greeting, FAQ, and hours.",
48
+ "Configure the AI agent behavior. Set greeting message, FAQ, business hours, agent name, system instructions, tone, language, and custom rules.",
49
49
  schema: {
50
50
  greeting_message: z
51
51
  .string()
52
52
  .optional()
53
- .describe("Greeting message the AI sends to new customers on WhatsApp (e.g. 'Olá! Bem-vindo à Scinti. Como posso ajudar?')"),
53
+ .describe("Greeting message for new customers"),
54
54
  faq: z
55
55
  .array(
56
56
  z.object({
57
- question: z.string().describe("A question customers commonly ask"),
58
- answer: z.string().describe("The answer the AI should give"),
57
+ question: z.string(),
58
+ answer: z.string(),
59
59
  }),
60
60
  )
61
61
  .optional()
62
- .describe("List of FAQ entries the AI uses to answer customer questions"),
62
+ .describe("Frequently asked questions"),
63
63
  business_hours: z
64
64
  .record(z.string(), z.string())
65
65
  .optional()
66
66
  .describe(
67
- "Business hours per weekday (e.g. { monday: '9:00-18:00', saturday: '9:00-13:00' })",
67
+ "Business hours (e.g. { monday: '9:00-18:00' })",
68
68
  ),
69
+ agent_name: z
70
+ .string()
71
+ .optional()
72
+ .describe("Display name for the AI agent (e.g. 'Sofia', 'Assistente Verbo')"),
73
+ system_instructions: z
74
+ .string()
75
+ .optional()
76
+ .describe("Custom system instructions that define how the agent behaves and responds"),
77
+ tone: z
78
+ .enum(["professional", "friendly", "formal", "casual"])
79
+ .optional()
80
+ .describe("Tone of voice for the agent's responses"),
81
+ language: z
82
+ .string()
83
+ .optional()
84
+ .describe("Primary language for responses (e.g. 'pt-BR', 'en-US', 'es')"),
85
+ rules: z
86
+ .array(z.string())
87
+ .optional()
88
+ .describe("List of custom rules the agent must follow (e.g. 'Never mention competitors')"),
69
89
  },
70
90
  },
71
91
  } as const;
@@ -84,16 +104,14 @@ export async function executeTool(
84
104
  args.message as string,
85
105
  args.image_url as string | undefined,
86
106
  );
87
- return JSON.stringify(result, null, 2) +
88
- "\n\n→ Message sent. Use verbo_list_conversations to see the conversation.";
107
+ return JSON.stringify(result, null, 2);
89
108
  }
90
109
  case "verbo_list_conversations": {
91
110
  const result = await client.listConversations({
92
111
  status: args.status as string | undefined,
93
112
  limit: args.limit as number | undefined,
94
113
  });
95
- return JSON.stringify(result, null, 2) +
96
- "\n\n→ Use verbo_get_conversation with a conversation ID to see full messages.";
114
+ return JSON.stringify(result, null, 2);
97
115
  }
98
116
  case "verbo_get_conversation": {
99
117
  const result = await client.getConversation(
@@ -112,9 +130,13 @@ export async function executeTool(
112
130
  businessHours: args.business_hours as
113
131
  | Record<string, unknown>
114
132
  | undefined,
133
+ agentName: args.agent_name as string | undefined,
134
+ systemInstructions: args.system_instructions as string | undefined,
135
+ tone: args.tone as "professional" | "friendly" | "formal" | "casual" | undefined,
136
+ language: args.language as string | undefined,
137
+ rules: args.rules as string[] | undefined,
115
138
  });
116
- return JSON.stringify(result, null, 2) +
117
- "\n\n→ Agent updated. Use verbo_setup_status to verify the full setup.";
139
+ return JSON.stringify(result, null, 2);
118
140
  }
119
141
  default:
120
142
  return JSON.stringify({ error: `Unknown tool: ${name}` });
@@ -0,0 +1,27 @@
1
+ // packages/mcp-server/src/usage-tools.ts
2
+ import { type VerboClient } from "./client.js";
3
+
4
+ export const usageToolDefinitions = {
5
+ verbo_usage: {
6
+ description:
7
+ "Get usage statistics for the current billing period. Shows messages sent, conversations handled, AI calls made, and remaining quota.",
8
+ schema: {},
9
+ },
10
+ } as const;
11
+
12
+ export type UsageToolName = keyof typeof usageToolDefinitions;
13
+
14
+ export async function executeUsageTool(
15
+ client: VerboClient,
16
+ name: string,
17
+ _args: Record<string, unknown>,
18
+ ): Promise<string> {
19
+ switch (name) {
20
+ case "verbo_usage": {
21
+ const result = await client.getUsage();
22
+ return JSON.stringify(result, null, 2);
23
+ }
24
+ default:
25
+ return JSON.stringify({ error: `Unknown usage tool: ${name}` });
26
+ }
27
+ }
@@ -0,0 +1,61 @@
1
+ // packages/mcp-server/src/webhook-tools.ts
2
+ import { z } from "zod";
3
+ import { type VerboClient } from "./client.js";
4
+
5
+ export const webhookToolDefinitions = {
6
+ verbo_webhook_register: {
7
+ description:
8
+ "Register a webhook URL to receive real-time events from Verbo. Supported events: message.received, message.sent, conversation.opened, escalation.created.",
9
+ schema: {
10
+ url: z.string().describe("HTTPS URL to receive webhook POST requests"),
11
+ events: z
12
+ .array(z.string())
13
+ .describe(
14
+ "List of events to subscribe to (e.g. ['message.received', 'conversation.opened'])",
15
+ ),
16
+ },
17
+ },
18
+ verbo_webhook_list: {
19
+ description:
20
+ "List all registered webhooks. Shows URLs, subscribed events, and IDs.",
21
+ schema: {},
22
+ },
23
+ verbo_webhook_delete: {
24
+ description:
25
+ "Delete a registered webhook by its ID. Use verbo_webhook_list to find the ID.",
26
+ schema: {
27
+ id: z.string().describe("ID of the webhook to delete"),
28
+ },
29
+ },
30
+ } as const;
31
+
32
+ export type WebhookToolName = keyof typeof webhookToolDefinitions;
33
+
34
+ export async function executeWebhookTool(
35
+ client: VerboClient,
36
+ name: string,
37
+ args: Record<string, unknown>,
38
+ ): Promise<string> {
39
+ switch (name) {
40
+ case "verbo_webhook_register": {
41
+ const result = await client.webhookRegister(
42
+ args.url as string,
43
+ args.events as string[],
44
+ );
45
+ return JSON.stringify(result, null, 2) +
46
+ "\n\n→ Webhook registered. Verbo will POST events to your URL. Use verbo_webhook_list to see all webhooks.";
47
+ }
48
+ case "verbo_webhook_list": {
49
+ const result = await client.webhookList();
50
+ return JSON.stringify(result, null, 2) +
51
+ "\n\n→ Use verbo_webhook_delete with an ID to remove a webhook.";
52
+ }
53
+ case "verbo_webhook_delete": {
54
+ const result = await client.webhookDelete(args.id as string);
55
+ return JSON.stringify(result, null, 2) +
56
+ "\n\n→ Webhook deleted. No more events will be sent to that URL.";
57
+ }
58
+ default:
59
+ return JSON.stringify({ error: `Unknown webhook tool: ${name}` });
60
+ }
61
+ }