MCP server: A step-by-step guide to building from scratch

As AI revolutionises software development, integrating it within workflow using IDEs like Cursor and Windsurf is becoming normal for developers. However, a pain point remains: Integrating tools, external services like API, and local data with IDE / AI.
Though tools like Function Calling, Tool Calling, and RAG exist, they are painful, time-consuming, and often require domain knowledge. What if this process could be simplified?
A game changer, Right?
The Model Context Protocol (MCP) does just that without breaking a sweat. So, what is it, how do I use it, how do I integrate MCP in IDE, and what are some advanced use cases of MCP?
Let’s find out!
What is MCP
Think of MCP as a USB C port on a laptop. With it, you can charge your computer, perform data transfer, connect to other displays, and charge other Type C-supported devices.
Similarly, the Model Context Protocol provides a standard, secure, real-time, two-way communication interface for AI systems to connect with external tools, API Services, and data sources.
This means that, unlike traditional API integration, which requires separate code, documentation, authentication methods, and maintenance, MCP can provide a single, standardized way for AI models to interact with external systems. You write code once, and all AI systems can use it.
The key differences between MCP and traditional APIs include:
Feature | MCP | Traditional API |
---|---|---|
Integration Effort | Single, standardized integration | Separate integration per API |
Real-Time Communication | ✅ Yes | ❌ No |
Dynamic Discovery | ✅ Yes | ❌ No |
Scalability | Easy (plug-and-play) | Requires additional integrations |
Security & Control | Consistent across tools | Varies by API |
MCP enables two-way communication, allowing AI models to retrieve information and dynamically trigger actions. This makes it perfect for creating more intelligent and context-aware applications. Check out this blog on Model Context Protocol for a full breakdown.
So, how does this all work?
MCP Components

The MCP architecture consists of several key components that work together to enable seamless integration:
- 1. Hosts: These are applications (like Claude Desktop or AI-driven IDEs) that need access to external data or tools
- 2. Clients maintain dedicated, one-to-one connections with MCP servers.
- 3. MCP Servers: Lightweight servers that expose specific functionalities via MCP, connecting to local or remote data sources.
- 4. Local Data Sources: Files, databases, or services securely accessed by MCP servers
- 5. Remote Services: External internet-based APIs or services accessed by MCP servers
This separation of concerns makes MCP servers highly modular and maintainable.
So, how does this all connect?
How The Components Work Together
Let’s understand this with a practical example:
Say you’re using Cursor (an MCP host) to manage your project’s budget. If you want to update a budget report in Google Sheets, send your team a summary of the changes via Slack.
- • Cursor (MCP host) requests its MCP client to update the budget report in Google Sheets and send a Slack notification.
- • The MCP client connects to two MCP servers: one for Google Sheets and one for Slack.
- • The Google Sheets MCP server interacts with the Google Sheets API (remote service) to update the budget report.
- • The Slack MCP server interacts with the Slack API (remote service) to send a notification.
- • MCP servers send responses back to the MCP client.
- • The MCP client forwards these responses to the Cursor, which displays the result to the user.
This seamless process allows Cursor to integrate with multiple services through a standardized interface.
But understanding fundamentals is no use if one can’t build, so let’s get building!
How to Build an MCP Server
There are 2 ways to build an MCP Server: using the Python SDK or the JavaScript SDK. For the sake of simplicity, I will stick to the Python SDK.
So, like any other good dev, let’s create a separate work environment to isolate things.
1. Work Environment Setup
We start by creating a project directory.
Navigate to your working folder and create a folder named MCP, or u can use the terminal command:
mkdir mcp
cd mcp
Next, create a virtual environment using:
# windows
python -m venv dotenv
# linux/mac
python -m venv --help
sudo apt-get install python3-venv #install venv - optional
python3 -m venv dev-env
Now activate the environment with:
# activates env
dotenv\\Scripts\\activate
# linux/mac
dotenv\\Scripts\\activate
Ensure you see (dotenv) in Front of the terminal cwd path.
Finally install two libraries – MCP SDK MCP CLI:
# install libraries
pip install mcp mcp[cli]
It might ask you permission to install, press y and once installed, we are done with setting up the environment
2. Writing the Server Code
Open the folder in any of your favourite editors of choice, create a new file called calculator.py, and write the following code:
# basic import
from mcp.server.fastmcp import FastMCP
import math
# instantiate an MCP server client
mcp = FastMCP("Hello World")
# DEFINE TOOLS
#addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return int(a + b)
# subtraction tool
@mcp.tool()
def subtract(a: int, b: int) -> int:
"""Subtract two numbers"""
return int(a - b)
# multiplication tool
@mcp.tool()
def multiply(a: int, b: int) -> int:
"""Multiply two numbers"""
return int(a * b)
# division tool
@mcp.tool()
def divide(a: int, b: int) -> float:
"""Divide two numbers"""
return float(a / b)
# power tool
@mcp.tool()
def power(a: int, b: int) -> int:
"""Power of two numbers"""
return int(a ** b)
# square root tool
@mcp.tool()
def sqrt(a: int) -> float:
"""Square root of a number"""
return float(a ** 0.5)
# cube root tool
@mcp.tool()
def cbrt(a: int) -> float:
"""Cube root of a number"""
return float(a ** (1/3))
# factorial tool
@mcp.tool()
def factorial(a: int) -> int:
"""factorial of a number"""
return int(math.factorial(a))
# log tool
@mcp.tool()
def log(a: int) -> float:
"""log of a number"""
return float(math.log(a))
# remainder tool
@mcp.tool()
def remainder(a: int, b: int) -> int:
"""remainder of two numbers divison"""
return int(a % b)
# sin tool
@mcp.tool()
def sin(a: int) -> float:
"""sin of a number"""
return float(math.sin(a))
# cos tool
@mcp.tool()
def cos(a: int) -> float:
"""cos of a number"""
return float(math.cos(a))
# tan tool
@mcp.tool()
def tan(a: int) -> float:
"""tan of a number"""
return float(math.tan(a))
# DEFINE RESOURCES
# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
# execute and return the stdio output
if __name__ == "__main__":
mcp.run(transport="stdio")
Let’s take a moment to understand what’s happening in the code.
- First, we imported the
FastMCP
server from the MCP package and themath
module. The FastMCP Server manages connections, follows the MCP protocol, and routes messages. - Next, we created an MCP server client and named it “Hello World”.
- Then, we added tools using
@mcp.tool()
and resources using@mcp.resource()
. These tools help the server perform operations, and the resource provides personalized greetings. (talk about exposing your data to LLM) - Lastly, we start the MCP server using
@mcp.run()
, and the setup allows communication via standard input/output (stdio
).
Hopefully, you will clearly understand what the code is doing now!
Now let’s test it using MCP Inspector
3. Running & Testing the Server Locally
MCP Inspector is a handy GUI tool that lets you test your custom MCP server without integrating it with LLM / AI agents. Let’s set it up.
Open the terminal and ensure you are in the working environment. Then type the following command:
mcp dev server.py<br>
If you haven’t installed CLI in the previous section, you will be prompted to do so. You can either do it manually or again press ‘y’.
Once done, rerun the command, showing you a URL (mostly localhost).

Open it and press Connect:
Connecting MCP Inspector to the server.
Note: If you cannot connect and it throws an error, restart your PC and rerun the command.
Now, let’s test the resource functionality.
Click on “List Templates,” select the displayed one, add your name, click “Read Resouces,” and check out the output.
Now let’s test the tools, I am going to test one of them, though you are free to do.
Head to the Tools top in the navbar, click “List Tools” → select your desired one → Input values and press “Run Tool”. You will see the output.
Note: In case you encounter the Pydantic Error as :
Error executing tool subtract: 2 validation errors for subtractArguments
a
Field required [type=missing, input_value={}, input_type=dict]
For further information visit <https://errors.pydantic.dev/2.10/v/missing>
b
Field required [type=missing, input_value={}, input_type=dict]
For further information visit <https://errors.pydantic.dev/2.10/v/missing>
You can delete both values and enter a different value. This is one bug with the tool, and it may have been done deliberately to reduce misuse.
So, with this, we are done with testing.
However real power of MCP lies with the integration of IDE’s / Agents. Let’s look at how to connect them?
Connecting Custom Servers to Cursor
I will use Cursor for demonstration purposes, as integration is simple and straightforward.
Head over to your current working directory (cwd) and open the folder within Cursor. Your file explorer should look something like this 👇

project folder opened in cursor – file explorer view
Once in the folder, activate the virtual environment we made in the previous steps. (optional but suggested)

activate virtual environment – dotenv (in Windows)
Next, head to File → Preferences → Cursor Settings → MCP → Add New Server
Open MCP Server Settings
Next, Fill in the details as follows:
Name: Name of the server. I am calling it a calculator.
Type: command (imp) .
Command: Here, you need to provide the command that will run the server. It follows the format:
/path/to/your/venv/bin/python /path/to/your/file.py
In my case, this maps to:
C:\\Users\\Harsh\\Documents\\WORK\\mcp-demos\\mcp-hello-world\\dotenv\\Scripts\\python.exe C:\\Users\\Harsh\\Documents\\WORK\\mcp-demos\\mcp-hello-world\\calculator.py
Once done, you will see a cmd/ terminal window opening; minimize it, and you can see a 🟢 calculator:
Add mcp server config and production.
Note: If you see a 🟠 calculator, check your path to both routes and retry.
To check the functionality, head to the composer, select Agent, write the following prompt and hit enter:
Can you add two numbers, 3 and 6?
You will see it automatically retrieves the add tool under the alias mcp_add()
. This means the cursor is now connected to the server. Here is a small demo of testing server tools in cursor (only supported functionality).
Testing server tools functionality.
So far, so good, but these are just toy examples. What if you have to work on some advanced projects and use multiple different servers/tools? You’d need to write numerous lines of code for multiple tools, right?
Let’s look at a simpler alternative and how its one-liner integrations simplify workflow.
Enters Composio!
Composio in a Nutshell
Composio is the ultimate integration platform, empowering developers to seamlessly connect AI agents with external tools, servers, and APIs with just a single line of code.
With the fully managed MCP Servers, developers can rapidly build powerful AI applications without the hassle of managing complex integrations. We take care of the infrastructure so you can focus on innovation.
Let’s dive into how you can integrate composite-mcp into your workflow effortlessly!
Composio MCP Integration
Integrating with Composio MCP is incredibly simple and can be done in just five steps:
- 1. Visit the Composio MCP Directory page
- 2. Select Tools you need, keep an eye on the following:
- Name: Name of tool / Server
- Description: What the tool does
- Images: Compatibility (as of now, Windsurf isn’t available for Windows)
- 3. Go to the Installation Steps section on the next page and hit Generate. Copy the generated URL (private info). Make sure to read all the available functions in the Available Actions section.
- 4. Open the cursor and head over to File → Preferences → Cursor Settings → MCP → Add New Server
- 5. Select Type as “sse” & paste the copied URL into the Server URL.
& you are done!
For reference, here is a sample integration with Google Drive, Sheets & Docs:
To test the integration, go to the Composer, initiate a connection, and ask it to perform actions.
Let’s look at an advanced integration to see where composio-mcp shines.
Linear tickets Management with Slack Collaboration.
Composio can handle advanced use cases effortlessly. Let’s demonstrate how Composio solves the following challenge seamlessly:
Development teams often struggle to manage product-related issues, as this requires constant back-and-forth between the IDE and team Slack channels.
Develop an agent that handles all the operations through the IDE. This way, teams can stay in sync without unnecessary context switching, dramatically increasing productivity.
Let’s use composio-mcp for this one!
We will create a linear ticket for demonstration purposes and send it to our Slack team channel.
Follow the steps one after another:
- 1. Head to the MCP Repository and select Linear & Slack integrations. If you don’t find them listed, use the search console.
- 2. Generate an SSE Key & copy it.
- 3. Open the cursor and integrate it with the method covered in the above section.
If you are having any issues, here is a sample integration video. 👇
Integrating Linear & Slack in Cursor.
Ok, now let’s see if it works as expected.
- Head to the cursor chat and select Agent.
- Initiate an OAuth connection by writing “create a connection with Slack”. Do the same for Linear
- Head to the generated URL and authenticate. Make sure to review the permission! slack-oauth.mp4
- Once done, head back to the cursor and ask if the connection is active.
- Once everything is in place, you can start working with the MCP integrations.
I used a simple prompt to create a linear issue and send a message about it in a Slack channel.
Prompt: Create a Linear issue under a given project, change the label to “TODO,” add a comment under the problem, and once everything is done, message about the issue creation status on a Slack channel.
Composio MCP’s seamless integration connected a complex workflow without writing a single line of code. You
We have now reached the end of the article, but before that, here are some final thoughts.
Conclusion
As AI transforms software development, MCP will play an increasingly important role in creating seamless, integrated experiences.
Whether building custom MCP servers or leveraging pre-built solutions like Composio MCP, the protocol offers a powerful way to enhance AI capabilities through external tools and data sources.
The future of AI isn’t just about smarter models – it’s about creating ecosystems where AI can seamlessly interact with the tools we use every day. MCP is a crucial step toward that future.
I hope you had a great learning experience—happy building with Composio!