@iterable/mcp 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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +318 -0
  3. package/TOOLS.md +133 -0
  4. package/dist/client-detection.d.ts +7 -0
  5. package/dist/client-detection.d.ts.map +1 -0
  6. package/dist/client-detection.js +22 -0
  7. package/dist/client-detection.js.map +1 -0
  8. package/dist/config.d.ts +25 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +74 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/http-headers.d.ts +5 -0
  13. package/dist/http-headers.d.ts.map +1 -0
  14. package/dist/http-headers.js +5 -0
  15. package/dist/http-headers.js.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +43 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/install.d.ts +41 -0
  21. package/dist/install.d.ts.map +1 -0
  22. package/dist/install.js +725 -0
  23. package/dist/install.js.map +1 -0
  24. package/dist/key-manager.d.ts +236 -0
  25. package/dist/key-manager.d.ts.map +1 -0
  26. package/dist/key-manager.js +776 -0
  27. package/dist/key-manager.js.map +1 -0
  28. package/dist/keys-cli.d.ts +8 -0
  29. package/dist/keys-cli.d.ts.map +1 -0
  30. package/dist/keys-cli.js +487 -0
  31. package/dist/keys-cli.js.map +1 -0
  32. package/dist/prompts.d.ts +15 -0
  33. package/dist/prompts.d.ts.map +1 -0
  34. package/dist/prompts.js +66 -0
  35. package/dist/prompts.js.map +1 -0
  36. package/dist/schema-utils.d.ts +22 -0
  37. package/dist/schema-utils.d.ts.map +1 -0
  38. package/dist/schema-utils.js +65 -0
  39. package/dist/schema-utils.js.map +1 -0
  40. package/dist/server.d.ts +13 -0
  41. package/dist/server.d.ts.map +1 -0
  42. package/dist/server.js +172 -0
  43. package/dist/server.js.map +1 -0
  44. package/dist/shutdown.d.ts +5 -0
  45. package/dist/shutdown.d.ts.map +1 -0
  46. package/dist/shutdown.js +68 -0
  47. package/dist/shutdown.js.map +1 -0
  48. package/dist/tool-filter.d.ts +19 -0
  49. package/dist/tool-filter.d.ts.map +1 -0
  50. package/dist/tool-filter.js +144 -0
  51. package/dist/tool-filter.js.map +1 -0
  52. package/dist/tools/campaigns.d.ts +7 -0
  53. package/dist/tools/campaigns.d.ts.map +1 -0
  54. package/dist/tools/campaigns.js +88 -0
  55. package/dist/tools/campaigns.js.map +1 -0
  56. package/dist/tools/catalogs.d.ts +7 -0
  57. package/dist/tools/catalogs.d.ts.map +1 -0
  58. package/dist/tools/catalogs.js +85 -0
  59. package/dist/tools/catalogs.js.map +1 -0
  60. package/dist/tools/events.d.ts +7 -0
  61. package/dist/tools/events.d.ts.map +1 -0
  62. package/dist/tools/events.js +34 -0
  63. package/dist/tools/events.js.map +1 -0
  64. package/dist/tools/experiments.d.ts +7 -0
  65. package/dist/tools/experiments.d.ts.map +1 -0
  66. package/dist/tools/experiments.js +16 -0
  67. package/dist/tools/experiments.js.map +1 -0
  68. package/dist/tools/export.d.ts +7 -0
  69. package/dist/tools/export.d.ts.map +1 -0
  70. package/dist/tools/export.js +41 -0
  71. package/dist/tools/export.js.map +1 -0
  72. package/dist/tools/index.d.ts +19 -0
  73. package/dist/tools/index.d.ts.map +1 -0
  74. package/dist/tools/index.js +44 -0
  75. package/dist/tools/index.js.map +1 -0
  76. package/dist/tools/journeys.d.ts +10 -0
  77. package/dist/tools/journeys.d.ts.map +1 -0
  78. package/dist/tools/journeys.js +25 -0
  79. package/dist/tools/journeys.js.map +1 -0
  80. package/dist/tools/lists.d.ts +7 -0
  81. package/dist/tools/lists.d.ts.map +1 -0
  82. package/dist/tools/lists.js +58 -0
  83. package/dist/tools/lists.js.map +1 -0
  84. package/dist/tools/messaging.d.ts +11 -0
  85. package/dist/tools/messaging.d.ts.map +1 -0
  86. package/dist/tools/messaging.js +103 -0
  87. package/dist/tools/messaging.js.map +1 -0
  88. package/dist/tools/snippets.d.ts +7 -0
  89. package/dist/tools/snippets.d.ts.map +1 -0
  90. package/dist/tools/snippets.js +46 -0
  91. package/dist/tools/snippets.js.map +1 -0
  92. package/dist/tools/subscriptions.d.ts +4 -0
  93. package/dist/tools/subscriptions.d.ts.map +1 -0
  94. package/dist/tools/subscriptions.js +37 -0
  95. package/dist/tools/subscriptions.js.map +1 -0
  96. package/dist/tools/templates.d.ts +7 -0
  97. package/dist/tools/templates.d.ts.map +1 -0
  98. package/dist/tools/templates.js +118 -0
  99. package/dist/tools/templates.js.map +1 -0
  100. package/dist/tools/users.d.ts +10 -0
  101. package/dist/tools/users.d.ts.map +1 -0
  102. package/dist/tools/users.js +74 -0
  103. package/dist/tools/users.js.map +1 -0
  104. package/dist/tools/webhooks.d.ts +7 -0
  105. package/dist/tools/webhooks.d.ts.map +1 -0
  106. package/dist/tools/webhooks.js +22 -0
  107. package/dist/tools/webhooks.js.map +1 -0
  108. package/dist/utils/cli-env.d.ts +11 -0
  109. package/dist/utils/cli-env.d.ts.map +1 -0
  110. package/dist/utils/cli-env.js +32 -0
  111. package/dist/utils/cli-env.js.map +1 -0
  112. package/dist/utils/endpoint-prompt.d.ts +14 -0
  113. package/dist/utils/endpoint-prompt.d.ts.map +1 -0
  114. package/dist/utils/endpoint-prompt.js +73 -0
  115. package/dist/utils/endpoint-prompt.js.map +1 -0
  116. package/dist/utils/formatting.d.ts +10 -0
  117. package/dist/utils/formatting.d.ts.map +1 -0
  118. package/dist/utils/formatting.js +12 -0
  119. package/dist/utils/formatting.js.map +1 -0
  120. package/dist/utils/password-prompt.d.ts +19 -0
  121. package/dist/utils/password-prompt.d.ts.map +1 -0
  122. package/dist/utils/password-prompt.js +37 -0
  123. package/dist/utils/password-prompt.js.map +1 -0
  124. package/dist/utils/sanitize.d.ts +13 -0
  125. package/dist/utils/sanitize.d.ts.map +1 -0
  126. package/dist/utils/sanitize.js +23 -0
  127. package/dist/utils/sanitize.js.map +1 -0
  128. package/dist/utils/tool-config.d.ts +13 -0
  129. package/dist/utils/tool-config.d.ts.map +1 -0
  130. package/dist/utils/tool-config.js +45 -0
  131. package/dist/utils/tool-config.js.map +1 -0
  132. package/dist/utils/ui.d.ts +90 -0
  133. package/dist/utils/ui.d.ts.map +1 -0
  134. package/dist/utils/ui.js +298 -0
  135. package/dist/utils/ui.js.map +1 -0
  136. package/dist/utils/url.d.ts +20 -0
  137. package/dist/utils/url.d.ts.map +1 -0
  138. package/dist/utils/url.js +53 -0
  139. package/dist/utils/url.js.map +1 -0
  140. package/package.json +105 -0
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Auto-generated MCP prompts from existing tools
3
+ * Creates slash commands without code duplication
4
+ */
5
+ /**
6
+ * Convert a tool's JSON Schema to MCP prompt arguments
7
+ */
8
+ function toolSchemaToPromptArguments(schema) {
9
+ if (!schema?.properties)
10
+ return [];
11
+ const required = schema.required || [];
12
+ return Object.entries(schema.properties).map(([name, prop]) => ({
13
+ name,
14
+ description: prop.description || `${name} parameter`,
15
+ required: required.includes(name),
16
+ }));
17
+ }
18
+ /**
19
+ * Convert tool name to user-friendly prompt name
20
+ * get_user -> get-user, export_data -> export-data
21
+ */
22
+ function toolNameToPromptName(toolName) {
23
+ return toolName.replace(/_/g, "-");
24
+ }
25
+ /**
26
+ * Generate MCP prompts from filtered tools
27
+ * Creates prompts for all provided tools (assumes they're already filtered appropriately)
28
+ */
29
+ export function generatePrompts(tools) {
30
+ return tools.map((tool) => ({
31
+ name: toolNameToPromptName(tool.name),
32
+ description: tool.description,
33
+ arguments: toolSchemaToPromptArguments(tool.inputSchema),
34
+ }));
35
+ }
36
+ /**
37
+ * Generate prompt message that calls the corresponding tool
38
+ */
39
+ export function generatePromptMessage(promptName, args = {}) {
40
+ // Convert prompt name back to tool name
41
+ const toolName = promptName.replace(/-/g, "_");
42
+ // Generate a natural language instruction to use the tool
43
+ const argsList = Object.entries(args)
44
+ .filter(([_, value]) => value !== undefined && value !== "")
45
+ .map(([key, value]) => {
46
+ if (typeof value === "string") {
47
+ return `"${key}": "${value}"`;
48
+ }
49
+ return `"${key}": ${JSON.stringify(value)}`;
50
+ });
51
+ const toolCall = argsList.length > 0
52
+ ? `${toolName} tool with parameters: { ${argsList.join(", ")} }`
53
+ : `${toolName} tool`;
54
+ return {
55
+ messages: [
56
+ {
57
+ role: "user",
58
+ content: {
59
+ type: "text",
60
+ text: `Please use the ${toolCall} to complete this request.`,
61
+ },
62
+ },
63
+ ],
64
+ };
65
+ }
66
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;GAEG;AACH,SAAS,2BAA2B,CAClC,MAAW;IAEX,IAAI,CAAC,MAAM,EAAE,UAAU;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAC1C,CAAC,CAAC,IAAI,EAAE,IAAI,CAAgB,EAAE,EAAE,CAAC,CAAC;QAChC,IAAI;QACJ,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,GAAG,IAAI,YAAY;QACpD,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;KAClC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;QACrC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,2BAA2B,CAAC,IAAI,CAAC,WAAW,CAAC;KACzD,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,OAAgC,EAAE;IAElC,wCAAwC;IACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAE/C,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC;SAC3D,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,GAAG,OAAO,KAAK,GAAG,CAAC;QAChC,CAAC;QACD,OAAO,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEL,MAAM,QAAQ,GACZ,QAAQ,CAAC,MAAM,GAAG,CAAC;QACjB,CAAC,CAAC,GAAG,QAAQ,4BAA4B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QAChE,CAAC,CAAC,GAAG,QAAQ,OAAO,CAAC;IAEzB,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,kBAAkB,QAAQ,4BAA4B;iBAC7D;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Utilities for converting Zod schemas to JSON Schema format
3
+ * This eliminates the need to manually duplicate schema definitions
4
+ */
5
+ import { zodToJsonSchema } from "@alcyone-labs/zod-to-json-schema";
6
+ export { zodToJsonSchema };
7
+ import { Tool } from "@modelcontextprotocol/sdk/types.js";
8
+ import { z } from "zod";
9
+ /**
10
+ * Tool configuration for MCP tool creation
11
+ */
12
+ interface ToolConfig<TSchema extends z.ZodType> {
13
+ name: string;
14
+ description: string;
15
+ schema: TSchema;
16
+ execute: (params: z.infer<TSchema>) => Promise<any>;
17
+ }
18
+ /**
19
+ * Create an MCP tool with automatic error handling and response formatting
20
+ */
21
+ export declare function createTool<TSchema extends z.ZodType>(config: ToolConfig<TSchema>): Tool;
22
+ //# sourceMappingURL=schema-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-utils.d.ts","sourceRoot":"","sources":["../src/schema-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,eAAe,EAAE,CAAC;AAQ3B,OAAO,EAAuB,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,UAAU,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,EAClD,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,GAC1B,IAAI,CAoEN"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Utilities for converting Zod schemas to JSON Schema format
3
+ * This eliminates the need to manually duplicate schema definitions
4
+ */
5
+ import { zodToJsonSchema, } from "@alcyone-labs/zod-to-json-schema";
6
+ // Re-export for testing
7
+ export { zodToJsonSchema };
8
+ import { IterableApiError, IterableNetworkError, IterableRawError, IterableResponseValidationError, } from "@iterable/api";
9
+ import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
10
+ import { z } from "zod";
11
+ /**
12
+ * Create an MCP tool with automatic error handling and response formatting
13
+ */
14
+ export function createTool(config) {
15
+ const handler = async (args) => {
16
+ try {
17
+ // Validate input with schema
18
+ const params = config.schema.parse(args);
19
+ // Execute the tool logic
20
+ const result = await config.execute(params);
21
+ return {
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: JSON.stringify(result, null, 2),
26
+ },
27
+ ],
28
+ };
29
+ }
30
+ catch (error) {
31
+ if (error instanceof z.ZodError) {
32
+ throw new McpError(ErrorCode.InvalidParams, `Validation error: ${error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`);
33
+ }
34
+ if (error instanceof McpError) {
35
+ throw error;
36
+ }
37
+ // Handle Iterable-specific errors - return structured data when possible
38
+ if (error instanceof IterableResponseValidationError ||
39
+ error instanceof IterableApiError ||
40
+ error instanceof IterableRawError) {
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: JSON.stringify(error, null, 2),
46
+ },
47
+ ],
48
+ };
49
+ }
50
+ // Network errors don't have useful response data, so throw
51
+ if (error instanceof IterableNetworkError) {
52
+ throw new McpError(ErrorCode.InternalError, `Iterable network error: ${error.message}`);
53
+ }
54
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
55
+ throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${errorMessage}`);
56
+ }
57
+ };
58
+ return {
59
+ name: config.name,
60
+ description: config.description,
61
+ inputSchema: zodToJsonSchema(config.schema),
62
+ handler,
63
+ };
64
+ }
65
+ //# sourceMappingURL=schema-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-utils.js","sourceRoot":"","sources":["../src/schema-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,eAAe,GAChB,MAAM,kCAAkC,CAAC;AAE1C,wBAAwB;AACxB,OAAO,EAAE,eAAe,EAAE,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAQ,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,MAA2B;IAE3B,MAAM,OAAO,GAAG,KAAK,EAAE,IAAa,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEzC,yBAAyB;YACzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAE5C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,qBAAqB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3G,CAAC;YACJ,CAAC;YAED,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,yEAAyE;YACzE,IACE,KAAK,YAAY,+BAA+B;gBAChD,KAAK,YAAY,gBAAgB;gBACjC,KAAK,YAAY,gBAAgB,EACjC,CAAC;gBACD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;yBACrC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,2DAA2D;YAC3D,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;gBAC1C,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,2BAA4B,KAAa,CAAC,OAAO,EAAE,CACpD,CAAC;YACJ,CAAC;YAED,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;YACpE,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,0BAA0B,YAAY,EAAE,CACzC,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,WAAW,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,CAA0B;QACpE,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare class IterableMcpServer {
2
+ private server;
3
+ private iterableClient;
4
+ private tools;
5
+ private prompts;
6
+ private globalSessionId;
7
+ private sessionContext;
8
+ constructor();
9
+ private setupHandlers;
10
+ private setupHttpInterceptors;
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAkDA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,OAAO,CAAY;IAG3B,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,cAAc,CAA2C;;IAkCjE,OAAO,CAAC,aAAa;IAkDrB,OAAO,CAAC,qBAAqB;IA6DvB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
package/dist/server.js ADDED
@@ -0,0 +1,172 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { IterableClient } from "@iterable/api";
3
+ import { logger } from "@iterable/api";
4
+ import { DEFAULT_USER_AGENT } from "@iterable/api";
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { CallToolRequestSchema, ErrorCode, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
8
+ import { readFileSync } from "fs";
9
+ import { dirname, join } from "path";
10
+ import { fileURLToPath } from "url";
11
+ import { detectClientName } from "./client-detection.js";
12
+ import { loadMcpServerConfig } from "./config.js";
13
+ import { HEADER_CLIENT, HEADER_SESSION_ID, HEADER_TOOL, HEADER_USER_AGENT, } from "./http-headers.js";
14
+ import { generatePromptMessage, generatePrompts } from "./prompts.js";
15
+ import { setupGracefulShutdown } from "./shutdown.js";
16
+ import { filterTools } from "./tool-filter.js";
17
+ import { createAllTools } from "./tools/index.js";
18
+ import { sanitizeUrlForLogs } from "./utils/url.js";
19
+ // Get package version
20
+ const packageJson = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8"));
21
+ export class IterableMcpServer {
22
+ server;
23
+ iterableClient;
24
+ tools;
25
+ prompts;
26
+ // Since we are using the stdio transport, we assume a global session
27
+ globalSessionId = createSessionId();
28
+ sessionContext = new AsyncLocalStorage();
29
+ constructor() {
30
+ this.server = new Server({
31
+ name: "iterable-mcp",
32
+ version: packageJson.version,
33
+ }, {
34
+ capabilities: {
35
+ tools: {},
36
+ prompts: {},
37
+ },
38
+ });
39
+ this.setupHandlers();
40
+ // Set up callback to log when MCP handshake completes
41
+ this.server.oninitialized = () => {
42
+ logger.info("MCP session initialized", {
43
+ sessionId: this.globalSessionId,
44
+ clientName: detectClientName(this.server),
45
+ });
46
+ };
47
+ this.server.onerror = (error) => logger.error("MCP Error", { error });
48
+ // Setup graceful shutdown
49
+ setupGracefulShutdown(async () => {
50
+ await this.server.close();
51
+ });
52
+ }
53
+ setupHandlers() {
54
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
55
+ tools: this.tools,
56
+ }));
57
+ this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
58
+ prompts: this.prompts,
59
+ }));
60
+ this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
61
+ const { name, arguments: args } = request.params;
62
+ if (!this.prompts.some((prompt) => prompt.name === name)) {
63
+ throw new McpError(ErrorCode.InvalidRequest, `Unknown prompt: ${name}`);
64
+ }
65
+ return generatePromptMessage(name, args || {});
66
+ });
67
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
68
+ const { name, arguments: args } = request.params;
69
+ const tool = this.tools.find((tool) => tool.name === name);
70
+ if (!tool || typeof tool.handler !== "function") {
71
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
72
+ }
73
+ try {
74
+ return await this.sessionContext.run({
75
+ sessionId: this.globalSessionId,
76
+ clientName: detectClientName(this.server),
77
+ toolName: name,
78
+ }, async () => {
79
+ return await tool.handler(args || {});
80
+ });
81
+ }
82
+ catch (error) {
83
+ if (error instanceof McpError) {
84
+ throw error;
85
+ }
86
+ throw new McpError(ErrorCode.InternalError, `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`);
87
+ }
88
+ });
89
+ }
90
+ setupHttpInterceptors() {
91
+ // Request interceptor for adding session headers
92
+ this.iterableClient.client.interceptors.request.use((config) => {
93
+ const sessionContext = this.sessionContext.getStore();
94
+ const userAgent = [
95
+ `iterable-mcp/${packageJson.version}`,
96
+ DEFAULT_USER_AGENT,
97
+ `(node=${process.versions.node}; os=${process.platform}; client=${sessionContext?.clientName || "none"})`,
98
+ ].join(" ");
99
+ Object.assign(config.headers, {
100
+ [HEADER_CLIENT]: sessionContext?.clientName,
101
+ [HEADER_SESSION_ID]: sessionContext?.sessionId,
102
+ [HEADER_TOOL]: sessionContext?.toolName,
103
+ [HEADER_USER_AGENT]: userAgent,
104
+ });
105
+ try {
106
+ const method = String(config.method || "GET").toUpperCase();
107
+ const baseURL = config.baseURL || this.iterableClient.client.defaults.baseURL;
108
+ const url = config.url || "";
109
+ const fullUrl = `${baseURL || ""}${url}`;
110
+ const safeUrl = sanitizeUrlForLogs(fullUrl);
111
+ // SECURITY: Do not log headers or params; sanitize URL to avoid PII
112
+ logger.debug("MCP HTTP request", {
113
+ method,
114
+ url: safeUrl,
115
+ timeout: config.timeout,
116
+ });
117
+ }
118
+ catch {
119
+ // Ignore logging errors
120
+ }
121
+ return config;
122
+ });
123
+ // Response interceptor for error logging
124
+ this.iterableClient.client.interceptors.response.use((response) => response, (error) => {
125
+ try {
126
+ const cfg = error?.config || {};
127
+ const method = String(cfg.method || "GET").toUpperCase();
128
+ const baseURL = cfg.baseURL || this.iterableClient.client.defaults.baseURL;
129
+ const url = cfg.url || "";
130
+ const fullUrl = `${baseURL || ""}${url}`;
131
+ const safeUrl = sanitizeUrlForLogs(fullUrl);
132
+ logger.error("MCP HTTP error", {
133
+ method,
134
+ url: safeUrl,
135
+ message: String(error?.message || "Unknown error"),
136
+ });
137
+ }
138
+ catch {
139
+ // Ignore logging errors
140
+ }
141
+ return Promise.reject(error);
142
+ });
143
+ }
144
+ async run() {
145
+ const mcpConfig = await loadMcpServerConfig();
146
+ // Initialize Iterable client with API key and base URL from config
147
+ this.iterableClient = new IterableClient({
148
+ apiKey: mcpConfig.apiKey,
149
+ baseURL: mcpConfig.baseUrl || "https://api.iterable.com",
150
+ });
151
+ this.setupHttpInterceptors();
152
+ // Create tools with filtering based on configuration
153
+ const allTools = createAllTools(this.iterableClient);
154
+ this.tools = filterTools(allTools, mcpConfig);
155
+ // Create prompts from read-only tools only (for safety)
156
+ const readOnlyTools = filterTools(allTools, {
157
+ ...mcpConfig,
158
+ allowWrites: false,
159
+ allowSends: false,
160
+ });
161
+ this.prompts = generatePrompts(readOnlyTools);
162
+ await this.server.connect(new StdioServerTransport());
163
+ logger.info(`Iterable MCP server v${packageJson.version} running on stdio`);
164
+ logger.info(`Configuration: PII=${mcpConfig.allowUserPii}, Writes=${mcpConfig.allowWrites}, Sends=${mcpConfig.allowSends}`);
165
+ logger.info(`Available tools: ${this.tools.length}`);
166
+ logger.debug("Debug mode enabled");
167
+ }
168
+ }
169
+ function createSessionId() {
170
+ return Math.random().toString(36).slice(2) + Date.now().toString(36);
171
+ }
172
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Simple graceful shutdown handling for the MCP server
3
+ */
4
+ export declare function setupGracefulShutdown(handler?: () => Promise<void>): void;
5
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4DH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAyBzE"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Simple graceful shutdown handling for the MCP server
3
+ */
4
+ import { createIterableConfig } from "@iterable/api";
5
+ import { logger } from "@iterable/api";
6
+ // Get config for shutdown timeout
7
+ const config = (() => {
8
+ try {
9
+ const iterableConfig = createIterableConfig();
10
+ return { SHUTDOWN_TIMEOUT: iterableConfig.timeout || 30000 };
11
+ }
12
+ catch {
13
+ return { SHUTDOWN_TIMEOUT: 30000 };
14
+ }
15
+ })();
16
+ let isShuttingDown = false;
17
+ async function shutdown(signal, handler) {
18
+ if (isShuttingDown) {
19
+ logger.info("Shutdown already in progress");
20
+ return;
21
+ }
22
+ isShuttingDown = true;
23
+ logger.info("Starting graceful shutdown", { signal });
24
+ const shutdownStart = Date.now();
25
+ try {
26
+ if (handler) {
27
+ // Run shutdown handler with timeout
28
+ await Promise.race([
29
+ handler(),
30
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Shutdown timeout after ${config.SHUTDOWN_TIMEOUT}ms`)), config.SHUTDOWN_TIMEOUT)),
31
+ ]);
32
+ }
33
+ const duration = Date.now() - shutdownStart;
34
+ logger.info("Graceful shutdown completed", { duration });
35
+ process.exit(0);
36
+ }
37
+ catch (error) {
38
+ logger.error("Graceful shutdown failed", {
39
+ error: error instanceof Error ? error.message : String(error),
40
+ duration: Date.now() - shutdownStart,
41
+ });
42
+ process.exit(1);
43
+ }
44
+ }
45
+ export function setupGracefulShutdown(handler) {
46
+ // Register signal handlers
47
+ const signals = ["SIGTERM", "SIGINT"];
48
+ signals.forEach((signal) => {
49
+ process.once(signal, () => {
50
+ void shutdown(signal, handler);
51
+ });
52
+ });
53
+ // Handle uncaught errors
54
+ process.once("uncaughtException", (error) => {
55
+ logger.error("Uncaught exception, shutting down", {
56
+ error: error.message,
57
+ stack: error.stack,
58
+ });
59
+ void shutdown("uncaughtException", handler);
60
+ });
61
+ process.once("unhandledRejection", (reason) => {
62
+ logger.error("Unhandled rejection, shutting down", {
63
+ reason: String(reason),
64
+ });
65
+ void shutdown("unhandledRejection", handler);
66
+ });
67
+ }
68
+ //# sourceMappingURL=shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Tool filtering system for MCP server restrictions
3
+ * Uses safe-list approach: explicitly allow safe tools, block everything else
4
+ */
5
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
6
+ import type { McpServerConfig } from "./config.js";
7
+ export declare const NON_PII_TOOLS: Set<string>;
8
+ export declare const READ_ONLY_TOOLS: Set<string>;
9
+ /**
10
+ * Tools that can directly or indirectly trigger sending messages.
11
+ * Conservative: includes immediate sends, scheduling, triggers, and event/journey triggers.
12
+ */
13
+ export declare const SEND_TOOLS: Set<string>;
14
+ /**
15
+ * Filter tools based on configuration restrictions
16
+ * Uses safe-list approach: only allow explicitly safe tools
17
+ */
18
+ export declare function filterTools(tools: Tool[], config: McpServerConfig): Tool[];
19
+ //# sourceMappingURL=tool-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-filter.d.ts","sourceRoot":"","sources":["../src/tool-filter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,aAAa,EAAE,GAAG,CAAC,MAAM,CA2DpC,CAAC;AAEH,eAAO,MAAM,eAAe,EAAE,GAAG,CAAC,MAAM,CAsCtC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,GAAG,CAAC,MAAM,CA0BjC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,EAAE,CAO1E"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Tool filtering system for MCP server restrictions
3
+ * Uses safe-list approach: explicitly allow safe tools, block everything else
4
+ */
5
+ export const NON_PII_TOOLS = new Set([
6
+ "abort_campaign",
7
+ "activate_triggered_campaign",
8
+ "archive_campaigns",
9
+ "bulk_delete_catalog_items",
10
+ "cancel_campaign",
11
+ "create_campaign",
12
+ "create_catalog",
13
+ "create_list",
14
+ "create_snippet",
15
+ "deactivate_triggered_campaign",
16
+ "delete_catalog",
17
+ "delete_catalog_item",
18
+ "delete_list",
19
+ "delete_snippet",
20
+ "delete_templates",
21
+ "get_campaign",
22
+ "get_campaign_metrics",
23
+ "get_campaigns",
24
+ "get_catalog_field_mappings",
25
+ "get_catalog_item",
26
+ "get_catalog_items",
27
+ "get_catalogs",
28
+ "get_channels",
29
+ "get_child_campaigns",
30
+ "get_email_template",
31
+ "get_experiment_metrics",
32
+ "get_inapp_template",
33
+ "get_journeys",
34
+ "get_list_size",
35
+ "get_lists",
36
+ "get_message_types",
37
+ "get_push_template",
38
+ "get_sms_template",
39
+ "get_snippet",
40
+ "get_snippets",
41
+ "get_template_by_client_id",
42
+ "get_templates",
43
+ "get_user_fields",
44
+ "get_webhooks",
45
+ "partial_update_catalog_item",
46
+ "preview_email_template",
47
+ "preview_inapp_template",
48
+ "replace_catalog_item",
49
+ "schedule_campaign",
50
+ "send_campaign",
51
+ "trigger_campaign",
52
+ "update_catalog_field_mappings",
53
+ "update_catalog_items",
54
+ "update_email_template",
55
+ "update_inapp_template",
56
+ "update_push_template",
57
+ "update_sms_template",
58
+ "update_snippet",
59
+ "update_webhook",
60
+ "upsert_email_template",
61
+ "upsert_inapp_template",
62
+ "upsert_push_template",
63
+ "upsert_sms_template",
64
+ ]);
65
+ export const READ_ONLY_TOOLS = new Set([
66
+ "get_campaign",
67
+ "get_campaign_metrics",
68
+ "get_campaigns",
69
+ "get_catalog_field_mappings",
70
+ "get_catalog_item",
71
+ "get_catalog_items",
72
+ "get_catalogs",
73
+ "get_channels",
74
+ "get_child_campaigns",
75
+ "get_email_template",
76
+ "get_embedded_messages",
77
+ "get_experiment_metrics",
78
+ "get_export_files",
79
+ "get_export_jobs",
80
+ "get_in_app_messages",
81
+ "get_inapp_template",
82
+ "get_journeys",
83
+ "get_list_preview_users",
84
+ "get_list_size",
85
+ "get_list_users",
86
+ "get_lists",
87
+ "get_message_types",
88
+ "get_push_template",
89
+ "get_sent_messages",
90
+ "get_sms_template",
91
+ "get_snippet",
92
+ "get_snippets",
93
+ "get_template_by_client_id",
94
+ "get_templates",
95
+ "get_user_by_email",
96
+ "get_user_by_user_id",
97
+ "get_user_events_by_email",
98
+ "get_user_events_by_user_id",
99
+ "get_user_fields",
100
+ "get_webhooks",
101
+ "preview_email_template",
102
+ "preview_inapp_template",
103
+ ]);
104
+ /**
105
+ * Tools that can directly or indirectly trigger sending messages.
106
+ * Conservative: includes immediate sends, scheduling, triggers, and event/journey triggers.
107
+ */
108
+ export const SEND_TOOLS = new Set([
109
+ // Campaign sends and enablers
110
+ "send_campaign",
111
+ "trigger_campaign",
112
+ "schedule_campaign",
113
+ // Creating a blast campaign can send immediately if sendAt not provided
114
+ "create_campaign",
115
+ // Triggered campaigns can cause sends upon activation; block unless explicitly allowed
116
+ "activate_triggered_campaign",
117
+ // Journey triggers enqueue users which may send
118
+ "trigger_journey",
119
+ // Events may drive sends via triggers/journeys
120
+ "track_event",
121
+ "track_bulk_events",
122
+ // Direct per-user messaging sends
123
+ "send_email",
124
+ "send_sms",
125
+ "send_whatsapp",
126
+ "send_web_push",
127
+ "send_push",
128
+ "send_in_app",
129
+ // Template proof sends (send to specific test recipient)
130
+ "send_email_template_proof",
131
+ "send_sms_template_proof",
132
+ "send_push_template_proof",
133
+ "send_inapp_template_proof",
134
+ ]);
135
+ /**
136
+ * Filter tools based on configuration restrictions
137
+ * Uses safe-list approach: only allow explicitly safe tools
138
+ */
139
+ export function filterTools(tools, config) {
140
+ return tools.filter((tool) => (config.allowUserPii || NON_PII_TOOLS.has(tool.name)) &&
141
+ (config.allowWrites || READ_ONLY_TOOLS.has(tool.name)) &&
142
+ (config.allowSends || !SEND_TOOLS.has(tool.name)));
143
+ }
144
+ //# sourceMappingURL=tool-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-filter.js","sourceRoot":"","sources":["../src/tool-filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tools for Iterable campaign operations
3
+ */
4
+ import type { IterableClient } from "@iterable/api";
5
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
6
+ export declare function createCampaignTools(client: IterableClient): Tool[];
7
+ //# sourceMappingURL=campaigns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaigns.d.ts","sourceRoot":"","sources":["../../src/tools/campaigns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI/D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,CAwFlE"}