Skip to content

Integrate template tools #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cf49bdf
Enhance Mailtrap client configuration to conditionally set accountId …
narekhovhannisyan Aug 8, 2025
7ef5169
Update README.md to include new Mailtrap template management operatio…
narekhovhannisyan Aug 8, 2025
d48c223
Add email template management operations to the server
narekhovhannisyan Aug 8, 2025
4685d70
Add email template management functions: create, delete, list, and up…
narekhovhannisyan Aug 8, 2025
8925fa8
Add index file for email template management functions
narekhovhannisyan Aug 8, 2025
b4b09f0
Add unit tests for email template management functions
narekhovhannisyan Aug 8, 2025
19dd35f
Add schemas for email template management operations
narekhovhannisyan Aug 8, 2025
0a93350
Add interfaces for email template management requests
narekhovhannisyan Aug 8, 2025
ac0f7f2
Fix typo in README.md by correcting "MAILTRA_ACCOUNT_ID" to "MAILTRAP…
narekhovhannisyan Aug 11, 2025
58ddacf
Enhance Mailtrap client configuration to validate MAILTRAP_ACCOUNT_ID…
narekhovhannisyan Aug 11, 2025
dfd0606
Implement validation for updateTemplate function to ensure at least o…
narekhovhannisyan Aug 11, 2025
7f60905
Add test for updateTemplate function to reject updates with no fields…
narekhovhannisyan Aug 11, 2025
3c20f57
Update README.md to clarify requirements for update-template function
narekhovhannisyan Aug 12, 2025
e9a5127
improve readme
yanchuk Aug 12, 2025
5585290
Update Mailtrap dependency to version 4.2.0 and add yarn.lock file fo…
narekhovhannisyan Aug 15, 2025
de31afe
Update Mailtrap dependency to version 4.2.0 and remove yarn.lock file…
narekhovhannisyan Aug 15, 2025
9e6bdae
bump version
yanchuk Aug 18, 2025
e3eefec
fix cursor and vs code links
yanchuk Aug 18, 2025
7b495ed
add claude.md
yanchuk Aug 18, 2025
d250419
add agent.md
yanchuk Aug 18, 2025
1fe652e
Update SendMailToolRequest interface to require category field
narekhovhannisyan Aug 20, 2025
ed84ae3
Refactor category field in sendEmail schema to be required for tracking
narekhovhannisyan Aug 20, 2025
c344b54
Clarify requirements for email template fields in README.md
narekhovhannisyan Aug 20, 2025
0f8516c
Update README.md to change category field from optional to required f…
narekhovhannisyan Aug 21, 2025
62f8727
Update sendEmail tests to include required category field in email data
narekhovhannisyan Aug 21, 2025
6ec93c5
Implement validation for email template creation to ensure at least o…
narekhovhannisyan Aug 25, 2025
f2264aa
Enhance validation in updateTemplate function to ensure that when bot…
narekhovhannisyan Aug 25, 2025
5533355
Make 'html' field optional in createTemplate schema to allow for more…
narekhovhannisyan Aug 25, 2025
5c33992
Make 'html' field optional in CreateTemplateRequest interface to enha…
narekhovhannisyan Aug 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions AGENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# AGENT.md

## Build/Lint/Test Commands
- `npm run build` - Compile TypeScript to dist/
- `npm run lint` - Run ESLint and TypeScript checks
- `npm test` - Run all Jest tests
- `npm run test:watch` - Run tests in watch mode
- `jest src/tools/sendEmail/__tests__/sendEmail.test.ts` - Run single test file
- `npm run dev` - Run MCP server with inspector for testing

## Architecture
- MCP (Model Context Protocol) server integrating with Mailtrap email service
- Main entry point: `src/index.ts` registers tools and handles server lifecycle
- Tools located in `src/tools/` with pattern: each tool has subdirectory with index.ts, schema.ts, implementation.ts, and __tests__/
- Client configuration: `src/client.ts` handles Mailtrap API initialization
- Configuration: `src/config/index.ts` for server constants

## Code Style
- Uses Airbnb TypeScript ESLint config with Prettier
- TypeScript strict mode enabled, targeting ES2022 with CommonJS
- Zod schemas for all tool input validation
- Error handling: catch and re-throw with descriptive messages
- Import style: ES modules syntax, grouped with external first
- Naming: camelCase for functions/variables, PascalCase for types/interfaces
- No console.log allowed in production code (use proper error handling)
69 changes: 69 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands

### Build and Development
- `npm run build` - Compile TypeScript to JavaScript in the `dist/` directory
- `npm run dev` - Run the MCP server with the MCP Inspector for testing
- `npm run prepublish` - Build the project and make the executable script executable

### Code Quality
- `npm run lint` - Run both ESLint and TypeScript checks
- `npm run lint:eslint` - Run ESLint for code style checking
- `npm run lint:tsc` - Run TypeScript compiler for type checking

### Testing
- `npm test` - Run all Jest tests
- `npm run test:watch` - Run tests in watch mode during development
- `npm run test:coverage` - Run tests with coverage reporting

## Project Architecture

This is an MCP (Model Context Protocol) server that integrates with Mailtrap's email service. The architecture follows a modular pattern:

### Core Components
- **src/index.ts**: Main MCP server entry point that registers all tools and handles the server lifecycle
- **src/client.ts**: Mailtrap client configuration and initialization
- **src/config/index.ts**: Server configuration constants

### Tool Architecture
All tools follow a consistent pattern in the `src/tools/` directory:
- Each tool has its own subdirectory (e.g., `sendEmail/`, `templates/`)
- Tools export both their implementation function and Zod schema for validation
- Template operations are grouped under `templates/` with individual files for each CRUD operation

### Tool Structure Pattern
```
src/tools/{toolName}/
├── index.ts # Main tool export
├── schema.ts # Zod validation schema
├── {toolName}.ts # Tool implementation
└── __tests__/ # Jest test files
```

### Environment Variables Required
- `MAILTRAP_API_TOKEN`: Required API token from Mailtrap
- `DEFAULT_FROM_EMAIL`: Default sender email address
- `MAILTRAP_ACCOUNT_ID`: Optional account ID for multi-account setups

### Testing Setup
- Uses Jest with TypeScript support via ts-jest
- Test files are located in `__tests__/` directories within each tool
- Environment variables are set up via `jest/setEnvVars.js`
- Coverage reports exclude test files and type definitions

### Build Configuration
- TypeScript compilation targets ES2022 with CommonJS modules
- Separate build config (`tsconfig.build.json`) excludes test files from distribution
- Output goes to `dist/` directory with proper executable permissions

### Available MCP Tools
1. **send-email**: Send transactional emails through Mailtrap
2. **create-template**: Create new email templates
3. **list-templates**: List all email templates
4. **update-template**: Update existing email templates
5. **delete-template**: Delete email templates

Each tool uses Zod schemas for input validation and follows the MCP protocol for response formatting.
91 changes: 79 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@

# MCP Mailtrap Server

An MCP server that provides a tool for sending transactional emails via Mailtrap
An MCP server that provides tools for sending transactional emails and managing email templates via Mailtrap

## Prerequisites

Before using this MCP server, you need to:

1. [Create a Mailtrap account](https://mailtrap.io/signup)
2. [Verify your domain](https://mailtrap.io/sending/domains)
3. Get your API token from [Mailtrap API settings](https://mailtrap.io/api-tokens)
4. Get your Account ID from [Mailtrap account management](https://mailtrap.io/account-management)

## Quick Install

[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=mailtrap&config=eyJjb21tYW5kIjoibnB4IC15IG1jcC1tYWlsdHJhcCIsImVudiI6eyJNQUlMVFJBUF9BUElfVE9LRU4iOiJ5b3VyX21haWx0cmFwX2FwaV90b2tlbiIsIkRFRkFVTFRfRlJPTV9FTUFJTCI6InlvdXJfc2VuZGVyQGV4YW1wbGUuY29tIn19)
[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=mailtrap&config=eyJjb21tYW5kIjoibnB4IC15IG1jcC1tYWlsdHJhcCIsImVudiI6eyJNQUlMVFJBUF9BUElfVE9LRU4iOiJ5b3VyX21haWx0cmFwX2FwaV90b2tlbiIsIkRFRkFVTFRfRlJPTV9FTUFJTCI6InlvdXJfc2VuZGVyQGV4YW1wbGUuY29tIiwiTUFJTFRSQVBfQUNDT1VOVF9JRCI6InlvdXJfYWNjb3VudF9pZCJ9fQ%3D%3D)

[![Install with Node in VS Code](https://img.shields.io/badge/VS_Code-Node-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mailtrap-email&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-mailtrap%22%5D%2C%22env%22%3A%7B%22MAILTRAP_API_TOKEN%22%3A%22%24%7Binput%3AmailtrapApiToken%7D%22%2C%22DEFAULT_FROM_EMAIL%22%3A%22%24%7Binput%3AsenderEmail%7D%22%7D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22mailtrapApiToken%22%2C%22description%22%3A%22Mailtrap+API+Token%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22senderEmail%22%2C%22description%22%3A%22Sender+Email+Address%22%7D%5D)
[![Install with Node in VS Code](https://img.shields.io/badge/VS_Code-Node-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mailtrap&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-mailtrap%22%5D%2C%22env%22%3A%7B%22MAILTRAP_API_TOKEN%22%3A%22%24%7Binput%3AmailtrapApiToken%7D%22%2C%22DEFAULT_FROM_EMAIL%22%3A%22%24%7Binput%3AsenderEmail%7D%22%2C%22MAILTRAP_ACCOUNT_ID%22%3A%22%24%7Binput%3AmailtrapAccountId%7D%22%7D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22mailtrapApiToken%22%2C%22description%22%3A%22Mailtrap+API+Token%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22senderEmail%22%2C%22description%22%3A%22Sender+Email+Address%22%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22mailtrapAccountId%22%2C%22description%22%3A%22Mailtrap+Account+ID%22%7D%5D)

[![Install with Node in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Node-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mailtrap-email&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-mailtrap%22%5D%2C%22env%22%3A%7B%22MAILTRAP_API_TOKEN%22%3A%22%24%7Binput%3AmailtrapApiToken%7D%22%2C%22DEFAULT_FROM_EMAIL%22%3A%22%24%7Binput%3AsenderEmail%7D%22%7D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22mailtrapApiToken%22%2C%22description%22%3A%22Mailtrap+API+Token%22%2C%22password%22%3Atrue%7D%2C%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22senderEmail%22%2C%22description%22%3A%22Sender+Email+Address%22%7D%5D&quality=insiders)


## Setup
Expand All @@ -29,7 +37,8 @@ Add the following configuration:
"args": ["-y", "mcp-mailtrap"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand All @@ -50,7 +59,8 @@ If you are using `asdf` for managing Node.js you must use absolute path to execu
"ASDF_DATA_DIR": "/Users/<username>/.asdf",
"ASDF_NODEJS_VERSION": "20.6.1",
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand Down Expand Up @@ -89,7 +99,8 @@ Then, in the settings file, add the following configuration:
"args": ["-y", "mcp-mailtrap"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand All @@ -102,11 +113,20 @@ Then, in the settings file, add the following configuration:

## Usage

Once configured, you can ask agent to send emails, for example:
Once configured, you can ask agent to send emails and manage templates, for example:

**Email Operations:**

- "Send an email to john.doe@example.com with the subject 'Meeting Tomorrow' and a friendly reminder about our upcoming meeting."
- "Email sarah@example.com about the project update, and CC the team at team@example.com"

**Template Operations:**

- "List all email templates in my Mailtrap account"
- "Create a new email template called 'Welcome Email' with subject 'Welcome to our platform!'"
- "Update the template with ID 12345 to change the subject to 'Updated Welcome Message'"
- "Delete the template with ID 67890"

## Available Tools

### send-email
Expand All @@ -118,12 +138,56 @@ Sends a transactional email through Mailtrap.
- `to` (required): Email address of the recipient
- `subject` (required): Email subject line
- `from` (optional): Email address of the sender, if not provided "DEFAULT_FROM_EMAIL" will be used
- `text` (optional): Email body text, require if "html" is empty
- `text` (optional): Email body text, required if "html" is empty
- `html` (optional): HTML version of the email body, required if "text" is empty
- `cc` (optional): Array of CC recipient email addresses
- `bcc` (optional): Array of BCC recipient email addresses
- `category` (optional): Email category for tracking

### create-template

Creates a new email template in your Mailtrap account.

**Parameters:**

- `name` (required): Name of the template
- `subject` (required): Email subject line
- `html` (or `text` is required): HTML content of the template
- `text` (or `html` is required): Plain text version of the template
- `category` (optional): Template category (defaults to "General")

### list-templates

Lists all email templates in your Mailtrap account.

**Parameters:**

- No parameters required

### update-template

Updates an existing email template.

**Parameters:**

- `template_id` (required): ID of the template to update
- `name` (optional): New name for the template
- `subject` (optional): New email subject line
- `html` (optional): New HTML content of the template
- `text` (optional): New plain text version of the template
- `category` (optional): New category for the template

> [!NOTE]
> At least one updatable field (name, subject, html, text, or category) must be provided when calling update-template to perform an update.

### delete-template

Deletes an existing email template.

**Parameters:**

- `template_id` (required): ID of the template to delete

## Development

1. Clone the repository:
Expand Down Expand Up @@ -154,7 +218,8 @@ Add the following configuration:
"args": ["/path/to/mailtrap-mcp/dist/index.js"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand All @@ -177,7 +242,8 @@ If you are using `asdf` for managing Node.js you should use absolute path to exe
"ASDF_DATA_DIR": "/Users/<username>/.asdf",
"ASDF_NODEJS_VERSION": "20.6.1",
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand All @@ -198,7 +264,8 @@ If you are using `asdf` for managing Node.js you should use absolute path to exe
"args": ["/path/to/mailtrap-mcp/dist/index.js"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com"
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id"
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mcp-mailtrap",
"version": "0.0.2",
"version": "0.0.3",
"description": "Official MCP Server for Mailtrap",
"license": "MIT",
"author": "Railsware Products Studio LLC",
Expand Down Expand Up @@ -31,7 +31,7 @@
"dependencies": {
"@modelcontextprotocol/sdk": "^1.8.0",
"dotenv": "^16.4.7",
"mailtrap": "^4.0.0",
"mailtrap": "^4.2.0",
"zod": "^3.24.2"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ if (!MAILTRAP_API_TOKEN) {

const client = new MailtrapClient({
token: MAILTRAP_API_TOKEN,
// conditionally set accountId if it's a valid number
...(process.env.MAILTRAP_ACCOUNT_ID && !isNaN(Number(process.env.MAILTRAP_ACCOUNT_ID))
? { accountId: Number(process.env.MAILTRAP_ACCOUNT_ID) }
: {}),
});

// eslint-disable-next-line import/prefer-default-export
Expand Down
41 changes: 41 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import dotenv from "dotenv";
import CONFIG from "./config";

import { sendEmailSchema, sendEmail } from "./tools/sendEmail";
import {
createTemplate,
createTemplateSchema,
deleteTemplate,
deleteTemplateSchema,
listTemplates,
listTemplatesSchema,
updateTemplate,
updateTemplateSchema,
} from "./tools/templates";

dotenv.config();

Expand All @@ -14,13 +24,44 @@ const server = new McpServer({
version: CONFIG.MCP_SERVER_VERSION,
});

/**
* Sending operations.
*/
server.tool(
"send-email",
"Send transactional email using Mailtrap",
sendEmailSchema,
sendEmail
);

/**
* Templates operations.
*/
server.tool(
"create-template",
"Create a new email template",
createTemplateSchema,
createTemplate
);
server.tool(
"list-templates",
"List all email templates",
listTemplatesSchema,
listTemplates
);
server.tool(
"update-template",
"Update an existing email template",
updateTemplateSchema,
updateTemplate
);
server.tool(
"delete-template",
"Delete an existing email template",
deleteTemplateSchema,
deleteTemplate
);

async function main() {
const transport = new StdioServerTransport();

Expand Down
5 changes: 1 addition & 4 deletions src/tools/sendEmail/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ const sendEmailSchema = {
.array(z.string().email())
.optional()
.describe("Optional BCC recipients"),
category: z
.string()
.optional()
.describe("Optional email category for tracking"),
category: z.string().describe("Email category for tracking"),
text: z.string().optional().describe("Email body text"),
html: z
.string()
Expand Down
Loading