
前言
AI越来越火了,从年初公司提出AI优先后,这股AI的风也是慢慢吹到了团队中,笔者所在的团队是一个有着十几个人的前端小团队。其他团队的小伙伴慢慢卷起来了,隔天就要开个AI工具分享会,当其他人卷起来时,你也不得不跟紧脚步,于是便开始了解cursor,慢慢发现他似乎对我们日常的工作帮助还是蛮大的,从被迫AI到接受AI再到主动AI。
了解Cursor后,会发现mcp其实是区分他与之前的AI工具非常大的一个变动,甚至于了解完Mcp后,我甚至有点想通过他搞钱的想法,加上钱的动力,让我下定决心搞懂MCP,赚钱嘛不寒碜
什么是MCP
在cursor的文档中,解释的很透彻了,虽然他有点儿很浓的技术味。MCP其实就是供LLM智能体直接使用的工具。你可以让大模型通过MCP直接调用某些能力。
拿现实类比,AI就好像电脑,MCP就好像U盘,可以让电脑用你U盘里的所有数据,或者软件。
而他最吸引我的功能,我认为就是通过MCP可以让大模型知道实时的数据
,这也是我今天想分享的内容
众所周知GPT出世的那会,AI最为诟病的其实是数据的延后性与复杂性。数据的延后让你没办法实时通过AI获取到你想要的内容,比如,我今天该不该买股票啊!!
我相信用到AI的时候,各位韭菜肯定动过让AI帮你买股票的心思。数据复杂性更不用说了,一股脑检索全网的数据,让AI一本正经的胡说八道。
开发MCP
关于MCP的开发,官方文档其实说的挺清晰了,但按着文档走,终归是会遇到点问题的,所以还是将开发的全过程分享出来 因为我是前端,所以自然而然的选择TS语言,其他的语言也有,奢俭由人吧
前端的话,能看到这的大家都是懂一点的,初始化工程的事长话短说
node>22
初始化package.json
js
{
"name": "mcp-cursor",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"start": "node dist/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.15.1",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^24.0.13",
"typescript": "^5.7.2"
}
}
在入口文件src/index.ts
我们进行代码的编写
编写之前,先分析下我们的需求:我想写一个MCP工具让cursor能够通过当前的工具,实时获取到某个地方的天气预报,例如获取到美国加州的当前天气。那么我们需要的就有以下几方面的内容
1、
有个接口能让我实时获得天气预报,这个MCP文档中提供了
2、有
现成工具包
,能让我调用他以后,cursor就能自动调用上面的接口,这个便是MCP官方提供的工具包@modelcontextprotocol/sdk
一、初始化服务器,可以直接在本地运行
javascript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";// 基础MCP服务,官方提供
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";// 服务器与大模型通信桥梁
import { z } from "zod";// 校验工具,校验大模型调用接口时传的入参格式
const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";
// 创建 server instance
const server = new McpServer({
name: "weather",
version: "1.0.0",
capabilities: { resources: {}, tools: {}, },
});
二、提供接口调用方法与数据处理
在该MCP工具中需要暴露出能够给AI调用的接口能力,大模型执行该方法后,能够获得到对应的数据给大模型
js
// 定义请求方法
async function makeNWSRequest<T>(url: string): Promise<T | null> {
const headers = {
"User-Agent": USER_AGENT,
Accept: "application/geo+json",
};
try {
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return (await response.json()) as T;
} catch (error) {
console.error("Error making NWS request:", error);
return null;
}
}
// 定义数据结构格式化方法
function formatAlert(feature: AlertFeature): string {
const props = feature.properties;
return [
`Event: ${props.event || "Unknown"}`,
`Area: ${props.areaDesc || "Unknown"}`,
`Severity: ${props.severity || "Unknown"}`,
`Status: ${props.status || "Unknown"}`,
`Headline: ${props.headline || "No headline"}`,
"---",
].join("\n");
}
三、注册Tool类,提供给大模型调用
这里只注册一个方法,就是根据缩写获取到对应州的地址 tool方法有四个参数
第一个是方法名
第二个是方法描述,
第三个是对于大模型调用该方法时入参的数据格式校验,这里用zod规定了大模型传的state只能是2个字符
第四个就是具体的方法了,return 的数据会提供给大模型
js
server.tool(
"get-alerts",
"Get weather alerts for a state",
{
state: z.string().min(2).max(2).describe("Two-letter state code (e.g. CA, NY)"),
},
async ({ state }) => {
const stateCode = state.toUpperCase();
const alertsUrl = `${NWS_API_BASE}/alerts?area=${stateCode}`;
//
const alertsData = await makeNWSRequest<AlertsResponse>(alertsUrl);
if (!alertsData) {
return {
content: [
{
type: "text",
text: "Failed to retrieve alerts data",
},
],
};
}
const features = alertsData.features || [];
if (features.length === 0) {
return {
content: [
{
type: "text",
text: `No active alerts for ${stateCode}`,
},
],
};
}
const formattedAlerts = features.map(formatAlert);
const alertsText = `Active alerts for ${stateCode}:\n\n${formattedAlerts.join("\n")}`;
return {
content: [
{
type: "text",
text: alertsText,
},
],
};
},
);
运行 server
完成业务逻辑开发后,启动服务
js
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
以上便完成了全部mcp的业务开发,接下来要做的就是执行build生成产物,这里生成的产物就在本地环境,dist/index.js
,为了验证你的产物是否正常,可以让cursor为你生成一个测试脚本,这里就不再赘述,测试脚本内容也就是手动构造入参,然后调用对应的tool类
调试MCP
打开cursor配置,在tool目录下,将我们刚刚写的mcp工具添加进去,
这其实就是告诉cursor,执行
node dist/index.js
命令就能拿到我提供的工具类了
js
{
"mcpServers": {
"weather": {
"command": "node",// 命令
"args": ["/Users/mishi/Cursor/dist/index.js"],// 地址指向
"env": {}
}
}
}
效果展示
可以看到大模型给工具类传入了
{state:"CA"}
并且能够根据result给我们提供相应的建议
结语
能看到这的,你以为我们只是让大模型帮我们做天气预报吗?如果这里的数据不是天气预报,而是某个公司爬取下来的财报,亦或者就是某个公司的近半年股价。那么大模型,会帮助我们分析出什么呢?
我承认,一开始脑海中浮现的就是这个,才推动着我,手写一个MCP。不仅学到了点东西,甚至能让大模型真正为个人服务