easy-email-pro-mcp 1.55.1
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.
- package/CHANGELOG.md +9 -0
- package/README.md +196 -0
- package/next.config.js +32 -0
- package/package.json +30 -0
- package/pages/api/mcp.ts +137 -0
- package/src/auth.ts +60 -0
- package/src/index.ts +10 -0
- package/src/knowledge/advanced.ts +2358 -0
- package/src/knowledge/api.ts +866 -0
- package/src/knowledge/concepts.ts +456 -0
- package/src/knowledge/index.ts +10 -0
- package/src/knowledge/integration.ts +645 -0
- package/src/knowledge/qa.ts +1343 -0
- package/src/server.ts +159 -0
- package/src/tools/advanced.ts +67 -0
- package/src/tools/api.ts +62 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/integration.ts +150 -0
- package/src/tools/qa.ts +38 -0
- package/tsconfig.json +25 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Easy Email Pro MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for helping developers integrate Easy Email Pro and answering questions about Easy Email Pro.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Quick Start Guide**: Get started with Easy Email Pro quickly
|
|
8
|
+
- **Integration Guides**: Framework-specific integration guides (React, Next.js, Vue)
|
|
9
|
+
- **API Reference**: Detailed API documentation
|
|
10
|
+
- **Q&A**: Answer common questions about Easy Email Pro
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
\`\`\`bash
|
|
15
|
+
cd packages/easy-email-pro-mcp
|
|
16
|
+
npm install
|
|
17
|
+
\`\`\`
|
|
18
|
+
|
|
19
|
+
## Development
|
|
20
|
+
|
|
21
|
+
\`\`\`bash
|
|
22
|
+
# Start development server
|
|
23
|
+
npm run dev
|
|
24
|
+
|
|
25
|
+
# The API will be available at http://localhost:3000/api/mcp
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
## Build
|
|
29
|
+
|
|
30
|
+
\`\`\`bash
|
|
31
|
+
# Build for production
|
|
32
|
+
npm run build
|
|
33
|
+
|
|
34
|
+
# Start production server
|
|
35
|
+
npm start
|
|
36
|
+
\`\`\`
|
|
37
|
+
|
|
38
|
+
## Deployment
|
|
39
|
+
|
|
40
|
+
### Deploy to Vercel
|
|
41
|
+
|
|
42
|
+
This is a Next.js application, so it can be easily deployed to Vercel:
|
|
43
|
+
|
|
44
|
+
\`\`\`bash
|
|
45
|
+
# Install Vercel CLI
|
|
46
|
+
npm i -g vercel
|
|
47
|
+
|
|
48
|
+
# Deploy
|
|
49
|
+
cd packages/easy-email-pro-mcp
|
|
50
|
+
vercel
|
|
51
|
+
\`\`\`
|
|
52
|
+
|
|
53
|
+
Or connect your GitHub repository to Vercel for automatic deployments.
|
|
54
|
+
|
|
55
|
+
### MCP Client Configuration
|
|
56
|
+
|
|
57
|
+
After deployment, configure your MCP client (e.g., Cursor) to use the HTTP API:
|
|
58
|
+
|
|
59
|
+
\`\`\`json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"easy-email-pro": {
|
|
63
|
+
"url": "https://your-domain.vercel.app/api/mcp",
|
|
64
|
+
"transport": "streamableHttp",
|
|
65
|
+
"headers": {
|
|
66
|
+
"x-client-id": "YOUR_CLIENT_ID"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
Or use query parameter:
|
|
74
|
+
|
|
75
|
+
\`\`\`json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"easy-email-pro": {
|
|
79
|
+
"url": "https://your-domain.vercel.app/api/mcp?client_id=YOUR_CLIENT_ID",
|
|
80
|
+
"transport": "streamableHttp"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
## Client ID
|
|
87
|
+
|
|
88
|
+
The HTTP API requires a valid `client_id` for authentication. You can:
|
|
89
|
+
|
|
90
|
+
- Use `"FREE"` for free tier access
|
|
91
|
+
- Use your enterprise `client_id` if you have a subscription
|
|
92
|
+
- Contact ch.mao@qq.com for a client_id
|
|
93
|
+
|
|
94
|
+
The `client_id` can be provided via:
|
|
95
|
+
- HTTP header: `x-client-id`
|
|
96
|
+
- Query parameter: `client_id`
|
|
97
|
+
- Authorization header: `Bearer YOUR_CLIENT_ID`
|
|
98
|
+
|
|
99
|
+
## Available Tools
|
|
100
|
+
|
|
101
|
+
### 1. get_quick_start
|
|
102
|
+
|
|
103
|
+
Get a quick start guide for Easy Email Pro.
|
|
104
|
+
|
|
105
|
+
**Usage:**
|
|
106
|
+
\`\`\`
|
|
107
|
+
get_quick_start({})
|
|
108
|
+
\`\`\`
|
|
109
|
+
|
|
110
|
+
### 2. get_integration_guide
|
|
111
|
+
|
|
112
|
+
Get integration guide for a specific framework.
|
|
113
|
+
|
|
114
|
+
**Parameters:**
|
|
115
|
+
- \`framework\` (optional): "react", "nextjs", or "vue" (default: "react")
|
|
116
|
+
|
|
117
|
+
**Usage:**
|
|
118
|
+
\`\`\`
|
|
119
|
+
get_integration_guide({ framework: "nextjs" })
|
|
120
|
+
\`\`\`
|
|
121
|
+
|
|
122
|
+
### 3. get_api_reference
|
|
123
|
+
|
|
124
|
+
Get API reference documentation.
|
|
125
|
+
|
|
126
|
+
**Parameters:**
|
|
127
|
+
- \`topic\` (optional): API topic name (EmailEditorProvider, useEditorProps, useSelectedNode, EditorCore, BlockManager, ElementType)
|
|
128
|
+
|
|
129
|
+
**Usage:**
|
|
130
|
+
\`\`\`
|
|
131
|
+
get_api_reference({ topic: "EmailEditorProvider" })
|
|
132
|
+
\`\`\`
|
|
133
|
+
|
|
134
|
+
### 4. answer_question
|
|
135
|
+
|
|
136
|
+
Answer questions about Easy Email Pro.
|
|
137
|
+
|
|
138
|
+
**Parameters:**
|
|
139
|
+
- \`question\` (required): Your question about Easy Email Pro
|
|
140
|
+
|
|
141
|
+
**Usage:**
|
|
142
|
+
\`\`\`
|
|
143
|
+
answer_question({ question: "How do I upload images?" })
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
## Example Usage
|
|
147
|
+
|
|
148
|
+
### Getting Started
|
|
149
|
+
|
|
150
|
+
\`\`\`
|
|
151
|
+
User: How do I get started with Easy Email Pro?
|
|
152
|
+
AI: I'll help you get started. Let me fetch the quick start guide.
|
|
153
|
+
[Call: get_quick_start({})]
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
### Framework-Specific Help
|
|
157
|
+
|
|
158
|
+
\`\`\`
|
|
159
|
+
User: How do I integrate Easy Email Pro with Next.js?
|
|
160
|
+
AI: Let me get the Next.js integration guide for you.
|
|
161
|
+
[Call: get_integration_guide({ framework: "nextjs" })]
|
|
162
|
+
\`\`\`
|
|
163
|
+
|
|
164
|
+
### API Questions
|
|
165
|
+
|
|
166
|
+
\`\`\`
|
|
167
|
+
User: What props does EmailEditorProvider accept?
|
|
168
|
+
AI: Let me get the API reference for EmailEditorProvider.
|
|
169
|
+
[Call: get_api_reference({ topic: "EmailEditorProvider" })]
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
### General Questions
|
|
173
|
+
|
|
174
|
+
\`\`\`
|
|
175
|
+
User: How do I handle image uploads?
|
|
176
|
+
AI: Let me answer that for you.
|
|
177
|
+
[Call: answer_question({ question: "How do I handle image uploads?" })]
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
180
|
+
## Knowledge Base
|
|
181
|
+
|
|
182
|
+
The MCP server includes a knowledge base covering:
|
|
183
|
+
|
|
184
|
+
- Installation and setup
|
|
185
|
+
- Framework integration (React, Next.js, Vue)
|
|
186
|
+
- API documentation
|
|
187
|
+
- Common questions and answers:
|
|
188
|
+
- Image upload configuration
|
|
189
|
+
- Exporting templates (MJML/HTML)
|
|
190
|
+
- Theme customization
|
|
191
|
+
- Troubleshooting
|
|
192
|
+
- Saving and loading templates
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
Same as Easy Email Pro
|
package/next.config.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @type {import('next').NextConfig} */
|
|
2
|
+
const nextConfig = {
|
|
3
|
+
output: 'standalone',
|
|
4
|
+
typescript: {
|
|
5
|
+
ignoreBuildErrors: false,
|
|
6
|
+
},
|
|
7
|
+
// Transpile ESM packages
|
|
8
|
+
transpilePackages: ['@modelcontextprotocol/sdk'],
|
|
9
|
+
// Enable experimental features if needed for ES modules
|
|
10
|
+
experimental: {
|
|
11
|
+
serverActions: {
|
|
12
|
+
bodySizeLimit: '2mb',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
webpack: (config, { isServer }) => {
|
|
16
|
+
// Handle ESM packages in Next.js
|
|
17
|
+
if (isServer) {
|
|
18
|
+
// Allow resolving .js extensions for ESM imports
|
|
19
|
+
config.resolve.extensionAlias = {
|
|
20
|
+
'.js': ['.js', '.ts', '.tsx'],
|
|
21
|
+
'.jsx': ['.jsx', '.tsx'],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Ensure proper module resolution for ESM packages
|
|
25
|
+
config.resolve.mainFields = ['main', 'module'];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return config;
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = nextConfig;
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "easy-email-pro-mcp",
|
|
3
|
+
"version": "1.55.1",
|
|
4
|
+
"description": "MCP server for Easy Email Pro integration guidance and Q&A",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"author": "",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
9
|
+
"crypto-js": "^4.1.1",
|
|
10
|
+
"easy-email-pro-core": "^1.56.1",
|
|
11
|
+
"next": "^14.0.0",
|
|
12
|
+
"react": "^18.2.0",
|
|
13
|
+
"react-dom": "^18.2.0",
|
|
14
|
+
"typescript": "^5.9.3"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/crypto-js": "^4.1.1",
|
|
18
|
+
"@types/node": "^20.0.0",
|
|
19
|
+
"@types/react": "^18.2.0",
|
|
20
|
+
"@types/react-dom": "^18.2.0",
|
|
21
|
+
"eslint": "^8.0.0",
|
|
22
|
+
"eslint-config-next": "^14.0.0"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "next dev",
|
|
26
|
+
"build": "next build",
|
|
27
|
+
"start": "next start",
|
|
28
|
+
"lint": "eslint --fix --ext .tsx,.ts pages src"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/pages/api/mcp.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js API Route for MCP HTTP API
|
|
3
|
+
* Handles MCP requests via HTTP transport
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
7
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
8
|
+
import { createMcpServer } from "../../src/server";
|
|
9
|
+
import { extractClientId, validateClientId } from "../../src/auth";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Convert Next.js request to standard Request object
|
|
13
|
+
*/
|
|
14
|
+
function createRequestFromNext(req: NextApiRequest): Request {
|
|
15
|
+
// Build URL from Next.js request
|
|
16
|
+
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
|
17
|
+
const host = req.headers.host || 'localhost';
|
|
18
|
+
const path = req.url || '/api/mcp';
|
|
19
|
+
|
|
20
|
+
// Add query parameters
|
|
21
|
+
const queryString = new URLSearchParams();
|
|
22
|
+
Object.entries(req.query).forEach(([key, value]) => {
|
|
23
|
+
if (value) {
|
|
24
|
+
queryString.append(key, Array.isArray(value) ? value[0] : String(value));
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const url = `${protocol}://${host}${path}${queryString.toString() ? '?' + queryString.toString() : ''}`;
|
|
29
|
+
|
|
30
|
+
// Convert headers
|
|
31
|
+
const headers = new Headers();
|
|
32
|
+
Object.entries(req.headers).forEach(([key, value]) => {
|
|
33
|
+
if (value && key !== 'host') { // Skip host as it's in URL
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
value.forEach(v => headers.append(key, v));
|
|
36
|
+
} else {
|
|
37
|
+
headers.set(key, value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Get body
|
|
43
|
+
let body: string | undefined;
|
|
44
|
+
if (req.body) {
|
|
45
|
+
body = typeof req.body === 'string' ? req.body : JSON.stringify(req.body);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return new Request(url, {
|
|
49
|
+
method: req.method || 'GET',
|
|
50
|
+
headers,
|
|
51
|
+
body,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Convert Response to Next.js response
|
|
57
|
+
*/
|
|
58
|
+
async function sendResponseToNext(res: NextApiResponse, response: Response): Promise<void> {
|
|
59
|
+
// Set status
|
|
60
|
+
res.status(response.status);
|
|
61
|
+
|
|
62
|
+
// Set headers
|
|
63
|
+
response.headers.forEach((value, key) => {
|
|
64
|
+
res.setHeader(key, value);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Send body
|
|
68
|
+
const text = await response.text();
|
|
69
|
+
res.send(text);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Next.js API Route handler
|
|
74
|
+
*/
|
|
75
|
+
export default async function handler(
|
|
76
|
+
req: NextApiRequest,
|
|
77
|
+
res: NextApiResponse
|
|
78
|
+
) {
|
|
79
|
+
// Only allow POST requests
|
|
80
|
+
if (req.method !== 'POST') {
|
|
81
|
+
return res.status(405).json({
|
|
82
|
+
jsonrpc: "2.0",
|
|
83
|
+
error: {
|
|
84
|
+
code: -32000,
|
|
85
|
+
message: "Method not allowed. Use POST for MCP requests.",
|
|
86
|
+
},
|
|
87
|
+
id: null,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// Convert Next.js request to standard Request
|
|
93
|
+
const request = createRequestFromNext(req);
|
|
94
|
+
|
|
95
|
+
// Extract and validate client_id
|
|
96
|
+
const clientId = extractClientId(request);
|
|
97
|
+
|
|
98
|
+
if (!(await validateClientId(clientId))) {
|
|
99
|
+
return res.status(401).json({
|
|
100
|
+
jsonrpc: "2.0",
|
|
101
|
+
error: {
|
|
102
|
+
code: -32001,
|
|
103
|
+
message: "Invalid or missing client_id. Please provide a valid client_id in headers (x-client-id) or query params (client_id).",
|
|
104
|
+
},
|
|
105
|
+
id: null,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Create MCP server instance
|
|
110
|
+
const server = createMcpServer();
|
|
111
|
+
|
|
112
|
+
// Create transport in stateless mode (suitable for serverless)
|
|
113
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
114
|
+
sessionIdGenerator: undefined, // Stateless mode
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Connect server to transport
|
|
118
|
+
await server.connect(transport);
|
|
119
|
+
|
|
120
|
+
// Handle the request
|
|
121
|
+
const response = await transport.handleRequest(request);
|
|
122
|
+
|
|
123
|
+
// Send response back to Next.js
|
|
124
|
+
await sendResponseToNext(res, response);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("MCP request error:", error);
|
|
127
|
+
|
|
128
|
+
return res.status(500).json({
|
|
129
|
+
jsonrpc: "2.0",
|
|
130
|
+
error: {
|
|
131
|
+
code: -32603,
|
|
132
|
+
message: error instanceof Error ? error.message : "Internal server error",
|
|
133
|
+
},
|
|
134
|
+
id: null,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
package/src/auth.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client ID validation for MCP HTTP API
|
|
3
|
+
* Uses EditorAuth from easy-email-pro-core for validation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { EditorAuth } from "easy-email-pro-core";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validate client ID using EditorAuth
|
|
10
|
+
* Returns true if client_id is valid (enterprise or FREE)
|
|
11
|
+
*/
|
|
12
|
+
export async function validateClientId(
|
|
13
|
+
clientId: string | null | undefined
|
|
14
|
+
): Promise<boolean> {
|
|
15
|
+
if (!clientId) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Allow FREE tier
|
|
20
|
+
if (clientId === "FREE") {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// Use EditorAuth to validate the client_id
|
|
26
|
+
await EditorAuth.auth(clientId);
|
|
27
|
+
const hasEnabled = EditorAuth.getFeatureEnabled('AI_ASSISTANT');
|
|
28
|
+
return hasEnabled;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("Client ID validation error:", error);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Extract client ID from request
|
|
37
|
+
* Checks headers, query params, and body
|
|
38
|
+
*/
|
|
39
|
+
export function extractClientId(request: Request): string | null {
|
|
40
|
+
// Check header
|
|
41
|
+
const headerClientId = request.headers.get("x-client-id");
|
|
42
|
+
if (headerClientId) {
|
|
43
|
+
return headerClientId;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check Authorization header (Bearer token format)
|
|
47
|
+
const authHeader = request.headers.get("authorization");
|
|
48
|
+
if (authHeader?.startsWith("Bearer ")) {
|
|
49
|
+
return authHeader.substring(7);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// For GET requests, check URL search params
|
|
53
|
+
const url = new URL(request.url);
|
|
54
|
+
const queryClientId = url.searchParams.get("client_id");
|
|
55
|
+
if (queryClientId) {
|
|
56
|
+
return queryClientId;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return null;
|
|
60
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Easy Email Pro MCP Server
|
|
3
|
+
*
|
|
4
|
+
* MCP server for helping developers integrate Easy Email Pro
|
|
5
|
+
* and answering questions about Easy Email Pro
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from "./server";
|
|
9
|
+
export * from "./tools";
|
|
10
|
+
// Note: knowledge exports are for internal use, not re-exported to avoid conflicts
|