Cursor Basics: MCP Development Calls and Project Practice

Written by
Iris Vance
Updated on:June-09th-2025
Recommendation

Explore the new realm of AI programming, Cursor and MCP make your project development twice as effective.

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

 
Yang Fangxian
Founder of 53A / Tencent Cloud (TVP), Most Valuable Expert

Recently, I brushed a few articles on cursor, and when I saw one of the articles introducing a few cursor project development cases, I suddenly had a feeling of opening my eyes to the world. Before, the knowledge of AI Coding still stayed in tab completion, automatic generation of unit tests, I did not expect that now it has developed to the direct development of the project, in a sense, to do "have a mouth on the line". So, try to play under the cursor, and combine with the MCP, Rules, Docs, and other new features to help those who are not familiar with the cursor quickly get started.

I. Concepts

1.1 MCP

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. (Analogous to the USB-C port, which is now common in electronic devices, MCP provides an open standard that enables AI applications to securely access and manipulate local and remote MCP provides an open standard that allows AI applications to securely access and manipulate local and remote data, providing an interface for AI applications to connect to everything).

 

From the official copy of the architecture diagram, a few components are introduced:

  • MCP Hosts (applications that initiate the connection to the large language model) : Programs like Claude Desktop, Tongyiqianwen App, IDEs, or AI tools that want to access data through MCP

  • MCP Clients (a component that runs inside Host) : Protocol clients that maintain 1:1 connections with servers. Client is responsible for implementing communication between Host and Server, and maintains a one-to-one connection with the MCP Server (Host:Client=1:n, Client:Server=1:1).

  • MCP Servers (core components that provide specific capabilities and data access) : Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol. The Server provides the context and tools responsible for handling requests from the Client and returning the appropriate responses

  • Local Data Sources : Your computer's files, databases, and services that MCP servers can securely access.

  • Remote Services: External systems available over the internet (e.g., through APIs) that MCP servers can connect to.

There are several ways that MCP Server can communicate, but here are the two main ones: local communication based on stdio (standard input/output) and remote communication based on SSE ( Server-Sent Events ).

  • Local communication: transferring data through stdin, applicable to the communication between the client and the server running on the same machine, the most common is the command line call.

  • Remote communication: using SSE combined with HTTP to realize real-time data transfer across the network, suitable for scenarios that require access to remote resources or distributed deployment. Now HSF service supports this way to quickly turn the MCP Server, see the line words of the teacher's " a line of code does not have to change! Getting HSF to MCP Server ".

Finally, look at the basic workflow of MCP:

1. Tool description and context injection: MCP Server will predefine the name, description, and communication mode of the tool, and inject this information into the context of the large language model in the form of structured text.

2. Tool Selection: The large language model analyzes the user commands and tool descriptions to reason out which tool should be invoked. Of course, you can also choose not to invoke, such as Case 2 in the above figure.

3. MCP Client initiates the tool invocation: the large language model combines user input and real-time context to generate a JSON-RPC request that meets the requirements of the tool and contains the tool name and parameters.

4. MCP Server executes the tool: Server parses the request, calls the corresponding tool processing function, and encapsulates the result into a JSON-RPC response.

5. Result return and model integration: The large language model can dynamically update the context according to the result returned by the tool to generate the final answer.

1.2 Cursor

Official documentation: https: //docs.cursor.com/get-started/introduction

We are all familiar with the Chat panel in the IDE sidebar, and it has always been interesting to use it before. In the past two days, I tried to play Cusor, and I said "it's great".

Because of the following Cursor will be used in practice when the Docs, Rules, and MCP functions have been introduced. The following looks at the Cursor on the Docs and Rules of the introduction:

1.2.1 Docs

Docs: Insert third-party documents into the context by indexing them. You can also select the document to be added to the context through @Docs in Chat.

1.2.2 Rules

Official document: https: //docs.cursor.com/context/rules-for-ai

Rules: Rules can be simply understood as prompt words; there are global User Rules (applied to all projects) and project-specific Rules.

There are several ways to match project rules:

Commonly used is Agent Requested, after providing the relevant rules description, in the use of Agent dialog, will be automatically selected according to the context of the content of the rule application.

 

2. Actual combat

 

2.1 Cursor Development MCP Server

1. First, create a folder, and then type cursor in the terminal . Open the cursor according to the current directory.

2. Create two Project Rules:

Cue words, of course, do not need us to write, directly throw the reference to the cursor:

With the above two Project Rules, the following formal development of a query for weather information on the MCP server is presented.

3. Execute the pnpm init command to establish the initial TypeScript environment, and then in the src directory to create an index.ts file, based on the file to open the Agent Chat (two GitHub repositories are the official TypeScript SDK and quickStart demo). 

4. main file that is index.ts have, you also need to perform the packaging of the project. As you can see from the figure below, he will automatically help us improve package.json to introduce relevant dependencies and create tsconfig.json. More surprising is that, like the execution of npm run build and other commands, he can be combined with the command error information to modify and optimize the code until the project can be built successfully (recalling that the previous build project all kinds of errors can only be Google, one by one, turn over the history! (I remembered that when I used to build projects with various errors, I had to Google them and go through the history one by one.)

Here is the index.ts 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; high: number; low: number; }[]; lastUpdated: string;}
// Simulate weather data storageconst weatherDatabase: Record<string, WeatherData> = { " Beijing": { city: "Beijing", temperature: 22, condition: "Sunny", forecast: [ { date: " 2025-04-08", condition: "Sunny", high: 24, low: 15 }, { date: "2025-04-09", condition: "Snowy", high: 23, low: 14 }, { date: "2025-04-10", condition: "Windy", high: 20, low: 12 }, { date: " Beijing": { city: "Beijing", temperature: 22, condition: " Sunny", forecast: [ { date: "Beijing", forecast: [ { date: "Beijing", forecast: high: 20, low: 12 } ], lastUpdated: new Date (). toISOString () }, " Shanghai": { city: "Shanghai", temperature: 24, condition: "Cloudy", forecast: [ { date: "2025-04-08", condition: " Cloudy", forecast: [ { date: "2025-04-08", condition : " Cloudy ", forecast: [ { date: "2025-04-10", condition: " Windy ", high: 23 , low: 14 } forecast : [ { date: " 2025-04-08 ", condition: "Cloudy", high: 25, low: 17 }, { date: "2025-04-09", condition: "Cloudy", high: 24, low: 16 }, { date: "2025-04-10", condition: "Light Rain", high: 22, low: 15 } ], lastUpdated: new Date (). toISOString () }, " Guangzhou": { city: "Guangzhou", temperature: 28, condition: "Sunny", forecast: [ { date: "2025-04-08", condition: "Sunny", high: 30, low: 21 }, { date: "2025-04-09", condition: "Sunny", high: 29, low: 21 }, { date: "2025-04-10", condition: "Cloudy", high: 28, low: 20 } ], lastUpdated. new Date (). toISOString ()}};
// Create the MCP serverconst server = new McpServer ({ name: "Weather Service", version: "1.0.0", description: "MCP service providing city weather information"});// Define the resource: get city weather information.
// Define the resource: get the city weather dataserver. resource ( " weatherData", " weather://{city}", async (uri) => { // Extract the city name from the URI const city = uri. pathname. split ( '/' ). pop () || ""; if (!weatherDatabase[city]) { return { contents: [{ uri: uri. href, text: `Weather data not found for city ${city}` }], isError: true }; }
return { contents: [{ uri: uri. href, text: JSON. stringify (weatherDatabase[city], null, 2 ) }] }; } );
// Define resource: get a list of all supported citiesserver. resource ( " cityList", " weather://cities", async (uri) => { return { contents: [{ uri: uri. href, text: JSON. stringify ( Object. keys (weatherDatabase), null, 2 ) }] }; } );
// Define tool: get weather forecastserver. tool ( " getWeatherForecast", { city: z. string (). describe ( "Name of city to query for weather forecast") }, async ({ city }) => { if (!weatherDatabase[]) { return { content: [{ uri: uri.href: text: JSON.stringify (Object.keys(weatherDatabase), null, 2) }] }; }; }; }; }; }; }; }; }; } city]) { return { content: [{ type: "text", text: `weather data for city ${city} does not exist` }], isError: true }; }
const weather = weatherDatabase[city]; return { content: [{ type: "text", text: `${city}weather:\n current temperature: ${weather.temperature}°C, weather condition: ${weather. condition}\nForecast for next 3 days:\n${ weather.forecast.map(day => `${day.date}: ${day.condition}, ${day.low}°C - ${day.high}°C` ).join( '\n' ) }\nLast Updated Time : ${weather.lastUpdated}` }] }; } );
// Define tool: update city weatherserver. tool ( " updateWeather", { city: z.string(). describe ( "Name of the city to update the weather to"), temperature: z. number ().describe( "Current temperature (°C)"), { condition : z.string ( ) . describe ( "Current temperature (°C)"), } ; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; } condition: z. string (). describe ( "Description of weather conditions") }, async ({ city, temperature, condition }) => { if (!weatherDatabase[city]) { // If the city doesn't exist, create a new record weatherDatabase[city] = { city, temperature, condition, forecast: [ { date: "2025-04-08", condition: condition, high: temperature + 2, low. temperature - 5 }, { date: "2025-04-09", condition: condition, high: temperature + 1, low: temperature - 6 }, { date: "2025-04-10", condition: condition , high: temperature, low: temperature - 7 } ], lastUpdated: new Date (). toISOString () }; } else { // Update existing records weatherDatabase[city]. temperature = temperature; weatherDatabase[city]. condition = condition; weatherDatabase[city]. lastUpdated = new Date (). toISOString (); }
return { content: [{ type: "text", text: `Weather data for ${city} has been successfully updated: temperature ${temperature}°C, weather condition ${condition}` } ] }; } ); }
// Define the prompt: weatherQueryserver. prompt ( " weatherQuery", { city: z. string (). describe ( "city name") }, ( { city }) => ({ messages: [{ role: "user", content: { type: " text", text: `Please providedetailed weather information for${city}, including temperature, weather conditions and forecast for the next few days. ` } } ] } ));
// Define the prompt: weatherAdviceserver. prompt ( " weatherAdvice", { city: z. string (). describe ( "city name"), activity: z. string (). describe ( "planned activity") }, ( { city, activity}) => ({ messages: [{ role: "user", content: { type: "text", text: `Pleasegive mesuggestionsabout${activity} based onthe weather conditions in${city}. Consider temperature, weather conditions, etc. ` } } ] } ));
// Start the serverasync function main (){ const transport = new StdioServerTransport (); console. log ( "Weather service starting..."); try { await server. connect (transport); console. log ( "Weather service is connected"); } catch (error) { console. error ( "Server connection failed:", error);}}
main (). catch ( console. error );

After the project is built, an index.js will be generated in the build directory, and the following calls the weather mcp server by command.

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" } }}

 

2.2 Cursor development of a gold price prediction project

Above, the use of the cursor development MCP exercise seems simple, with the ability to develop usable projects, cursor questions, and the following hands-on to do something more complex. Associated with attention to rhubarb in the last two months of the crazy upward trend (670 to 820), every time you sell hate yourself to sell early, if you can combine with a large model to analyze the gold trend in the next few days, is not it possible to improve short-term investment returns to a certain extent?

Said to do, first look at the current realization of the effect:

The data source of gold price prediction is based on three parts: the daily K-line of gold, the latest price of the current gold, about gold and the United States market newsletter.

2.2.1 Development

This project took a total of about ten hours, and really, all I did was the yellow part of the icon above. The rest of the more time-consuming parts are listed below:

  • API debugging (40%). Ideally, this part of the work is the context of the official documentation thrown to their api, and then changing their own key can be. But the use of the Claude-3.7-sonnet test down, the quality of the code is strictly dependent on the level of documentation, and it is difficult to run a one-time call successfully. Solution: Let the large language model read the demo code of the document, let it write the test file first, api test passes, and then apply it to the project code, otherwise api development to modify the data structure, the project code to follow the changes, time-consuming and easy to run up.

  • Front-end and back-end tuning (40%): front-end requests can be correctly routed to the back-end services, deployment troubleshooting, such as I encountered in this process, CORS, and so on. The better point is that you can directly encounter errors in the screenshot to correct the cursor repair. tips: front and back end are added to the log, check the data flow.

  • Details of the perfect (20%): the rest is some of the physical work of the mouth, the function of the perfect, page details to add (although the UI is not optimized haha).

2.2.2 Advantages and disadvantages

Pros:

  • In addition to MCP, Docs, Rules, and these tools, the cursor relative to the regular IDE Chat panel, you can directly read the entire project file, browse the web, read images, and run commands, which are very useful. For example, the command execution failure, according to the command to return to the content of the error to make adjustments, greatly improves the code generation capabilities; read the picture, the error directly throws the error screenshot or optimize the page directly throws the page component screenshot;

  • Fast response time;

  • Chat interaction is simple;

Disadvantages:

  • Long sessions, such as token exceeded, will be stuck displaying Generating. Now, after optimization, you can choose to start another New Chat to let the cursor summarize the contents of the session and continue the conversation;

  • Code debugging ability: Some very small code bugs are not easy to find. For example, in the development of gold K-line chart function, the mouse hover prompt will show the time, opening price, closing price, etc., api interface returns a two-dimensional array, probably long like this[[open,close,high,low,change,changeRate,volume,tick_at],[],,,,,] , in fact, each point is a two-dimensional array elements in an array, according to the index resolution to the corresponding field is good. cursor development is completed after the hover field does not correspond to, I took a screenshot to him to repair and let him hit the log to analyze, move his lips two or three times have not been fixed, and finally look at the code to find out that is a simple index is not on the right.

 

3. Some feelings and skills

Simple a few days cursor experience down, feel the net rumor of zero basic white hands on the development of app on-line, perhaps more or less exaggerated, slightly more complex projects, such as involving front and back end, deployment on-line, etc., or need to users with a certain degree of development foundation (commonly used node, python, linux, git commands). Because you can only understand the front and back end of the rough, what to do, in order to assist in the emergence of problems when the cursor repair optimization is performed.

But the role of the cursor can not be ignored, especially for front-end or back-end development, towards the full stack provides a simple and effective shortcut.

The article has already mentioned some cursor use skills, and finally, briefly added to summarize:

  • Describe the function of your product: the main function must be clear; the details of the description can be added later.

  • Technical options: do not come up to write code, first let the cursor out of a version of the technical program, modify it, and then start writing code.

  • Interface development: in addition to the official document quickStart, it is best to give demo code, and then test the interface, and then apply it to the project code.

  • Add logs: it can help to locate the problem faster.

  • Use Docs and Project Rules: these two tools can significantly improve the quality of the code, so that the code develops in the direction you expect.

  • Git Management: Always use git, and commit a feature once it is implemented. Since the cursor does not always generate code as expected every time, working with git allows for quick rollbacks.