@respond-io/mcp-server 1.0.0

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 (72) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/LICENSE +21 -0
  3. package/README.md +635 -0
  4. package/dist/constants.d.ts +89 -0
  5. package/dist/constants.d.ts.map +1 -0
  6. package/dist/constants.js +143 -0
  7. package/dist/constants.js.map +1 -0
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +40 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/middlewares/TokenVerifier.d.ts +19 -0
  13. package/dist/middlewares/TokenVerifier.d.ts.map +1 -0
  14. package/dist/middlewares/TokenVerifier.js +68 -0
  15. package/dist/middlewares/TokenVerifier.js.map +1 -0
  16. package/dist/protocol/BaseProtocol.d.ts +4 -0
  17. package/dist/protocol/BaseProtocol.d.ts.map +1 -0
  18. package/dist/protocol/BaseProtocol.js +7 -0
  19. package/dist/protocol/BaseProtocol.js.map +1 -0
  20. package/dist/protocol/HttpStreamProtocol.d.ts +36 -0
  21. package/dist/protocol/HttpStreamProtocol.d.ts.map +1 -0
  22. package/dist/protocol/HttpStreamProtocol.js +148 -0
  23. package/dist/protocol/HttpStreamProtocol.js.map +1 -0
  24. package/dist/protocol/StdioProtocol.d.ts +14 -0
  25. package/dist/protocol/StdioProtocol.d.ts.map +1 -0
  26. package/dist/protocol/StdioProtocol.js +32 -0
  27. package/dist/protocol/StdioProtocol.js.map +1 -0
  28. package/dist/protocol/index.d.ts +4 -0
  29. package/dist/protocol/index.d.ts.map +1 -0
  30. package/dist/protocol/index.js +4 -0
  31. package/dist/protocol/index.js.map +1 -0
  32. package/dist/server.d.ts +13 -0
  33. package/dist/server.d.ts.map +1 -0
  34. package/dist/server.js +36 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/tools/BaseTool.d.ts +38 -0
  37. package/dist/tools/BaseTool.d.ts.map +1 -0
  38. package/dist/tools/BaseTool.js +39 -0
  39. package/dist/tools/BaseTool.js.map +1 -0
  40. package/dist/tools/comment.tool.d.ts +14 -0
  41. package/dist/tools/comment.tool.d.ts.map +1 -0
  42. package/dist/tools/comment.tool.js +43 -0
  43. package/dist/tools/comment.tool.js.map +1 -0
  44. package/dist/tools/contacts.tool.d.ts +17 -0
  45. package/dist/tools/contacts.tool.d.ts.map +1 -0
  46. package/dist/tools/contacts.tool.js +355 -0
  47. package/dist/tools/contacts.tool.js.map +1 -0
  48. package/dist/tools/conversation.tool.d.ts +14 -0
  49. package/dist/tools/conversation.tool.d.ts.map +1 -0
  50. package/dist/tools/conversation.tool.js +77 -0
  51. package/dist/tools/conversation.tool.js.map +1 -0
  52. package/dist/tools/index.d.ts +7 -0
  53. package/dist/tools/index.d.ts.map +1 -0
  54. package/dist/tools/index.js +7 -0
  55. package/dist/tools/index.js.map +1 -0
  56. package/dist/tools/messaging.tool.d.ts +15 -0
  57. package/dist/tools/messaging.tool.d.ts.map +1 -0
  58. package/dist/tools/messaging.tool.js +160 -0
  59. package/dist/tools/messaging.tool.js.map +1 -0
  60. package/dist/tools/workspace.tool.d.ts +15 -0
  61. package/dist/tools/workspace.tool.d.ts.map +1 -0
  62. package/dist/tools/workspace.tool.js +282 -0
  63. package/dist/tools/workspace.tool.js.map +1 -0
  64. package/dist/types.d.ts +351 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +2 -0
  67. package/dist/types.js.map +1 -0
  68. package/dist/utils/api.d.ts +127 -0
  69. package/dist/utils/api.d.ts.map +1 -0
  70. package/dist/utils/api.js +340 -0
  71. package/dist/utils/api.js.map +1 -0
  72. package/package.json +108 -0
@@ -0,0 +1,32 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createServer } from "../server.js";
3
+ import { BaseProtocol } from "./BaseProtocol.js";
4
+ export class StdioProtocol extends BaseProtocol {
5
+ apiBaseUrl;
6
+ debug;
7
+ constructor(options) {
8
+ super();
9
+ this.apiBaseUrl = options.apiBaseUrl;
10
+ this.debug = options.debug;
11
+ }
12
+ async init() {
13
+ const transport = new StdioServerTransport();
14
+ const { server } = createServer({
15
+ apiBaseUrl: this.apiBaseUrl,
16
+ debug: this.debug,
17
+ mode: "stdio",
18
+ });
19
+ try {
20
+ await server.connect(transport);
21
+ console.error("MCP STDIO Server listening");
22
+ }
23
+ catch (error) {
24
+ console.error("Failed to set up the server:", error);
25
+ throw error;
26
+ }
27
+ }
28
+ async close() {
29
+ // No-op for STDIO
30
+ }
31
+ }
32
+ //# sourceMappingURL=StdioProtocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StdioProtocol.js","sourceRoot":"","sources":["../../src/protocol/StdioProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQjD,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC5B,UAAU,CAAS;IACnB,KAAK,CAAU;IAEhC,YAAY,OAAoB;QAC9B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAE7C,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;YAC9B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,OAAO;SACM,CAAC,CAAC;QAEvB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,kBAAkB;IACpB,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export * from "./BaseProtocol.js";
2
+ export * from "./HttpStreamProtocol.js";
3
+ export * from "./StdioProtocol.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./BaseProtocol.js";
2
+ export * from "./HttpStreamProtocol.js";
3
+ export * from "./StdioProtocol.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { MCPServerOptions } from "./types.js";
3
+ /**
4
+ * Creates and configures the MCP server.
5
+ * This function initializes the MCP server, registers all the available tools, and returns the server instance.
6
+ *
7
+ * @param {MCPServerOptions} options - The options for configuring the server, including the API base URL, debug mode, and server mode.
8
+ * @returns {{ server: McpServer }} - An object containing the configured MCP server instance.
9
+ */
10
+ export declare const createServer: (options: MCPServerOptions) => {
11
+ server: McpServer;
12
+ };
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9C;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,gBAAgB;;CAuBrD,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,36 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ContactsTool } from "./tools/index.js";
3
+ import { MessagingTool } from "./tools/messaging.tool.js";
4
+ import { ConversationTool } from "./tools/conversation.tool.js";
5
+ import { CommentTool } from "./tools/comment.tool.js";
6
+ import { WorkspaceTool } from "./tools/workspace.tool.js";
7
+ import { API_CONFIG } from "./constants.js";
8
+ /**
9
+ * Creates and configures the MCP server.
10
+ * This function initializes the MCP server, registers all the available tools, and returns the server instance.
11
+ *
12
+ * @param {MCPServerOptions} options - The options for configuring the server, including the API base URL, debug mode, and server mode.
13
+ * @returns {{ server: McpServer }} - An object containing the configured MCP server instance.
14
+ */
15
+ export const createServer = (options) => {
16
+ // Print startup configuration (excluding sensitive info)
17
+ console.error(`[INFO] Respond.io MCP Server starting...
18
+ API Base: ${API_CONFIG.BASE_URL}
19
+ Debug: ${options.debug ? "enabled" : "disabled"}
20
+ Mode: ${options.mode}
21
+ ${options.mode === "http" ? `HTTP mode on HTTP port: ${process.env.PORT}` : options.mode === "stdio" ? `STDIO mode` : ""}
22
+ `);
23
+ // Create server instance
24
+ const server = new McpServer({
25
+ name: "Respond.io MCP Server",
26
+ version: "1.0.1",
27
+ });
28
+ // Register all the tools with the server
29
+ new ContactsTool(options).register(server);
30
+ new MessagingTool(options).register(server);
31
+ new ConversationTool(options).register(server);
32
+ new CommentTool(options).register(server);
33
+ new WorkspaceTool(options).register(server);
34
+ return { server };
35
+ };
36
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAyB,EAAE,EAAE;IACxD,yDAAyD;IACzD,OAAO,CAAC,KAAK,CAAC;kBACE,UAAU,CAAC,QAAQ;eACtB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;cACvC,OAAO,CAAC,IAAI;QAClB,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,2BAA2B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;KACzH,CAAC,CAAC;IAEL,yBAAyB;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,yCAAyC;IACzC,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAE5C,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { MCPServerOptions, Tool } from "../types.js";
3
+ /**
4
+ * Abstract base class for creating tools to register with the MCP server.
5
+ * It simplifies tool creation by handling common initialization and registration logic.
6
+ */
7
+ export declare abstract class BaseTool {
8
+ /**
9
+ * An array of tool definitions to be registered with the MCP server.
10
+ * Each tool definition includes its name, description, schema, and handler.
11
+ */
12
+ protected abstract tools: Tool[];
13
+ /**
14
+ * The base URL for the API, used by all tools.
15
+ */
16
+ protected readonly apiBaseUrl: string;
17
+ /**
18
+ * A flag indicating whether debug mode is enabled.
19
+ */
20
+ protected readonly debug: boolean;
21
+ /**
22
+ * The mode in which the server is running, either "http" or "stdio."
23
+ */
24
+ protected readonly mode: "http" | "stdio";
25
+ /**
26
+ * Initializes the BaseTool with the given server options.
27
+ * @param {MCPServerOptions} options - The server options, including the API base URL, API token, debug flag, and mode.
28
+ */
29
+ constructor({ apiBaseUrl, debug, mode }: MCPServerOptions);
30
+ /**
31
+ * Registers all the tools defined in the `tools` array with the MCP server.
32
+ * This method iterates over the `tools` array and registers each tool
33
+ * with the server using its name, description, schema, and handler.
34
+ * @param {McpServer} server - The MCP server instance to register the tools with.
35
+ */
36
+ register(server: McpServer): void;
37
+ }
38
+ //# sourceMappingURL=BaseTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseTool.d.ts","sourceRoot":"","sources":["../../src/tools/BaseTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAErD;;;GAGG;AACH,8BAAsB,QAAQ;IAC5B;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAEtC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAE1C;;;OAGG;gBACS,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,gBAAgB;IAMzD;;;;;OAKG;IACI,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;CAKzC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Abstract base class for creating tools to register with the MCP server.
3
+ * It simplifies tool creation by handling common initialization and registration logic.
4
+ */
5
+ export class BaseTool {
6
+ /**
7
+ * The base URL for the API, used by all tools.
8
+ */
9
+ apiBaseUrl;
10
+ /**
11
+ * A flag indicating whether debug mode is enabled.
12
+ */
13
+ debug;
14
+ /**
15
+ * The mode in which the server is running, either "http" or "stdio."
16
+ */
17
+ mode;
18
+ /**
19
+ * Initializes the BaseTool with the given server options.
20
+ * @param {MCPServerOptions} options - The server options, including the API base URL, API token, debug flag, and mode.
21
+ */
22
+ constructor({ apiBaseUrl, debug, mode }) {
23
+ this.apiBaseUrl = apiBaseUrl;
24
+ this.debug = debug;
25
+ this.mode = mode;
26
+ }
27
+ /**
28
+ * Registers all the tools defined in the `tools` array with the MCP server.
29
+ * This method iterates over the `tools` array and registers each tool
30
+ * with the server using its name, description, schema, and handler.
31
+ * @param {McpServer} server - The MCP server instance to register the tools with.
32
+ */
33
+ register(server) {
34
+ for (const { name, description, schema, handler } of this.tools) {
35
+ server.tool(name, description, schema, handler);
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=BaseTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseTool.js","sourceRoot":"","sources":["../../src/tools/BaseTool.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAgB,QAAQ;IAO5B;;OAEG;IACgB,UAAU,CAAS;IAEtC;;OAEG;IACgB,KAAK,CAAU;IAElC;;OAEG;IACgB,IAAI,CAAmB;IAE1C;;;OAGG;IACH,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAoB;QACvD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACI,QAAQ,CAAC,MAAiB;QAC/B,KAAK,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import { BaseTool } from "./BaseTool.js";
2
+ import { Tool } from "../types.js";
3
+ /**
4
+ * A tool for managing comments on contacts.
5
+ * This tool allows you to create comments for a given contact, which can be used for internal notes and collaboration.
6
+ */
7
+ export declare class CommentTool extends BaseTool {
8
+ /**
9
+ * The list of tools provided by the CommentTool.
10
+ * It includes the `create_comment` tool, which allows you to add a comment to a contact.
11
+ */
12
+ protected tools: Tool[];
13
+ }
14
+ //# sourceMappingURL=comment.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment.tool.d.ts","sourceRoot":"","sources":["../../src/tools/comment.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOzC,OAAO,EAAO,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,qBAAa,WAAY,SAAQ,QAAQ;IACvC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CA6BrB;CACH"}
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { BaseTool } from "./BaseTool.js";
3
+ import { createSdkClient, formatContactIdentifier, handleSdkError, handleSdkResponse, } from "../utils/api.js";
4
+ /**
5
+ * A tool for managing comments on contacts.
6
+ * This tool allows you to create comments for a given contact, which can be used for internal notes and collaboration.
7
+ */
8
+ export class CommentTool extends BaseTool {
9
+ /**
10
+ * The list of tools provided by the CommentTool.
11
+ * It includes the `create_comment` tool, which allows you to add a comment to a contact.
12
+ */
13
+ tools = [
14
+ {
15
+ name: "create_comment",
16
+ description: "Add a comment to a contact for internal reference.",
17
+ schema: {
18
+ identifier: z
19
+ .string()
20
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
21
+ text: z
22
+ .string()
23
+ .max(1000)
24
+ .describe("The comment text. Max 1000 characters. To mention a user, use the format {{@user.ID}}."),
25
+ },
26
+ handler: async (args, ctx) => {
27
+ const { identifier, text } = args;
28
+ try {
29
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
30
+ const formattedIdentifier = formatContactIdentifier(identifier);
31
+ const result = await sdkClient.comments.create(formattedIdentifier, {
32
+ text,
33
+ });
34
+ return handleSdkResponse(result);
35
+ }
36
+ catch (error) {
37
+ return handleSdkError(error);
38
+ }
39
+ },
40
+ },
41
+ ];
42
+ }
43
+ //# sourceMappingURL=comment.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment.tool.js","sourceRoot":"","sources":["../../src/tools/comment.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAGzB;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,QAAQ;IACvC;;;OAGG;IACO,KAAK,GAAW;QACxB;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,oDAAoD;YACjE,MAAM,EAAE;gBACN,UAAU,EAAE,CAAC;qBACV,MAAM,EAAE;qBACR,QAAQ,CAAC,4EAA4E,CAAC;gBACzF,IAAI,EAAE,CAAC;qBACJ,MAAM,EAAE;qBACR,GAAG,CAAC,IAAI,CAAC;qBACT,QAAQ,CACP,wFAAwF,CACzF;aACJ;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC3B,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,IAA4C,CAAC;gBAC1E,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,GAAU,CAAC,CAAC;oBAC1E,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;oBAChE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,mBAAmB,EAAE;wBAClE,IAAI;qBACL,CAAC,CAAC;oBACH,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;SACF;KACF,CAAC;CACH"}
@@ -0,0 +1,17 @@
1
+ import { BaseTool } from "./BaseTool.js";
2
+ import { Tool } from "../types.js";
3
+ /**
4
+ * A tool for managing contacts.
5
+ * This tool provides a comprehensive set of functionalities for contact management,
6
+ * including creating, retrieving, updating, deleting, and listing contacts,
7
+ * as well as managing contact tags.
8
+ */
9
+ export declare class ContactsTool extends BaseTool {
10
+ /**
11
+ * The list of tools provided by the ContactsTool.
12
+ * It includes tools for getting, creating, updating, deleting, and listing contacts,
13
+ * as well as adding and removing tags from a contact.
14
+ */
15
+ protected tools: Tool[];
16
+ }
17
+ //# sourceMappingURL=contacts.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.tool.d.ts","sourceRoot":"","sources":["../../src/tools/contacts.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQzC,OAAO,EAAO,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,QAAQ;IACxC;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAsYrB;CACH"}
@@ -0,0 +1,355 @@
1
+ import { z } from "zod";
2
+ import { BaseTool } from "./BaseTool.js";
3
+ import { createSdkClient, formatContactIdentifier, handleSdkError, handleSdkResponse, } from "../utils/api.js";
4
+ /**
5
+ * A tool for managing contacts.
6
+ * This tool provides a comprehensive set of functionalities for contact management,
7
+ * including creating, retrieving, updating, deleting, and listing contacts,
8
+ * as well as managing contact tags.
9
+ */
10
+ export class ContactsTool extends BaseTool {
11
+ /**
12
+ * The list of tools provided by the ContactsTool.
13
+ * It includes tools for getting, creating, updating, deleting, and listing contacts,
14
+ * as well as adding and removing tags from a contact.
15
+ */
16
+ tools = [
17
+ {
18
+ name: "get_contact",
19
+ description: "Retrieve information about a specific contact by their ID, email, or phone number.",
20
+ schema: {
21
+ identifier: z
22
+ .string()
23
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number, formatted as 'id:123', 'email:user@example.com', or 'phone:+1234567890'."),
24
+ },
25
+ handler: async (args, ctx) => {
26
+ const { identifier } = args;
27
+ try {
28
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
29
+ const formattedIdentifier = formatContactIdentifier(identifier);
30
+ const contact = await sdkClient.contacts.get(formattedIdentifier);
31
+ return handleSdkResponse(contact);
32
+ }
33
+ catch (error) {
34
+ return handleSdkError(error);
35
+ }
36
+ },
37
+ },
38
+ {
39
+ name: "create_contact",
40
+ description: "Create a new contact in the workspace.",
41
+ schema: {
42
+ identifier: z
43
+ .string()
44
+ .describe("The contact's identifier, using their phone or email, formatted as 'email:user@example.com' or 'phone:+1234567890'."),
45
+ firstName: z.string().describe("The first name of the contact."),
46
+ lastName: z.string().optional().describe("The last name of the contact."),
47
+ email: z.string().optional().describe("The contact's email address."),
48
+ phone: z
49
+ .string()
50
+ .optional()
51
+ .describe("The contact's phone number, including the country code (e.g., +60123456789)."),
52
+ language: z
53
+ .string()
54
+ .optional()
55
+ .describe("The contact's language code, based on the ISO 639-1 standard (e.g., 'en' for English, 'ms' for Malay)."),
56
+ custom_fields: z
57
+ .array(z.object({
58
+ name: z.string(),
59
+ value: z.any(),
60
+ }))
61
+ .optional()
62
+ .describe("An array of custom field objects, each with a name and value."),
63
+ },
64
+ handler: async (args, ctx) => {
65
+ const { identifier, firstName, lastName, phone, email, language, custom_fields } = args;
66
+ const data = { firstName, lastName, phone, email, language, custom_fields };
67
+ try {
68
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
69
+ // For creation, we need email: or phone: format, not id:
70
+ let formattedIdentifier;
71
+ if (identifier.includes("@")) {
72
+ formattedIdentifier = `email:${identifier}`;
73
+ }
74
+ else if (identifier.startsWith("+") || /^\d+$/.test(identifier)) {
75
+ formattedIdentifier = `phone:${identifier.startsWith("+") ? identifier : "+" + identifier}`;
76
+ }
77
+ else {
78
+ formattedIdentifier = `email:${identifier}`; // Default to email
79
+ }
80
+ const contact = await sdkClient.contacts.create(formattedIdentifier, data);
81
+ return handleSdkResponse(contact);
82
+ }
83
+ catch (error) {
84
+ return handleSdkError(error);
85
+ }
86
+ },
87
+ },
88
+ {
89
+ name: "update_contact",
90
+ description: "Update an existing contact's information.",
91
+ schema: {
92
+ identifier: z
93
+ .string()
94
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
95
+ firstName: z.string().optional().describe("The contact's new first name."),
96
+ lastName: z.string().optional().describe("The contact's new last name."),
97
+ email: z.string().optional().describe("The contact's new email address."),
98
+ phone: z.string().optional().describe("The contact's new phone number."),
99
+ language: z.string().optional().describe("The contact's new language code."),
100
+ custom_fields: z.array(z.any()).optional().describe("An array of custom fields to update."),
101
+ },
102
+ handler: async (args, ctx) => {
103
+ const { identifier, ...data } = args;
104
+ try {
105
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
106
+ const formattedIdentifier = formatContactIdentifier(identifier);
107
+ const contact = await sdkClient.contacts.update(formattedIdentifier, data);
108
+ return handleSdkResponse(contact);
109
+ }
110
+ catch (error) {
111
+ return handleSdkError(error);
112
+ }
113
+ },
114
+ },
115
+ {
116
+ name: "delete_contact",
117
+ description: "Delete a contact from the workspace.",
118
+ schema: {
119
+ identifier: z
120
+ .string()
121
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
122
+ },
123
+ handler: async (args, ctx) => {
124
+ const { identifier } = args;
125
+ try {
126
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
127
+ const formattedIdentifier = formatContactIdentifier(identifier);
128
+ await sdkClient.contacts.delete(formattedIdentifier);
129
+ return handleSdkResponse({ success: true, message: "Contact deleted successfully" });
130
+ }
131
+ catch (error) {
132
+ return handleSdkError(error);
133
+ }
134
+ },
135
+ },
136
+ {
137
+ name: "list_contacts",
138
+ description: "List contacts with optional filters and search.",
139
+ schema: {
140
+ limit: z
141
+ .number()
142
+ .min(1)
143
+ .max(100)
144
+ .default(10)
145
+ .describe("The number of contacts to return, between 1 and 100."),
146
+ cursorId: z.number().optional().describe("The cursor ID for pagination."),
147
+ search: z.string().optional().describe("A search query to filter contacts."),
148
+ timezone: z
149
+ .string()
150
+ .default("UTC")
151
+ .describe("The timezone to use for the search (e.g., 'Asia/Kuala_Lumpur')."),
152
+ },
153
+ handler: async (args, ctx) => {
154
+ const { limit = 10, cursorId, search = "", timezone = "UTC", } = args;
155
+ try {
156
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
157
+ const result = await sdkClient.contacts.list({
158
+ search,
159
+ timezone,
160
+ filter: { $and: [] },
161
+ }, {
162
+ limit,
163
+ cursorId,
164
+ });
165
+ return handleSdkResponse(result);
166
+ }
167
+ catch (error) {
168
+ return handleSdkError(error);
169
+ }
170
+ },
171
+ },
172
+ {
173
+ name: "add_contact_tags",
174
+ description: "Add tags to a contact.",
175
+ schema: {
176
+ identifier: z
177
+ .string()
178
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
179
+ tags: z
180
+ .array(z.string())
181
+ .nonempty()
182
+ .describe("An array of tag names to add to the contact."),
183
+ },
184
+ handler: async (args, ctx) => {
185
+ const { identifier, tags } = args;
186
+ try {
187
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
188
+ const formattedIdentifier = formatContactIdentifier(identifier);
189
+ await sdkClient.contacts.addTags(formattedIdentifier, tags);
190
+ return handleSdkResponse({ success: true, message: "Tags added successfully" });
191
+ }
192
+ catch (error) {
193
+ return handleSdkError(error);
194
+ }
195
+ },
196
+ },
197
+ {
198
+ name: "remove_contact_tags",
199
+ description: "Remove tags from a contact.",
200
+ schema: {
201
+ identifier: z
202
+ .string()
203
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
204
+ tags: z
205
+ .array(z.string())
206
+ .nonempty()
207
+ .describe("An array of tag names to remove from the contact."),
208
+ },
209
+ handler: async (args, ctx) => {
210
+ const { identifier, tags } = args;
211
+ try {
212
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
213
+ const formattedIdentifier = formatContactIdentifier(identifier);
214
+ await sdkClient.contacts.deleteTags(formattedIdentifier, tags);
215
+ return handleSdkResponse({ success: true, message: "Tags removed successfully" });
216
+ }
217
+ catch (error) {
218
+ return handleSdkError(error);
219
+ }
220
+ },
221
+ },
222
+ {
223
+ name: "create_or_update_contact",
224
+ description: "Create a contact if they do not exist, or update the existing contact. Uses the contact identifier to match.",
225
+ schema: {
226
+ identifier: z
227
+ .string()
228
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
229
+ firstName: z.string().describe("The first name of the contact."),
230
+ lastName: z.string().optional().describe("The last name of the contact."),
231
+ email: z.string().optional().describe("The contact's email address."),
232
+ phone: z
233
+ .string()
234
+ .optional()
235
+ .describe("The contact's phone number, including the country code (e.g., +60123456789)."),
236
+ language: z
237
+ .string()
238
+ .optional()
239
+ .describe("The contact's language code, based on the ISO 639-1 standard (e.g., 'en' for English)."),
240
+ custom_fields: z
241
+ .array(z.object({
242
+ name: z.string(),
243
+ value: z.any(),
244
+ }))
245
+ .optional()
246
+ .describe("An array of custom field objects, each with a name and value."),
247
+ },
248
+ handler: async (args, ctx) => {
249
+ const { identifier, firstName, lastName, phone, email, language, custom_fields } = args;
250
+ const data = { firstName, lastName, phone, email, language, custom_fields };
251
+ try {
252
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
253
+ const formattedIdentifier = formatContactIdentifier(identifier);
254
+ const result = await sdkClient.contacts.createOrUpdate(formattedIdentifier, data);
255
+ return handleSdkResponse(result);
256
+ }
257
+ catch (error) {
258
+ return handleSdkError(error);
259
+ }
260
+ },
261
+ },
262
+ {
263
+ name: "merge_contacts",
264
+ description: "Merge two contacts. The primary contact is kept; the secondary is merged into it. Optionally update fields on the primary.",
265
+ schema: {
266
+ primaryContactId: z
267
+ .number()
268
+ .describe("The contact ID of the contact to keep (primary). Must be numeric ID."),
269
+ secondaryContactId: z
270
+ .number()
271
+ .describe("The contact ID of the contact to merge into the primary (secondary)."),
272
+ firstName: z.string().optional().describe("Update the primary contact's first name."),
273
+ lastName: z.string().optional().describe("Update the primary contact's last name."),
274
+ email: z.string().optional().describe("Update the primary contact's email."),
275
+ phone: z.string().optional().describe("Update the primary contact's phone."),
276
+ },
277
+ handler: async (args, ctx) => {
278
+ const { primaryContactId, secondaryContactId, firstName, lastName, email, phone } = args;
279
+ try {
280
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
281
+ const request = {
282
+ contactIds: [primaryContactId, secondaryContactId],
283
+ ...(firstName !== undefined && { firstName }),
284
+ ...(lastName !== undefined && { lastName }),
285
+ ...(email !== undefined && { email }),
286
+ ...(phone !== undefined && { phone }),
287
+ };
288
+ const result = await sdkClient.contacts.merge(request);
289
+ return handleSdkResponse(result);
290
+ }
291
+ catch (error) {
292
+ return handleSdkError(error);
293
+ }
294
+ },
295
+ },
296
+ {
297
+ name: "list_contact_channels",
298
+ description: "List all messaging channels connected to a contact (e.g. WhatsApp, Facebook).",
299
+ schema: {
300
+ identifier: z
301
+ .string()
302
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
303
+ limit: z
304
+ .number()
305
+ .min(1)
306
+ .max(100)
307
+ .default(10)
308
+ .describe("The number of channels to return, between 1 and 100."),
309
+ cursorId: z.number().optional().describe("The cursor ID for pagination."),
310
+ },
311
+ handler: async (args, ctx) => {
312
+ const { identifier, limit = 10, cursorId, } = args;
313
+ try {
314
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
315
+ const formattedIdentifier = formatContactIdentifier(identifier);
316
+ const result = await sdkClient.contacts.listChannels(formattedIdentifier, {
317
+ limit,
318
+ cursorId,
319
+ });
320
+ return handleSdkResponse(result);
321
+ }
322
+ catch (error) {
323
+ return handleSdkError(error);
324
+ }
325
+ },
326
+ },
327
+ {
328
+ name: "update_contact_lifecycle",
329
+ description: "Update a contact's lifecycle stage, or remove the lifecycle (pass stage as null or empty to clear).",
330
+ schema: {
331
+ identifier: z
332
+ .string()
333
+ .describe("The contact's identifier. Can be the contact's ID, email, or phone number."),
334
+ stage: z
335
+ .string()
336
+ .nullable()
337
+ .describe("The lifecycle stage name to set. Set to null or omit to remove the contact's lifecycle."),
338
+ },
339
+ handler: async (args, ctx) => {
340
+ const { identifier, stage } = args;
341
+ try {
342
+ const sdkClient = createSdkClient(this.apiBaseUrl, this.mode, ctx);
343
+ const formattedIdentifier = formatContactIdentifier(identifier);
344
+ const request = stage == null || stage === "" ? null : { name: stage };
345
+ const result = await sdkClient.contacts.updateLifecycle(formattedIdentifier, request);
346
+ return handleSdkResponse(result);
347
+ }
348
+ catch (error) {
349
+ return handleSdkError(error);
350
+ }
351
+ },
352
+ },
353
+ ];
354
+ }
355
+ //# sourceMappingURL=contacts.tool.js.map