掘金 人工智能 05月15日 10:38
创建你的第一个MCP服务
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文提供了一份详细的教程,指导用户如何基于Model Context Protocol (MCP) 协议,创建一个中国天气查询服务。教程涵盖了环境准备、依赖安装、MCP 服务实现、配置创建、服务测试以及与 Cursor 集成的完整流程。通过构建该服务,读者能够深入了解 MCP 的工作原理,并为开发更多 AI 工具打下基础。

💡 **理解MCP协议:** MCP 是一种开放标准协议,允许大型语言模型(LLM)与外部系统交互。它允许LLM访问实时数据、执行计算和调用API,从而增强AI的功能性。

🛠️ **环境准备与依赖安装:** 教程首先介绍了创建中国天气查询 MCP 服务所需的环境准备,包括安装 Node.js 和 npm。然后,详细说明了如何通过 npm init 和 npm install 命令来初始化项目并安装必要的依赖,例如 @modelcontextprotocol/sdk、moment 和 zod。

⚙️ **MCP 服务实现:** 教程的核心部分是创建 weather.js 文件,该文件定义了 MCP 服务的主程序。其中包括导入所需的模块、定义城市和省份的映射、生成模拟天气数据、格式化天气数据以及注册天气查询和城市信息查询工具。此外,还提供了获取当前季节和生成随机整数的辅助函数。

🧪 **服务测试与集成:** 教程指导用户如何创建配置文件,以便在 Cursor 或 Claude Desktop 中使用 MCP 服务。通过运行 npm start 命令启动服务,并使用 npm run test:weather 进行测试。最后,详细说明了如何将创建好的 MCP 服务与 Cursor 集成,以便在 Cursor 中直接调用天气查询工具。

创建你的第一个MCP服务

Model Context Protocol (MCP) 中国天气查询服务创建教程

什么是 Model Context Protocol (MCP)

Model Context Protocol (MCP) 是一种开放标准协议,允许大型语言模型(LLM)如 Claude 与外部系统和数据源进行交互。通过 MCP,Claude 可以:

MCP 赋予 AI 以"工具使用"能力,使其突破固有知识库的限制,能够获取最新信息并执行具体任务,大大提升了 AI 的实用性。

MCP 的工作原理

MCP 的核心是一套简单但强大的通信协议:

    工具注册:开发者定义工具,描述其功能和参数工具调用:Claude 确定需要使用工具并发出请求工具执行:MCP 服务器接收请求,执行操作,返回结果结果解析:Claude 解析结果并将其整合到回答中

整个过程对用户来说是无缝的,用户只需提出问题,MCP 在后台自动处理工具调用。

创建中国天气查询 MCP 服务教程

Git 地址 : github.com/lovelyqun/M…

下面我们将一步一步创建一个中国天气查询 MCP 服务。

第一步:环境准备

首先,确保你的系统安装了 Node.js 和 npm。然后创建项目:

mkdir weather-mcpcd weather-mcpnpm init -y

第二步:安装依赖

编辑 package.json 文件,添加必要的依赖:

{  "name": "weather-mcp-node",  "version": "1.0.0",  "description": "基于Node.js的中国天气查询MCP服务",  "main": "weather.js",  "type": "module",  "scripts": {    "start": "node weather.js",    "test:weather": "echo '{\"name\":\"get_china_weather\",\"parameters\":{\"city\":\"北京\"}}' | node weather.js"  },  "keywords": ["mcp", "weather", "claude", "china"],  "author": "",  "license": "MIT",  "dependencies": {    "@modelcontextprotocol/sdk": "^1.11.2",    "moment": "^2.30.1",    "zod": "^3.22.4"  }}

然后安装依赖:

npm install

第三步:实现 MCP 服务

创建 weather.js 文件,作为我们的主程序:

// 导入所需模块import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';import moment from 'moment';import { z } from 'zod';// 提供的城市和省份映射(简化版,实际可以包含更多城市)const CITY_PROVINCE = {  "北京": "北京市",  "上海": "上海市",  "广州": "广东省",  "深圳": "广东省",  "杭州": "浙江省",  "南京": "江苏省"};// 城市地理信息(经纬度)const CITY_LOCATIONS = {  "北京": {"lat": 39.9042, "lon": 116.4074},  "上海": {"lat": 31.2304, "lon": 121.4737},  "广州": {"lat": 23.1291, "lon": 113.2644},  "深圳": {"lat": 22.5431, "lon": 114.0579},  "杭州": {"lat": 30.2741, "lon": 120.1551},  "南京": {"lat": 32.0584, "lon": 118.7965}};// 初始化MCP服务器const server = new McpServer({  name: "china_weather",  version: "1.0.0",  capabilities: {    tools: {}  }});// 辅助函数:获取当前季节function getSeason() {  const month = moment().month() + 1;  if ([3, 4, 5].includes(month)) return "春季";  else if ([6, 7, 8].includes(month)) return "夏季";  else if ([9, 10, 11].includes(month)) return "秋季";  else return "冬季";}// 辅助函数:生成随机整数function getRandomInt(min, max) {  return Math.floor(Math.random() * (max - min + 1)) + min;}// 为城市生成模拟天气数据function generateWeatherData(city) {  if (!CITY_PROVINCE[city]) return null;    const season = getSeason();  const today = moment();  const forecastData = [];    // 根据季节设定温度范围  let tempRange;  switch (season) {    case "春季": tempRange = [15, 25]; break;    case "夏季": tempRange = [25, 35]; break;    case "秋季": tempRange = [15, 25]; break;    case "冬季": tempRange = [0, 15]; break;  }    // 设定可能的天气类型  const weatherTypes = ["晴", "多云", "小雨", "阴"];    // 生成5天的天气数据  for (let i = 0; i < 5; i++) {    const date = moment(today).add(i, 'days');    const dateStr = date.format('YYYY-MM-DD');    const weekDay = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"][date.day()];        const weatherType = weatherTypes[Math.floor(Math.random() * weatherTypes.length)];    const tempHigh = getRandomInt(tempRange[0], tempRange[1]);    const tempLow = getRandomInt(tempRange[0], tempHigh - 2);        forecastData.push({      date: dateStr,      week: weekDay,      weather: weatherType,      temp_day: tempHigh,      temp_night: tempLow,      wind_direction: "东南风",      wind_power: `${getRandomInt(1, 5)}级`    });  }    return {    city: city,    province: CITY_PROVINCE[city],    data: forecastData  };}// 将天气数据格式化为可读字符串function formatChinaWeather(data) {  if (!data) return "无法获取天气数据。";    const city = data.city || "未知城市";  const province = data.province || "";  const forecasts = [];    for (const day of data.data) {    const dayInfo = `日期: ${day.date} ${day.week}天气: ${day.weather}温度: ${day.temp_day}°C ~ ${day.temp_night}°C风力: ${day.wind_direction} ${day.wind_power}`;    forecasts.push(dayInfo);  }    const header = province ? `📍 ${province} ${city}` : `📍 ${city}`;  return `${header}\n\n` + forecasts.join("\n---\n");}// 注册天气查询工具server.tool(  "get_china_weather",  "查询中国城市的天气预报。",  {    city: z.string().describe('中国城市名称(例如"北京"、"上海"、"广州")')  },  async ({ city }) => {    const weatherData = generateWeatherData(city);        if (!weatherData) {      return {        content: [{          type: "text",          text: `无法获取${city}的天气信息。请提供准确的中国城市名称(如北京、上海、广州等)。`        }]      };    }        const result = formatChinaWeather(weatherData);    return {      content: [{        type: "text",        text: result      }]    };  });// 注册城市信息查询工具server.tool(  "get_china_city_info",  "获取中国城市的基本信息和地理位置。",  {    city: z.string().describe('中国城市名称(例如"北京"、"上海"、"广州")')  },  async ({ city }) => {    if (!CITY_PROVINCE[city]) {      return {        content: [{          type: "text",          text: `未找到城市:${city}。请提供准确的中国城市名称(如北京、上海、广州等)。`        }]      };    }        const province = CITY_PROVINCE[city];    const location = CITY_LOCATIONS[city];        const result = `📍 ${city}所在地区: ${province}经度: ${location.lon}纬度: ${location.lat}`;    return {      content: [{        type: "text",        text: result      }]    };  });// 运行服务器async function main() {  const transport = new StdioServerTransport();  await server.connect(transport);  console.error("中国天气MCP服务器已启动,使用stdio传输...");}main().catch(error => {  console.error("服务器运行错误:", error);  process.exit(1);});

第四步:创建配置文件

为了在 Cursor 或 Claude Desktop 中使用,创建一个 config-example.json 文件:

{  "mcpServers": {    "china_weather": {      "command": "npm",      "args": [        "start",        "--prefix",        "/Users/你的用户名/路径/到/weather-mcp"      ],      "env": {}    }  }}

第五步:测试服务

运行服务进行测试:

npm start

或使用预定义的测试命令:

npm run test:weather

第六步:与 Cursor 集成

    打开 Cursor 应用进入设置 (Settings)找到 MCP 设置部分添加新的 MCP 服务,名称为 "china_weather"设置命令为: npm start --prefix /你的完整路径/weather-mcp保存设置

第七步:使用 MCP 工具

在 Cursor 中,可以直接调用天气查询工具:

请问今天北京的天气怎么样?

Claude 会自动调用我们的 MCP 服务,并返回格式化的天气信息。

MCP 设计最佳实践

创建高质量的 MCP 服务,应当遵循以下最佳实践:

    简洁明了的工具描述:确保描述清晰表达工具的功能和用途严格的参数验证:使用 zod 等库验证输入参数友好的错误处理:提供有意义的错误信息合理的功能拆分:每个工具只做一件事,功能不要过于复杂优雅的响应格式:返回结构化且易读的数据高效的执行性能:避免不必要的延迟良好的文档:提供详细的安装和使用说明

扩展和优化

可以考虑对天气服务进行以下扩展:

    接入真实的天气 API(如和风天气、高德天气等)增加更多功能,如空气质量指数查询支持更多城市和地区添加历史天气数据查询增加可视化内容(如天气图标)

结语

MCP 为 AI 提供了与外部世界交互的能力,大大拓展了 Claude 等大型语言模型的应用场景。通过本教程,你不仅学会了如何创建一个基本的 MCP 服务,还了解了 MCP 的工作原理和设计理念。

希望这个中国天气查询服务能为你提供实用的功能,同时也作为你开发更多 MCP 工具的起点。随着 MCP 生态的不断发展,我们期待看到更多创新的应用出现。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

MCP AI工具 天气查询 Node.js
相关文章