当前位置: 首页 > news >正文

5分钟快速手搓mcp发送邮件的server接入到cherrystudio

效果演示

向大模型索要数据,并自动发送到指定邮箱
在这里插入图片描述
最后收到邮件的结果截图
在这里插入图片描述

先推荐2个mcp网站

mcp中文文档:https://mcpcn.com/docs/introduction/
mcp server收录站:https://mcp.so/

手搓的配套视频我放到文章底部

前置准备

我这边以node来做演示,node js环境点此下载,这个一定要有,没有现场装,啪的一下很快

// 检查node环境
node -v
// 检查npm环境
npm -v
// 检查npx环境
npx -v
// 配置淘宝源
npm config set registry https://registry.npmmirror.com

初始化mcp项目

# 创建一个文件夹(可手动创建)
mkdir first-mcp-server
cd first-mcp-server

# 初始化 npm 项目
npm init -y

# 安装mcp sdk依赖
npm install @modelcontextprotocol/sdk @anthropic-ai/sdk dotenv
npm install -D typescript @types/node

# 创建 TypeScript 配置
npx tsc --init

# 创建必要的文件
mkdir src
touch src/index.ts

加入如下代码

#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
    ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server({
  name: "first-mcp-server",
  version: "0.0.1",
}, {
  capabilities: {
    tools: {}
  }
});

// List available tools 一定要有,否则无法接入mcp-client
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
      tools: [
          {
              name: "测试方法",
              description: "这是一个测试方法描述",
              inputSchema: {
                  type: "object",
                  properties: {
                      property1: {
                          type: "string",
                          description: "属性1",
                      },
                      property2: {
                          type: "string",
                          description: "属性2",
                      },
                      property3: {
                          type: "number",
                          description: "属性3,非必填",
                      },
                  },
                  required: ["property1", "property2"],
              },
          },
      ],
  };
});

// 启动服务
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("First MCP Server running on stdio");
}

// 异常捕获
main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});

tsconfig.json改为如下

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"]
}

package.json加入如下代码

{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node build/client.js"
  }
}

编译构建

打开命令行执行 npm run build,构建后会生成build/index.js文件
在这里插入图片描述

cherry-studio接入

在这里插入图片描述
注意:cherry-studio需要安装bun和uv,否则可能会报错
在这里插入图片描述
点击保存后会与你的mcp-代码建立连接,连接完成如下:
在这里插入图片描述
如果你做到了和我上面一样,那么接下来我们来实现发邮件的功能,代码如下:

#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
    ListToolsRequestSchema,
    CallToolRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import * as nodemailer from 'nodemailer';

const server = new Server({
  name: "email-mcp-server",
  version: "0.0.1",
}, {
  capabilities: {
    tools: {}
  }
});

// 环境变量配置
const EMAIL_HOST = process.env.EMAIL_HOST || 'smtp.qq.com';
const EMAIL_PORT = parseInt(process.env.EMAIL_PORT || '465');
const EMAIL_USER = process.env.EMAIL_USER;
const EMAIL_PASS = process.env.EMAIL_PASS;

if (!EMAIL_USER || !EMAIL_PASS) {
  console.error("EMAIL_USER or EMAIL_PASS environment variable is not set");
  process.exit(1);
}

// 创建邮件传输器
const transporter = nodemailer.createTransport({
  host: EMAIL_HOST,
  port: EMAIL_PORT,
  secure: true,
  auth: {
    user: EMAIL_USER,
    pass: EMAIL_PASS,
  },
});

// List available tools 一定要有,否则无法接入mcp-client
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
      tools: [
          {
              name: "send-email",
              description: "发送邮件,支持HTML内容、表格和附件",
              inputSchema: {
                  type: "object",
                  properties: {
                      to: {
                          type: "string",
                          description: "收件人邮箱,多个收件人用逗号分隔",
                      },
                      cc: {
                          type: "string",
                          description: "抄送邮箱,多个抄送用逗号分隔",
                      },
                      subject: {
                          type: "string",
                          description: "邮件主题",
                      },
                      html: {
                          type: "string",
                          description: "邮件HTML内容,支持表格等HTML标签",
                      },
                      attachments: {
                          type: "array",
                          description: "附件列表",
                          items: {
                              type: "object",
                              properties: {
                                  filename: { type: "string" },
                                  path: { type: "string" }
                              }
                          }
                      }
                  },
                  required: ["to", "subject", "html"],
              },
          },
      ],
  };
});

// 处理发送邮件请求
server.setRequestHandler(CallToolRequestSchema, async (request) => {
    try {
        if (!request.params.name || !request.params.arguments) {
            return {
                success: false,
                error: "Tool name and arguments are required"
            };
        }
        if (request.params.name === "send-email") {
            const args = request.params.arguments as {
                to: string;
                cc?: string;
                subject: string;
                html: string;
                attachments?: Array<{ filename: string; path: string }>;
            };

            if (!args.to || !args.subject || !args.html) {
                return {
                    success: false,
                    error: "Required fields missing: to, subject, and html are required"
                };
            }

            const mailOptions = {
                from: EMAIL_USER,
                to: args.to,
                cc: args.cc,
                subject: args.subject,
                html: args.html,
                attachments: args.attachments
            };

            const info = await transporter.sendMail(mailOptions);
            return {
                success: true,
                data: {
                }
            };
        }
        return {
            success: false,
            error: `Unknown tool: ${request.params.name}`
        };
    } catch (error) {
        return {
            success: false,
            error: error instanceof Error ? error.message : "Unknown error occurred"
        };
    }
});

// 启动服务
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("First MCP Server running on stdio");
}

// 异常捕获
main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});

这里增加了一个发送邮件的nodemailer依赖,所以需要npm安装一下
npm install --save @types/nodemailer

然后再次执行构建 npm run build,构建后去cherry-studio简单修改下属性点击保存
在这里插入图片描述
这里有几个参数我给个示例

EMAIL_HOST=smtp.qq.com
EMAIL_PORT=465
EMAIL_USER=88888888@qq.com
EMAIL_PASS=lrjlmbyslnxxxx

注意EMAIL_PASS需要手动去开启邮箱的smtp服务,开启后会有一个码,开启位置如下:
在这里插入图片描述

在这里插入图片描述
最后收到邮件的结果
在这里插入图片描述

最后附一下视频:

相关文章:

  • MapReduce工作原理详解
  • Mapbox-GL 事件体系和使用方法的详细讲解
  • [动规19] 最大子数组和
  • Mentalab Explore Pro携手 Wearanize + 数据集,推动睡眠科学研究
  • 每日一题-力扣-2278. 字母在字符串中的百分比 0331
  • Java EE(19)——网络原理——应用层HTTPS协议
  • 视觉语言,轻量且开源-Gemma 3
  • nut-ui下拉选的实现方式:nut-menu
  • 快速入手-基于Django-rest-framework的第三方认证插件(SimpleJWT)权限认证扩展返回用户等其他信息(十一)
  • 闭包与作用域的理解
  • Linux操作系统下离线安装nginx
  • 嵌入式学习第三十天--队列
  • 【区块链安全 | 第二十篇】类型之运算符
  • Docker 拉取镜像部分成功部分失败?
  • TDengine 核心概念与时序数据模型深度解析(二)
  • 从TRPO到GRPO
  • scikit-surprise 智能推荐模块使用说明
  • 简单视图函数
  • (BFS)题解:P9425 [蓝桥杯 2023 国 B] AB 路线
  • 智能打印预约系统:微信小程序+SSM框架实战项目
  • 冠县网站建设/seo官网优化
  • 网站排名突然下降/2021年最为成功的营销案例
  • 如何建设一个普通网页网站/网络营销和推广做什么
  • dede被挂赌博网站木马/铜仁搜狗推广
  • 建个企业网站需要多少钱/软件推广赚钱一个10元
  • 如何做印刷报价网站/网站seo平台