Beginner of Cursor: MCP Development Calls and Project Combat

Explore new realms of AI programming, Cursor and MCP make your project development work twice the result with half the effort. Core content: 1. In-depth analysis of Cursor project development cases 2. Introduction to the MCP model context protocol and its components 3. Practical Guide to AI Application Development Based on MCP
I recently browsed several cursor articles and saw one of them I introduced several cursor project development cases, and suddenly I felt like I opened my eyes to see the world. Previously, my understanding of AI Coding was still focused on tab completion and automatic unit testing. I didn’t expect that it has developed to be able to develop projects directly. In a sense, I have achieved “just have a mouth”. So I tried the cursor and combined new functions such as MCP, Rules, Docs, etc. to help students who are not familiar with cursors get started quickly.
1. Concept
1.1 MCP
Model Context Protocol, Model Context Protocol. Official website: https://modelcontextprotocol.io/introduction
Function: MCP provides a standardized way to connect AI models to different data sources and tools. (Analogizes the USB-C ports that are now common to electronic devices, MCP provides an open standard that allows AI applications to safely access and operate local and remote data, providing an interface for AI applications to connect everything)
A few components are introduced from the official copy of the architecture diagram:
-
MCP Hosts (Initiate the application connecting to the large language model) : Programs like Claude Desktop, Tongyi Qianwen APP, IDEs, or AI tools that want to access data through MCP
-
MCP Clients (a component running inside the Host) : Protocol clients that maintain 1:1 connections with servers. Client is responsible for implementing communication between Host and Server and maintaining a one-to-one connection with MCP Server (Host:Client=1:n, Clinet:Server=1:1).
-
MCP Servers (Core component that provides specific capabilities and data access) : Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol. Server provides context and tools that handle requests from Client and return corresponding responses
-
Local Data Sources (local resource) : Your computer’s files, databases, and services that MCP servers can securely access
-
Remote Services (Remote Resource): External systems available over the internet (e.g., through APIs) that MCP servers can connect to
MCP Server has a variety of communication methods. The following two main ones are: local communication based on standard input and output (stdio) and SSE based on SSE ( Server-Sent Events ) remote communication.
-
Local communication: Transfer data through stdio, suitable for communication between clients and servers running on the same machine, the most common command line call Command.
-
Remote communication: uses SSE and HTTP to achieve real-time data transmission across the network, suitable for scenarios where remote resources are required or distributed deployments. Now the hsf service supports rapid transfer of MCP Server in this way. For details, please refer to the chanting teacher 《 A line of code does not need to be changed! Get HSF to MCP Server ".
Finally, let's take a look at the basic workflow of MCP:
Image from https://zhuanlan.zhihu.com/p/29001189476
1. Tool description and context injection: MCP Server predefined the tool's name, description, and communication method, and injected this information into the context of the large language model in structured text;
2. Select a tool: The large language model infers which tool needs to be called by analyzing user instructions and tool descriptions. Of course, you can also choose not to call Case2 in the figure above;
3. MCP Client initiates tool calls: The large model combines user input and real-time context to generate a JSON-RPC request that meets the tool requirements, including tool name and parameters;
4. MCP Server Execution Tool: Server parse the request, call the corresponding tool handler function, and encapsulate the result into a JSON-RPC response;
5. Result return integration with model: The large language model can dynamically update the context based on the results returned by the tool to generate the final answer.
1.2 Cursor
Official documentation: https://docs.cursor.com/get-started/introduction
IDE sidebar Chat panel is very familiar with, and I always feel it is almost interesting when I used it before. I tried Cusor these two days and said it was "very fragrant".
Because the following Cursor uses Docs, Rules, and MCP functions in actual combat. MCP has been introduced before. Let's take a look at the introduction to Docs and Rules in Cursor:
1.2.1 Docs
Docs: Insert into the context by indexing third-party documents.
For example, in the picture above, I inserted the MCP document in Docs, and in Chat, I can select the document through @Docs to add it to the context.
1.2.2 Rules
Official documentation: https://docs.cursor.com/context/rules-for-ai
Rules: Rules, which can be simply understood as prompt words, have global User Rules (applied to all projects) and project Project Rules
How to match project rules, there are several ways:
The commonly used one is Agent Requested. After providing a description of the relevant rules, the rules will be automatically selected according to the context content when using the Agent dialogue.
2. Practical
2.1 cursor development MCP Server
1. Create a folder first, and then enter the terminal
cursor .
Open cursor based on the current directory.
2. Create two Project Rules:
Of course we don't need to write the prompt word, just throw the reference content to the cursor:
With the above two project right-hand assistants, a mcp server for querying weather information is officially developed.
3. Execute
pnpm init
command creates the initial typeScript environment, and then creates an index.ts file in the src directory, and enables Agent based on the file Chat (the two github repositories are the official typeScript SDK and quickStart demo respectively):
4. The main file, that is, index.ts, needs to be packaged. As can be seen from the figure below, it will automatically help us improve package.json to introduce related dependencies and create tsconfig.json. What is even more surprising is that it is like execution
npm run build
, he can modify the optimization code based on the command error message until the project can be built smoothly (I remember that in the past, I could only Google to report various errors to build the project, and I flipped through historical posts one by one, and now I am really happy to buy).
The following is a file generated by cursor:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
interface WeatherData {
city: string;
temperature: number;
condition: string;
forecast: {
date: string;
condition: string;
number;
number;
low: number;
}[];
lastUpdated: string;
}
}
// Simulated weather data storage
const weatherDatabase: Record<string, WeatherData> = {
"Beijing": {
city: "Beijing",
temperature: 22,
condition: condition: 22,
condition: class="code-snippet__string">"Sunny",
forecast: [
{ date: "2025-04-08", condition: "Sunny", "Sunny", condition: "Sunny", , class="code-snippet__attr">high: 24, low: 15},
{ date: "2025-04-09", "2025-04-09", "2025-04-09", class="code-snippet__attr">condition: "大雪", high: 23, low: 14 },
{ date: "2025-04-10", condition: "High wind", high: 20, low: 12 }
],
lastUpdated: new Date().toISOString()
},
"Shanghai": {
city: "Shanghai",
temperature: 24,
condition: condition: 24,
condition: class="code-snippet__string">"cloudy",
forecast: [
{ date: "2025-04-08", condition: "cloudy", "cloudy", "cloudy", class="code-snippet__attr">high: 25, low: 17},
{ date: "2025-04-09", "2025-04-09", "2025-04-09", class="code-snippet__attr">condition: "阴天", high: 24, low: 16 },
{ date: "2025-04-10", condition: "Xiaoyu", high: 22, low: 15 }
],
lastUpdated: new Date().toISOString()
},
"Guangzhou": {
city: "Guangzhou",
temperature: 28,
condition: condition: 28,
condition: condition: class="code-snippet__string">"Sunny",
forecast: [
{ date: "2025-04-08", condition: "Sunny", "Sunny", condition: "Sunny", , class="code-snippet__attr">high: 30, low: 21 },
{ date: "2025-04-09", condition: "晴朗", high: 29, low: 21 },
{ date: "2025-04-10", condition: condition: 2025-04-10", condition: condition: class="code-snippet__string">"多云", high: 28, low: 20 }
],
lastUpdated: new Date().toISOString()
}
};
// Create an MCP server
const server = new McpServer({
name: "天气服务",
version: "1.0.0",
description: "MCP service providing city weather information"
});
// Define resources: obtain city weather data
server. class="code-snippet__title">resource(
"weatherData",
"weather://{city}",
async (uri) => {
async (uri) => {
async (uri) => {
async (uri) => {
// Extract city name from URI
const city = uri.pathname.split('/').pop() || pop() || class="code-snippet__string">"";
if (!weatherDatabase[city]) {
return {
contents: [{
uri: uri.href,
text: `未找到城市 ${city} 的天气数据`
}],
isError: true
};
}
return {
contents: [{
uri: uri.href,
text: JSON.stringify(weatherDatabase[city], null, 2)
}]
};
};
}
);
// Define resources: Get a list of all supported cities
server.resource(
"cityList",
"cityList",
"weather://cities",
async (uri) => {
return {
contents: [{
uri: uri.href,
text: JSON.stringify(Object.keys(weatherDatabase), null, 2)
}]
};
}
);
// Definition tool: Get weather forecast
server.tool(
"getWeatherForecast",
{ city: z.string().describe("The name of the city to query the weather forecast") },
async ({ city }) => {
async ({ city }) => {
if (!weatherDatabase[city]) {
return {
content: [{
type: content: type: content: class="code-snippet__string">"text",
text: `City
Weather data for the city
}],
isError: true
};
}
}
const weather = weatherDatabase[city];
return {
content: [{
type: "text",
text: "text: "text: "text,
text: class="code-snippet__string">``${city}Weather Forecast:\nCurrent Temperature: ${weather.temperature}°C, Weather Condition: ${weather.condition}\nForecast of the next three days:\n${
weather.forecast.map(day => ` weather.forecast.map(day => ` weather.forecast.map(day => `${day.date}: ${day.condition}, ${day.low}°C -${day.high}°C`).join('\n')
}\nLast update time: ${weather.lastUpdated}`
}]
};
}
}
);
// Definition tool: Update city weather
server.
server. class="code-snippet__title">tool(
"updateWeather",
{
city: z.string().describe("The name of the city to update the weather"),
temperature: z.number().describe("当前温度(°C)"),
condition: z.string().describe("天气状况描述")
},
async ({ city, temperature, condition }) => {
if (!weatherDatabase[city]) {
// If the city does not exist, create a new record
weatherDatabase[city] = {
city,
temperature,
condition,
{ date: "2025-04-08", condition: condition, high: temperature + 2, low: temperature - 2, low: temperature - 5 },
{ date: "2025-04-09", condition: condition, high: temperature + 1, 1, 1, 1, class="code-snippet__attr">low: temperature - 6 },
{ date: "2025-04-10", condition: condition, high: temperature, low: temperature - 7 }
],
],
lastUpdated: new Date(). class="code-snippet__title">toISOString()
};
} else {
// Update existing records
weatherDatabase[city].temperature = temperature;
weatherDatabase[city].condition = condition;
weatherDatabase[city].lastUpdated = new Date().Date(). class="code-snippet__title">toISOString();
}
return {
content: [{
type: type: content: type: content: class="code-snippet__string">"text",
text: `Weather data for ${city}${temperature}°C, Weather Condition ${condition}`
}]
};
}
);
// Definition prompt word: weather query
server.prompt(
"weatherQuery",
{ city: z.string().describe("City name") },
({ city }{ city }{ city }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Please provide detailed weather information for ${city}${city}, including temperature, weather conditions and forecasts for the next few days. `
}
}]
})
);
// Definition prompt word: weather suggestions
server.prompt(
"weatherAdvice",
{
city: z.string().describe("城市名称"),
activity: z.string().describe(describe("planned activities")
},
({ city, activity }) => ({
messages: [{
role: "user",
"user",
"user",
class="code-snippet__attr">content: {
type: "text",
text: `Please follow ${city}weather conditions, give me suggestions on${activity}${activity}
}]
Consider factors such as temperature and weather conditions. `
}]
}]
]
� })
);
// Start the server
async function main(){
const transport = new StdioServerTransport();
console.log(log(log("Weather service is being started...");
try {
await server.connect(transport);
await server.connect(transport);
await server.connect(transport);
console.log("天气服务已连接");
} catch (error) {
console.error("Server connection failed:", error);
}
}
main().catch(console.catch(console.catch(console.error);
After the project is built, an index.js will be generated in the build directory. The following command calls this weather mcp server.
Cursor Add MCP path in Cursor Settings->MCP->Add new global MCP Server:
{ "mcpServers": { "weather-mcp-server": { "type": "command", "command": "node /Users/jayzx/CursorProjects/cursor-mcp-demo/quickstart-resources/weather-mcp-server/build/index.js" } }}
Let's test:
2.2 cursor开发黄金价格预测项目
The above exercises of using cursor to develop MCP seem simple. With doubts about the ability of cursor to develop projects, let's do something complicated. Recalling the crazy rise of rhubarb in the past two months (670 to 820), I hate myself for selling it too early every time. If I can combine the large language model to analyze the gold trend in the next few days, can I increase short-term investment returns to a certain extent?
Do it just by doing it, first look at the current effect:
The data source for gold price forecasts is based on three parts: the daily K-line of gold, the current latest price of gold, and the U.S. market news.
2.2.1 Development
This project took a total of more than ten hours, and what I really did was actually the yellow part on the icon. The remaining long-term parts are listed as follows:
-
API debugging (40%). Ideally, this part of the work is to throw the context to the official API document and then modify your own key. However, after testing with claude-3.7-sonnet, the code quality depends strictly on the level of the document, and it is difficult to run the call successfully in one go. Solution: Let the large language model read the demo code of the document, let it write the test file first, and then apply it to the project code. Otherwise, the API development and modification of the data structure, and the project code must be modified accordingly, which is time-consuming and easy to run.
-
Front-end joint debugging (40%): Front-end requests can be correctly routed to the back-end service, deployment and troubleshooting, for example, I encountered CORS during this process. The better thing is that when you encounter an error, you can directly take a screenshot and throw it to cursor for repair. tips: Both the front and back ends add logs to view the data flow.
-
Details are perfected (20%): The rest is some physical work that moves the mouth, which improves the functions and supplements the details of the page (although this UI has not been optimized now, haha).
2.2.2 Pros and cons
Pros:
-
Fast response;
-
Chat interaction is simple;
Disadvantages:
-
Long sessions, such as tokens that exceed, will keep stuck to display Generating. Now after optimization, you can choose to start a new Chat and let the cursor summarize the conversation content and continue the conversation;
-
Code debug capability: Some extremely small code bugs are not easy to detect. For example, when developing the gold K-line chart function, the mouse hover prompts the time, opening price, closing price, etc. The API interface returns a two-dimensional array, which is probably like this
[[open,close,high,low,change,changeRate,volume,tick_at],[],,]
, in fact, each point is an array element in a two-dimensional array, just parse it to the corresponding field according to the index. After the cursor development is completed, the hover field does not correspond to it. I took a screenshot to fix it and asked him to log and analyze it. I talked about it two or three times but it was not fixed. Finally, I looked at the code myself and found that the simple index was not matched.
3. Some feelings and techniques
After a few simple days of cursor experience, I feel that the rumored novice started to develop the app online or a little exaggerated. A slightly more complex project, such as front-end, deployment and online, still requires the user to have a certain development foundation (common node, python, linux, git commands). Because only if you can understand what the front and back ends are doing, you can assist cursor repair and optimize when problems arise.
But the role of cursor cannot be ignored, especially for the front-end or back-end development toward full stack, it provides a simple and effective shortcut.
The article has mentioned some cursor usage techniques, and finally summarized it briefly:
-
Describe your product functions well: The main functions must be explained clearly, and the detailed description can be added later.
-
Technical options: Don't write code as soon as you come up. Let cursor release a technical solution first, modify it before starting to write code.
-
Interface development: In addition to the quickStart of the official document, it is best to give the demo code, and then test the interface and apply it to the project code.
-
Add logs: can help locate problems faster.
-
Use Docs and Project Rules: These two tools can significantly improve the quality of your code and let the code develop in the direction you expect.
-
Git management: Be sure to use git to commit in time after implementing a function. Since cursor generates code not necessarily in line with expectations each time, it can quickly roll back with git.
The final 10 cursor gameplay summarized by Prajwal Tomar is given: