Skip to content

Conversation

glebedel
Copy link
Contributor

@glebedel glebedel commented Sep 12, 2025

  • Introduced Customer.io connector with functionalities for sending transactional emails, triggering broadcasts, and managing campaigns.
  • Implemented comprehensive tests for the Customer.io connector, covering various scenarios including successful email sending, broadcast triggering, and error handling.
  • Updated index to include the new CustomerIOConnectorConfig for integration with the MCP framework.

Summary by cubic

Adds a new Customer.io MCP connector with tools for emails, broadcasts, campaigns, customers, segments, events, exports, newsletters, and reporting. Supports US/EU regions and includes comprehensive tests; connector is registered in the index.

  • New Features

    • Tools for transactional emails, API-triggered broadcasts, campaign/message data, exports, newsletters, customer management, segments, event tracking, and reporting.
    • Region-aware base URLs (us, eu).
    • Zod-validated inputs and consistent error messaging.
    • Added to Connectors registry and exports.
  • Migration

    • Add credentials: appApiKey (required); siteId and trackingApiKey (optional for tracking endpoints).
    • Set setup.region to us or eu.
    • No breaking changes.

- Introduced Customer.io connector with functionalities for sending transactional emails, triggering broadcasts, and managing campaigns.
- Implemented comprehensive tests for the Customer.io connector, covering various scenarios including successful email sending, broadcast triggering, and error handling.
- Updated index to include the new CustomerIOConnectorConfig for integration with the MCP framework.
@Copilot Copilot AI review requested due to automatic review settings September 12, 2025 20:21
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a comprehensive Customer.io connector with email marketing and customer management functionality for the MCP framework. It provides tools for transactional emails, broadcast campaigns, customer data management, and reporting capabilities.

  • Implements Customer.io client with support for US and EU regions
  • Adds 26 tools covering email sending, campaign management, customer operations, and reporting
  • Includes comprehensive test coverage for core functionality and error handling

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
packages/mcp-connectors/src/index.ts Adds CustomerIOConnectorConfig to the connector registry and exports
packages/mcp-connectors/src/connectors/customerio.ts Implements the complete Customer.io connector with client class and tool definitions
packages/mcp-connectors/src/connectors/customerio.spec.ts Provides comprehensive test coverage for the Customer.io connector functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

describe('and all required fields are provided', () => {
it('returns delivery confirmation', async () => {
server.use(
http.post('https://api.customer.io/v1/api/send-email', () => {
Copy link
Preview

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API endpoint URL is incorrect. According to the implementation in customerio.ts line 238, it should be '/send/email' not '/send-email'.

Copilot uses AI. Check for mistakes.

describe('and optional message data is provided', () => {
it('includes personalization data in request', async () => {
server.use(
http.post('https://api.customer.io/v1/api/send-email', () => {
Copy link
Preview

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API endpoint URL is incorrect. According to the implementation in customerio.ts line 238, it should be '/send/email' not '/send-email'.

Copilot uses AI. Check for mistakes.

describe('when API request fails', () => {
it('returns error message', async () => {
server.use(
http.post('https://api.customer.io/v1/api/send-email', () => {
Copy link
Preview

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API endpoint URL is incorrect. According to the implementation in customerio.ts line 238, it should be '/send/email' not '/send-email'.

Copilot uses AI. Check for mistakes.


it('uses EU API endpoint', async () => {
server.use(
http.post('https://api-eu.customer.io/v1/api/send-email', () => {
Copy link
Preview

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API endpoint URL is incorrect. According to the implementation in customerio.ts line 238, it should be '/send/email' not '/send-email'.

Suggested change
http.post('https://api-eu.customer.io/v1/api/send-email', () => {
http.post('https://api-eu.customer.io/v1/api/send/email', () => {

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 3 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="packages/mcp-connectors/src/connectors/customerio.spec.ts">

<violation number="1" location="packages/mcp-connectors/src/connectors/customerio.spec.ts:23">
MSW handler targets /send-email but the connector calls /send/email, so the request won’t be intercepted and the test will fail under onUnhandledRequest: &#39;error&#39;.</violation>

<violation number="2" location="packages/mcp-connectors/src/connectors/customerio.spec.ts:689">
EU region test targets /send-email but the connector calls /send/email; MSW won’t match and the test will fail.</violation>
</file>

<file name="packages/mcp-connectors/src/connectors/customerio.ts">

<violation number="1" location="packages/mcp-connectors/src/connectors/customerio.ts:238">
Transactional email endpoint path uses /send/email but tests and expected path are /send-email; this mismatch will cause requests to go unhandled in tests and likely fail at runtime.</violation>

<violation number="2" location="packages/mcp-connectors/src/connectors/customerio.ts:535">
Using || may overwrite a valid timestamp of 0; prefer nullish coalescing to only default when undefined or null.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.


it('uses EU API endpoint', async () => {
server.use(
http.post('https://api-eu.customer.io/v1/api/send-email', () => {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EU region test targets /send-email but the connector calls /send/email; MSW won’t match and the test will fail.

Prompt for AI agents
Address the following comment on packages/mcp-connectors/src/connectors/customerio.spec.ts at line 689:

<comment>EU region test targets /send-email but the connector calls /send/email; MSW won’t match and the test will fail.</comment>

<file context>
@@ -0,0 +1,717 @@
+
+    it(&#39;uses EU API endpoint&#39;, async () =&gt; {
+      server.use(
+        http.post(&#39;https://api-eu.customer.io/v1/api/send-email&#39;, () =&gt; {
+          return HttpResponse.json({
+            delivery_id: &#39;eu-delivery-123&#39;,
</file context>
Suggested change
http.post('https://api-eu.customer.io/v1/api/send-email', () => {
http.post('https://api-eu.customer.io/v1/api/send/email', () => {
Fix with Cubic

describe('and all required fields are provided', () => {
it('returns delivery confirmation', async () => {
server.use(
http.post('https://api.customer.io/v1/api/send-email', () => {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSW handler targets /send-email but the connector calls /send/email, so the request won’t be intercepted and the test will fail under onUnhandledRequest: 'error'.

Prompt for AI agents
Address the following comment on packages/mcp-connectors/src/connectors/customerio.spec.ts at line 23:

<comment>MSW handler targets /send-email but the connector calls /send/email, so the request won’t be intercepted and the test will fail under onUnhandledRequest: &#39;error&#39;.</comment>

<file context>
@@ -0,0 +1,717 @@
+      describe(&#39;and all required fields are provided&#39;, () =&gt; {
+        it(&#39;returns delivery confirmation&#39;, async () =&gt; {
+          server.use(
+            http.post(&#39;https://api.customer.io/v1/api/send-email&#39;, () =&gt; {
+              return HttpResponse.json({
+                delivery_id: &#39;test-delivery-123&#39;,
</file context>
Suggested change
http.post('https://api.customer.io/v1/api/send-email', () => {
http.post('https://api.customer.io/v1/api/send/email', () => {
Fix with Cubic

body: JSON.stringify({
name: event.name,
data: event.data,
timestamp: event.timestamp || Math.floor(Date.now() / 1000),
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using || may overwrite a valid timestamp of 0; prefer nullish coalescing to only default when undefined or null.

Prompt for AI agents
Address the following comment on packages/mcp-connectors/src/connectors/customerio.ts at line 535:

<comment>Using || may overwrite a valid timestamp of 0; prefer nullish coalescing to only default when undefined or null.</comment>

<file context>
@@ -0,0 +1,1315 @@
+        body: JSON.stringify({
+          name: event.name,
+          data: event.data,
+          timestamp: event.timestamp || Math.floor(Date.now() / 1000),
+        }),
+      }
</file context>
Suggested change
timestamp: event.timestamp || Math.floor(Date.now() / 1000),
timestamp: event.timestamp ?? Math.floor(Date.now() / 1000),
Fix with Cubic

async sendTransactionalEmail(
data: TransactionalEmailRequest
): Promise<TransactionalEmailResponse> {
const response = await fetch(`${this.baseUrl}/send/email`, {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transactional email endpoint path uses /send/email but tests and expected path are /send-email; this mismatch will cause requests to go unhandled in tests and likely fail at runtime.

Prompt for AI agents
Address the following comment on packages/mcp-connectors/src/connectors/customerio.ts at line 238:

<comment>Transactional email endpoint path uses /send/email but tests and expected path are /send-email; this mismatch will cause requests to go unhandled in tests and likely fail at runtime.</comment>

<file context>
@@ -0,0 +1,1315 @@
+  async sendTransactionalEmail(
+    data: TransactionalEmailRequest
+  ): Promise&lt;TransactionalEmailResponse&gt; {
+    const response = await fetch(`${this.baseUrl}/send/email`, {
+      method: &#39;POST&#39;,
+      headers: this.headers,
</file context>
Suggested change
const response = await fetch(`${this.baseUrl}/send/email`, {
const response = await fetch(`${this.baseUrl}/send-email`, {
Fix with Cubic

@glebedel glebedel marked this pull request as draft September 20, 2025 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant