在 Laravel 中通过 MCP 协议发送邮件需要完成以下关键步骤,这里提供完整实现指南:

一、服务端配置

  1. 创建邮件工具类
// app/Tools/EmailTool.php
namespace App\Tools;

use PhpMcp\Laravel\Server\Attributes\McpTool;
use Illuminate\Support\Facades\Mail;
use App\Mail\TransactionalEmail;
use Illuminate\Support\Facades\Validator;

class EmailTool {
    #[McpTool(
        name: "send_email",
        description: "发送事务邮件",
        params: [
            'recipient' => 'required|email',
            'subject' => 'required|string|max:120',
            'template' => 'required|string|in:invoice,welcome,reset',
            'variables' => 'array'
        ]
    )]
    public function send(array $params): array {
        // 二次校验确保安全
        $validator = Validator::make($params, [
            'recipient' => 'required|email',
            'template' => 'required|exists:mail_templates,name'
        ]);
        
        if ($validator->fails()) {
            abort(422, $validator->errors()->first());
        }

        // 实际发送邮件
        Mail::to($params['recipient'])
            ->queue(new TransactionalEmail(
                $params['subject'],
                $params['template'],
                $params['variables'] ?? []
            ));
        
        return [
            'status' => 'queued',
            'message' => '邮件已进入发送队列',
            'timestamp' => now()->toDateTimeString()
        ];
    }
}
  1. 创建邮件模板类
// app/Mail/TransactionalEmail.php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class TransactionalEmail extends Mailable {
    use Queueable, SerializesModels;

    public function __construct(
        public string $subject,
        public string $template,
        public array $variables = []
    ) {}

    public function build() {
        return $this->subject($this->subject)
            ->view('emails.' . $this->template)
            ->with($this->variables);
    }
}

二、客户端调用示例(JavaScript)

// 连接到 MCP 服务
const mcp = new McpClient('https://api.yourdomain.com/mcp/sse', {
  token: AUTH_TOKEN // 服务端签发的 JWT
});

// 调用邮件发送工具
async function sendInvoiceEmail() {
  const response = await mcp.execute('send_email', {
    recipient: 'client@example.com',
    subject: '您的订单发票 #INV-2023-0456',
    template: 'invoice',
    variables: {
      invoice_number: 'INV-2023-0456',
      amount: 2499.00,
      due_date: '2023-12-31'
    }
  });
  
  console.log('邮件发送状态:', response);
  // 输出: {status: "queued", message: "邮件已进入发送队列", ...}
}

// 处理错误
mcp.on('error', (err) => {
  console.error('邮件发送失败:', err);
});

三、关键配置项

  1. MCP 路由配置 (config/mcp.php)
'transports' => [
    'sse' => [
        'route' => '/mcp/sse',
        'middleware' => ['auth:api', 'throttle:100/minute']
    ]
],
'security' => [
    'jwt_secret' => env('MCP_JWT_SECRET', env('APP_KEY')),
    'allowed_origins' => ['https://your-frontend.com']
]
  1. 邮件队列配置 (.env)
MAIL_MAILER=smtp
MAIL_HOST=mail.example.com
MAIL_PORT=587
MAIL_USERNAME=no-reply@example.com
MAIL_PASSWORD=yourpassword
MAIL_ENCRYPTION=tls

QUEUE_CONNECTION=redis # 使用队列发送

四、高级功能实现

  1. 邮件发送限流
// 在路由中添加限流中间件
Mcp::route()->middleware(['throttle:emails:60,1']);

// 在 AppServiceProvider 中定义限流器
RateLimiter::for('emails', function (Request $request) {
    return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
  1. 邮件追踪
// 修改邮件工具类
#[McpTool(/* ... */)]
public function send(array $params): array {
    $mail = new TransactionalEmail(/* ... */);
    
    // 添加邮件追踪ID
    $trackingId = Str::uuid();
    $mail->withSwiftMessage(function ($message) use ($trackingId) {
        $message->getHeaders()->addTextHeader('X-Mail-Tracking-ID', $trackingId);
    });

    Mail::queue($mail);
    
    return [
        'tracking_id' => $trackingId,
        // ...
    ];
}
  1. 模板预检接口
#[McpTool(
    name: "preview_template",
    description: "预览邮件模板"
)]
public function preview(string $template, array $variables = []) {
    return view('emails.' . $template, $variables)->render();
}

五、调试技巧

  1. 测试发送本地邮件
php artisan tinker
>>> Mcp::call('send_email', [
     'recipient' => 'test@localhost',
     'subject' => '测试邮件',
     'template' => 'test'
   ]);
  1. 查看邮件日志
tail -f storage/logs/mcp-*.log
# 启用调试模式
MCP_LOG_LEVEL=debug

六、安全建议

  1. 敏感操作审计
// 在工具类中添加审计日志
public function send(array $params) {
    activity('mcp_email')
        ->withProperties([
            'recipient' => $params['recipient'],
            'template' => $params['template']
        ])
        ->log('邮件发送请求');
    
    // ...发送逻辑...
}
  1. IP 白名单限制
// config/mcp.php
'security' => [
    'allowed_ips' => [
        '192.168.1.0/24',
        '172.16.0.0/12'
    ]
]

通过以上实现,您将获得一个安全可靠、支持队列发送、带有完整审计日志的 MCP 邮件服务。实际生产部署时建议:

  1. 使用 Redis 或 Horizon 管理邮件队列
  2. 配置邮件送达状态监控(如 Mailgun 或 Sendgrid 的回调)
  3. 定期审计邮件发送日志
  4. 为高风险操作添加二次确认机制
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐