setup-cline.js•8.85 kB
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fileURLToPath } from 'url';
import inquirer from 'inquirer';
import nodemailer from 'nodemailer';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 检测Cline配置文件路径
function getClienceConfigPath() {
const platform = os.platform();
const homeDir = os.homedir();
let configPath;
if (platform === 'win32') {
configPath = path.join(homeDir, 'AppData', 'Roaming', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json');
} else if (platform === 'darwin') {
configPath = path.join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json');
} else {
configPath = path.join(homeDir, '.config', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json');
}
return configPath;
}
// 备份配置文件
function backupConfig(configPath) {
const backupPath = configPath + '.backup.' + Date.now();
if (fs.existsSync(configPath)) {
fs.copyFileSync(configPath, backupPath);
console.log(`✅ 配置文件已备份至: ${backupPath}`);
return backupPath;
}
return null;
}
// 读取现有配置
function readExistingConfig(configPath) {
if (fs.existsSync(configPath)) {
try {
const content = fs.readFileSync(configPath, 'utf8');
return JSON.parse(content);
} catch (error) {
console.warn(`⚠️ 读取配置文件失败: ${error.message}`);
return { mcpServers: {} };
}
}
return { mcpServers: {} };
}
// 创建MCP配置
function createMcpConfig(smtpUser, smtpPass, emailTo) {
const currentDir = path.resolve(__dirname);
const emailMcpPath = path.join(currentDir, 'email-mcp.js');
return {
"email-notify": {
"type": "stdio",
"command": "node",
"args": [emailMcpPath],
"env": {
"SMTP_HOST": "smtp-relay.brevo.com",
"SMTP_PORT": "587",
"SMTP_SECURE": "false",
"SMTP_USER": smtpUser,
"SMTP_PASS": smtpPass,
"EMAIL_FROM": `cline bot<${smtpUser}>`,
"EMAIL_TO": emailTo
},
"disabled": false,
"timeout": 60,
"alwaysAllow": ["send_email"],
"autoApprove": ["send_email"]
}
};
}
// 测试SMTP连接
async function testSmtpConnection(smtpUser, smtpPass) {
console.log('🔍 测试SMTP连接...');
const transporter = nodemailer.createTransporter({
host: 'smtp-relay.brevo.com',
port: 587,
secure: false,
auth: {
user: smtpUser,
pass: smtpPass,
},
});
try {
await transporter.verify();
console.log('✅ SMTP连接测试成功');
return true;
} catch (error) {
console.error('❌ SMTP连接测试失败:', error.message);
return false;
}
}
// 发送测试邮件
async function sendTestEmail(smtpUser, smtpPass, emailTo) {
console.log('📧 发送测试邮件...');
const transporter = nodemailer.createTransporter({
host: 'smtp-relay.brevo.com',
port: 587,
secure: false,
auth: {
user: smtpUser,
pass: smtpPass,
},
});
try {
const info = await transporter.sendMail({
from: `cline bot<${smtpUser}>`,
to: emailTo,
subject: '[Cline] Email MCP配置成功通知',
text: `
恭喜!您的Cline Email MCP服务器已成功配置。
配置详情:
- SMTP服务器: smtp-relay.brevo.com:587
- 发送邮箱: ${smtpUser}
- 接收邮箱: ${emailTo}
- 配置时间: ${new Date().toLocaleString()}
现在Cline可以在以下情况发送邮件通知:
- 长时间任务完成
- 遇到需要人工干预的错误
- 等待用户输入或确认
- 测试通过和目标达成
祝您使用愉快!
`.trim(),
html: `
<h2>🎉 Cline Email MCP配置成功!</h2>
<p>恭喜!您的Cline Email MCP服务器已成功配置。</p>
<h3>📋 配置详情</h3>
<ul>
<li><strong>SMTP服务器:</strong> smtp-relay.brevo.com:587</li>
<li><strong>发送邮箱:</strong> ${smtpUser}</li>
<li><strong>接收邮箱:</strong> ${emailTo}</li>
<li><strong>配置时间:</strong> ${new Date().toLocaleString()}</li>
</ul>
<h3>📨 通知场景</h3>
<p>现在Cline可以在以下情况发送邮件通知:</p>
<ul>
<li>长时间任务完成</li>
<li>遇到需要人工干预的错误</li>
<li>等待用户输入或确认</li>
<li>测试通过和目标达成</li>
</ul>
<p><strong>祝您使用愉快!</strong></p>
`
});
console.log('✅ 测试邮件发送成功!');
console.log(`📬 MessageId: ${info.messageId}`);
return true;
} catch (error) {
console.error('❌ 测试邮件发送失败:', error.message);
return false;
}
}
// 主函数
async function main() {
console.log('🚀 Cline Email MCP 自动配置工具');
console.log('=====================================\n');
// 检查Cline配置文件路径
const configPath = getClienceConfigPath();
console.log(`📁 Cline配置文件路径: ${configPath}`);
if (!fs.existsSync(path.dirname(configPath))) {
console.error('❌ 未找到Cline配置目录,请确保Cline已安装并运行过');
process.exit(1);
}
// 收集用户输入
console.log('\n📝 请输入SMTP配置信息:');
const answers = await inquirer.prompt([
{
type: 'input',
name: 'smtpUser',
message: 'SMTP用户名 (邮箱地址):',
validate: (input) => {
if (!input || !input.includes('@')) {
return '请输入有效的邮箱地址';
}
return true;
}
},
{
type: 'password',
name: 'smtpPass',
message: 'SMTP密码 (建议使用应用专用密码):',
validate: (input) => {
if (!input || input.length < 4) {
return '密码不能为空且长度不少于4位';
}
return true;
}
},
{
type: 'input',
name: 'emailTo',
message: '接收通知的邮箱地址:',
default: (answers) => answers.smtpUser,
validate: (input) => {
if (!input || !input.includes('@')) {
return '请输入有效的邮箱地址';
}
return true;
}
}
]);
// 测试SMTP连接
const smtpTest = await testSmtpConnection(answers.smtpUser, answers.smtpPass);
if (!smtpTest) {
console.error('❌ SMTP配置测试失败,请检查用户名和密码');
process.exit(1);
}
// 备份现有配置
const backupPath = backupConfig(configPath);
try {
// 读取现有配置
const existingConfig = readExistingConfig(configPath);
// 创建新的MCP配置
const newMcpConfig = createMcpConfig(answers.smtpUser, answers.smtpPass, answers.emailTo);
// 合并配置
existingConfig.mcpServers = {
...existingConfig.mcpServers,
...newMcpConfig
};
// 确保目录存在
fs.mkdirSync(path.dirname(configPath), { recursive: true });
// 写入配置文件
fs.writeFileSync(configPath, JSON.stringify(existingConfig, null, 2));
console.log('✅ Cline MCP配置已更新');
// 发送测试邮件
const emailTest = await sendTestEmail(answers.smtpUser, answers.smtpPass, answers.emailTo);
if (emailTest) {
console.log('\n🎉 配置完成!');
console.log('📧 测试邮件已发送,请检查您的邮箱');
console.log('🔄 请重启Cline以使配置生效');
} else {
console.log('\n⚠️ 配置已保存,但测试邮件发送失败');
console.log('🔄 请重启Cline并稍后测试邮件功能');
}
} catch (error) {
console.error('❌ 配置过程中发生错误:', error.message);
// 尝试恢复备份
if (backupPath && fs.existsSync(backupPath)) {
fs.copyFileSync(backupPath, configPath);
console.log('🔄 配置已恢复到备份状态');
}
process.exit(1);
}
}
// 运行主函数
main().catch(console.error);