MT-22401: Add email campaigns tools - #128
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdded email campaign tools for CRUD operations, lifecycle management, scheduling, cancellation, termination, reset, listing, retrieval, and statistics. Added typed contracts, validation schemas, server registration, tests, and documentation. ChangesEmail Campaigns
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant Server
participant EmailCampaignsClient
MCPClient->>Server: Invoke an email campaign tool
Server->>EmailCampaignsClient: Execute the campaign operation
EmailCampaignsClient-->>Server: Return campaign or statistics data
Server-->>MCPClient: Return formatted tool response
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Aligned with the account-id fix from the Python/Node.js PRs: all 11 campaign handlers now call |
a2d725e to
44d7081
Compare
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (3)
src/tools/emailCampaigns/listEmailCampaigns.ts (1)
13-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftUse the required per-tool directory layout.
Move this tool to
src/tools/emailCampaigns/listEmailCampaigns/. Addindex.ts,schema.ts,implementation.ts, and__tests__/.Apply the same layout to the other campaign tools. The current shared
schemas/and__tests__/directories do not meet the configured tool structure.As per coding guidelines, “each tool has subdirectory with index.ts, schema.ts, implementation.ts, and tests/.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/emailCampaigns/listEmailCampaigns.ts` around lines 13 - 50, Restructure the email campaign tools to use per-tool directories: move each tool into its own directory under emailCampaigns, including listEmailCampaigns, with index.ts, schema.ts, implementation.ts, and __tests__/; update imports and exports to preserve existing behavior, and remove reliance on the shared schemas/ and __tests__/ directories.Source: Coding guidelines
src/tools/emailCampaigns/getEmailCampaign.ts (1)
12-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse camelCase for campaign request local variables.
The JSON wire fields must remain snake_case. Alias them at destructuring boundaries, then use camelCase variables in each handler.
src/tools/emailCampaigns/getEmailCampaign.ts#L12-L20: Aliasemail_campaign_idtoemailCampaignId.src/tools/emailCampaigns/deleteEmailCampaign.ts#L12-L23: Aliasemail_campaign_idtoemailCampaignId.src/tools/emailCampaigns/startEmailCampaign.ts#L12-L20: Aliasemail_campaign_idtoemailCampaignId.src/tools/emailCampaigns/terminateEmailCampaign.ts#L12-L20: Aliasemail_campaign_idtoemailCampaignId.src/tools/emailCampaigns/getEmailCampaignStats.ts#L12-L29: Aliasemail_campaign_id,start_date, andend_dateto camelCase variables.As per coding guidelines: “Use camelCase for functions and variables.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/emailCampaigns/getEmailCampaign.ts` around lines 12 - 20, Alias the snake_case request fields at destructuring boundaries and use camelCase locals throughout each handler: in src/tools/emailCampaigns/getEmailCampaign.ts lines 12-20, deleteEmailCampaign.ts lines 12-23, startEmailCampaign.ts lines 12-20, and terminateEmailCampaign.ts lines 12-20, rename email_campaign_id to emailCampaignId; in src/tools/emailCampaigns/getEmailCampaignStats.ts lines 12-29, also rename start_date to startDate and end_date to endDate. Preserve the original snake_case JSON wire fields.Source: Coding guidelines
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts (1)
1-23: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftPlace each campaign tool in its required tool directory.
The reviewed files use shared
schemas/and__tests__/directories. This does not provide the required per-toolindex.ts,schema.ts,implementation.ts, and__tests__/structure.
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts#L1-L23: move togetEmailCampaignStats/schema.ts.src/tools/emailCampaigns/schemas/resetEmailCampaign.ts#L1-L13: move toresetEmailCampaign/schema.ts.src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts#L1-L27: move toscheduleEmailCampaign/schema.ts.src/tools/emailCampaigns/schemas/startEmailCampaign.ts#L1-L13: move tostartEmailCampaign/schema.ts.src/tools/emailCampaigns/schemas/terminateEmailCampaign.ts#L1-L13: move toterminateEmailCampaign/schema.ts.src/tools/emailCampaigns/scheduleEmailCampaign.ts#L1-L39: move toscheduleEmailCampaign/implementation.tsand add itsindex.ts.src/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.ts#L1-L71: move underscheduleEmailCampaign/__tests__/.src/tools/emailCampaigns/__tests__/cancelEmailCampaign.test.ts#L1-L48: move undercancelEmailCampaign/__tests__/.src/tools/emailCampaigns/__tests__/terminateEmailCampaign.test.ts#L1-L48: move underterminateEmailCampaign/__tests__/.As per coding guidelines,
src/tools/**/*.tstools must use a subdirectory withindex.ts,schema.ts,implementation.ts, and__tests__/.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts` around lines 1 - 23, Reorganize the email campaign tools into per-tool directories with index.ts, schema.ts, implementation.ts, and __tests__/ structures. Move the schemas from src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts, resetEmailCampaign.ts, scheduleEmailCampaign.ts, startEmailCampaign.ts, and terminateEmailCampaign.ts to their corresponding tool directories as schema.ts; move src/tools/emailCampaigns/scheduleEmailCampaign.ts to scheduleEmailCampaign/implementation.ts and add its index.ts; move the schedule, cancel, and terminate test files from src/tools/emailCampaigns/__tests__/ into their corresponding tool __tests__/ directories. Update imports and exports to preserve existing tool behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CLAUDE.md`:
- Around line 182-195: Update the environment-variable documentation to include
all email campaign tools in the exception for MAILTRAP_ACCOUNT_ID, alongside
send-email and send-sandbox-email, reflecting the requireClient("email
campaigns", { requireAccountId: false }) behavior.
In `@src/tools/emailCampaigns/createEmailCampaign.ts`:
- Around line 23-27: Upgrade the Mailtrap SDK dependency to a release that
implements the emailCampaigns API, then update the client setup in the
createEmailCampaign flow to use the SDK-provided EmailCampaignsClient type and
remove the temporary unknown cast before calling mailtrap.emailCampaigns.create.
In `@src/tools/emailCampaigns/getEmailCampaign.ts`:
- Around line 16-20: Upgrade the mailtrap dependency in package.json and
package-lock.json to the future SDK release that provides EmailCampaignsClient
and emailCampaigns before exposing these handlers. Apply the dependency
alignment for getEmailCampaign.ts, deleteEmailCampaign.ts,
startEmailCampaign.ts, terminateEmailCampaign.ts, and getEmailCampaignStats.ts;
no direct handler logic change is required.
In `@src/tools/emailCampaigns/index.ts`:
- Around line 1-22: Reorganize the eleven campaign tools imported by
emailCampaigns/index.ts so each tool has its own directory containing index.ts,
schema.ts, implementation.ts, and __tests__/. Move the corresponding schema and
implementation files together for listEmailCampaigns, getEmailCampaign,
createEmailCampaign, updateEmailCampaign, deleteEmailCampaign,
startEmailCampaign, scheduleEmailCampaign, cancelEmailCampaign,
terminateEmailCampaign, resetEmailCampaign, and getEmailCampaignStats, and leave
emailCampaigns/index.ts only for group-level exports.
In `@src/tools/emailCampaigns/schemas/cancelEmailCampaign.ts`:
- Around line 4-5: Update the email_campaign_id schema property in
cancelEmailCampaign.ts (lines 4-5), deleteEmailCampaign.ts (lines 4-5), and
getEmailCampaign.ts (lines 4-5) to use type "integer" with minimum 1, ensuring
all campaign-ID schemas accept only positive integers.
In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts`:
- Around line 4-7: Constrain the email_campaign_id property in every exposed
schema to positive integers by using type "integer" and minimum 1, matching the
existing Zod identifier constraint. Apply this in
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts (lines 4-7),
resetEmailCampaign.ts (lines 4-7), scheduleEmailCampaign.ts (lines 6-9),
startEmailCampaign.ts (lines 4-7), and terminateEmailCampaign.ts (lines 4-7).
- Around line 8-17: Update the start_date and end_date properties in the email
campaign stats schema to validate the documented YYYY-MM-DD format, using a
pattern or equivalent date constraint that rejects invalid strings while
preserving their existing optional defaults and descriptions.
In `@src/tools/emailCampaigns/schemas/listEmailCampaigns.ts`:
- Around line 6-14: Align both email campaign JSON Schemas with their Zod
validators: in src/tools/emailCampaigns/schemas/listEmailCampaigns.ts lines
6-14, make token and per_page positive integers and set per_page.maximum to 100;
in src/tools/emailCampaigns/schemas/updateEmailCampaign.ts lines 6-107, make
campaign, list, and segment IDs plus emails_per_hour integers and add every
minimum constraint enforced by the corresponding Zod validator.
In `@src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts`:
- Around line 20-25: The scheduleEmailCampaignZod schema must validate datetime
invariants before scheduling: use offset-aware datetime parsing, require a
future timestamp, and reject values more than one month ahead. In
src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts at lines 20-25, update
the datetime validation and refinements; in
src/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.ts at lines 20-54,
change the success fixture to a future timestamp and add rejection coverage for
non-ISO, past, and over-one-month values.
In `@src/tools/emailCampaigns/schemas/updateEmailCampaign.ts`:
- Around line 61-64: Update the body_text field in the UpdateEmailCampaignParams
schema to accept optional null values by using the nullable optional Zod type,
and update its JSON Schema representation to allow both string and null while
preserving the existing description and optional behavior.
- Around line 110-144: Update updateEmailCampaignZod and its corresponding JSON
Schema so requests must include at least one mutable field in addition to
email_campaign_id. Apply the non-empty update constraint to the existing
optional fields without making the required identifier optional, and ensure both
validation definitions reject identifier-only payloads.
In `@src/types/mailtrap.ts`:
- Around line 803-832: Upgrade the mailtrap dependency to a release that
provides the runtime emailCampaigns resource, then remove the temporary
EmailCampaignsClient interface and all per-handler casts relying on it. Update
campaign handlers to use the typed SDK client directly while preserving the
existing campaign operations.
---
Nitpick comments:
In `@src/tools/emailCampaigns/getEmailCampaign.ts`:
- Around line 12-20: Alias the snake_case request fields at destructuring
boundaries and use camelCase locals throughout each handler: in
src/tools/emailCampaigns/getEmailCampaign.ts lines 12-20, deleteEmailCampaign.ts
lines 12-23, startEmailCampaign.ts lines 12-20, and terminateEmailCampaign.ts
lines 12-20, rename email_campaign_id to emailCampaignId; in
src/tools/emailCampaigns/getEmailCampaignStats.ts lines 12-29, also rename
start_date to startDate and end_date to endDate. Preserve the original
snake_case JSON wire fields.
In `@src/tools/emailCampaigns/listEmailCampaigns.ts`:
- Around line 13-50: Restructure the email campaign tools to use per-tool
directories: move each tool into its own directory under emailCampaigns,
including listEmailCampaigns, with index.ts, schema.ts, implementation.ts, and
__tests__/; update imports and exports to preserve existing behavior, and remove
reliance on the shared schemas/ and __tests__/ directories.
In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts`:
- Around line 1-23: Reorganize the email campaign tools into per-tool
directories with index.ts, schema.ts, implementation.ts, and __tests__/
structures. Move the schemas from
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts,
resetEmailCampaign.ts, scheduleEmailCampaign.ts, startEmailCampaign.ts, and
terminateEmailCampaign.ts to their corresponding tool directories as schema.ts;
move src/tools/emailCampaigns/scheduleEmailCampaign.ts to
scheduleEmailCampaign/implementation.ts and add its index.ts; move the schedule,
cancel, and terminate test files from src/tools/emailCampaigns/__tests__/ into
their corresponding tool __tests__/ directories. Update imports and exports to
preserve existing tool behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d43326b4-34a7-48df-b3cb-dcc2541858d5
📒 Files selected for processing (38)
CLAUDE.mdREADME.mdsrc/server.tssrc/tools/emailCampaigns/__tests__/cancelEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/createEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/deleteEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/getEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/getEmailCampaignStats.test.tssrc/tools/emailCampaigns/__tests__/listEmailCampaigns.test.tssrc/tools/emailCampaigns/__tests__/resetEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/startEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/terminateEmailCampaign.test.tssrc/tools/emailCampaigns/__tests__/updateEmailCampaign.test.tssrc/tools/emailCampaigns/cancelEmailCampaign.tssrc/tools/emailCampaigns/createEmailCampaign.tssrc/tools/emailCampaigns/deleteEmailCampaign.tssrc/tools/emailCampaigns/getEmailCampaign.tssrc/tools/emailCampaigns/getEmailCampaignStats.tssrc/tools/emailCampaigns/index.tssrc/tools/emailCampaigns/listEmailCampaigns.tssrc/tools/emailCampaigns/resetEmailCampaign.tssrc/tools/emailCampaigns/scheduleEmailCampaign.tssrc/tools/emailCampaigns/schemas/cancelEmailCampaign.tssrc/tools/emailCampaigns/schemas/createEmailCampaign.tssrc/tools/emailCampaigns/schemas/deleteEmailCampaign.tssrc/tools/emailCampaigns/schemas/getEmailCampaign.tssrc/tools/emailCampaigns/schemas/getEmailCampaignStats.tssrc/tools/emailCampaigns/schemas/listEmailCampaigns.tssrc/tools/emailCampaigns/schemas/resetEmailCampaign.tssrc/tools/emailCampaigns/schemas/scheduleEmailCampaign.tssrc/tools/emailCampaigns/schemas/startEmailCampaign.tssrc/tools/emailCampaigns/schemas/terminateEmailCampaign.tssrc/tools/emailCampaigns/schemas/updateEmailCampaign.tssrc/tools/emailCampaigns/startEmailCampaign.tssrc/tools/emailCampaigns/terminateEmailCampaign.tssrc/tools/emailCampaigns/updateEmailCampaign.tssrc/types/mailtrap.ts
Decisions:
- 11 tools mirror src/tools/contactLists/ layout (one file per tool, schemas/, __tests__, barrel index.ts), registered after the contacts group in src/server.ts
- Handlers target the future mailtrap npm emailCampaigns surface via a local EmailCampaignsClient interface in src/types/mailtrap.ts with a single TODO(MT-22401) to drop the casts after the SDK release
- Single-object and stats responses unwrap the {data} envelope; list keeps {data, pagination} so page tokens stay visible; delete returns a {email_campaign_id, deleted: true} confirmation
- Zod validation layer added for list/create/update/schedule per repo CLAUDE.md recommendation
- readOnlyHint for list/get/stats; destructiveHint: true for create/update/delete and all five lifecycle tools per the MT-22401 plan
Decisions: - The email campaigns endpoints are token-scoped, so the handlers now pass requireAccountId: false (listAccounts precedent), matching the same fix in the Python and Node.js SDK PRs
44d7081 to
fdcd44b
Compare
Decisions: - Rename EmailCampaignPagination to Pagination; nothing in it is campaign-specific - Move it to a Common types section so the next paginated tool reuses it
Decisions: - The backend allows deleting only a campaign in the draft state (EmailCampaign#validate_soft_delete), not merely a non-sending one - Examples deleted a campaign after start/terminate, which would 422; a started campaign can never return to draft, so they now delete a fresh draft
Motivation
MT-22401
Port the Email Campaigns public API (MT-21113) to the MCP server.
Do not merge until mailtrap-nodejs#148 is released to npm and the
mailtrapdep is bumped here — handlers callclient.emailCampaigns.*, which doesn't exist in 4.8.0. Types compile today via a localEmailCampaignsClientinterface cast (marked with aTODO(MT-22401)to drop after the bump).Changes
list-email-campaigns,get-email-campaign,create-email-campaign,update-email-campaign,delete-email-campaign,start-email-campaign,schedule-email-campaign,cancel-email-campaign,terminate-email-campaign,reset-email-campaign,get-email-campaign-stats.strict()validation layer on list/create/update/schedule; lifecycle preconditions (draft-only, scheduled-only, sending-states) called out in tool descriptionsdataenvelope; list keeps{data, pagination}so page tokens stay usable; delete returns{email_campaign_id, deleted: true}How to test
mailtrapdep and real env vars, ask the MCP client to create a draft campaign, update its design, schedule and cancel it, fetch stats, then delete itFailed to cancel email campaign: ...messageSummary by CodeRabbit
Before merge
mailtrapto the release that shipsemailCampaigns(mailtrap-nodejs PR #148) and remove the temporaryEmailCampaignsClientinterface and per-handler casts