Dashboard
Lessons
Lesson 8: Building Your First MCP Server

Lesson 8: Building Your First MCP Server

Skills
Agentic Coding
Code Assistants
Prompt Engineering

Understanding MCP Servers: Your Gateway to AI Tool Enhancement

Imagine having the ability to teach your AI assistant completely new skills—like counting specific letters in words, checking weather conditions, or integrating with any API you choose. This is exactly what MCP (Model Context Protocol) servers enable you to do.

Think of an MCP server as a bridge between your AI assistant and custom functionality. Just as you might install apps on your smartphone to add new capabilities, MCP servers let you create and install custom tools that expand what Claude Desktop can accomplish. Instead of being limited to Claude's built-in capabilities, you can craft specialized tools tailored to your specific needs.

In this comprehensive guide, we'll build a simple yet functional tool that counts the letter "R" in any given word. While this example might seem basic, it demonstrates the fundamental principles you'll use to create sophisticated tools like weather checkers, API integrators, or data processors.

What Makes MCP Servers Powerful

MCP servers operate as intermediaries that expose your custom tools to AI assistants in a standardized way. When you create an MCP server, you're essentially creating a communication protocol that allows Claude Desktop to understand and execute your custom functions seamlessly.

The beauty of this system lies in its flexibility. Once you understand the basic structure, you can adapt it to wrap virtually any functionality—from simple text processing to complex database operations or third-party API integrations.

Setting Up Your Development Environment

Before we dive into code, we need to establish a proper development environment. This foundation ensures your MCP server runs smoothly and remains maintainable as you expand its capabilities.

Creating Your Project Structure

First, open your preferred IDE. For this tutorial, we'll use WindSurf, but any code editor will work perfectly. The key is having access to a terminal within your development environment.

Begin by creating a dedicated folder for your MCP server project. This organization keeps your code clean and makes future modifications easier to manage.

mkdir count-r-server
cd count-r-server

This simple step creates a focused workspace where all your MCP server files will live. Think of this folder as your tool's home base—everything related to this specific MCP server stays contained here.

Establishing a Virtual Environment

Virtual environments are crucial for Python development, especially when working with specialized libraries like MCP. They create isolated spaces where your project's dependencies won't conflict with other Python projects on your system.

python -m venv .venv

This command creates a new virtual environment in a hidden folder called .venv. Now you need to activate this environment, and the process differs slightly between operating systems.

For Windows users:

bash

.venv\Scripts\activate

For Mac and Linux users:

bash

source .venv/bin/activate

Once activated, you'll notice your terminal prompt changes to indicate you're working within the virtual environment. This visual cue confirms that any packages you install will be contained within this project's scope.

Installing the MCP Library

With your virtual environment active, install the MCP library that provides all the tools and frameworks necessary for building your server.

pip install mcp

This single command downloads and installs the Model Context Protocol library along with all its dependencies. The MCP library includes FastMCP, which simplifies server creation and handles much of the underlying complexity for you.

Try It Yourself

Before proceeding to the next section, take a moment to verify your environment setup:

  • Confirm your virtual environment is active (check your terminal prompt)
  • Test that Python is working by typing python --version
  • Verify the MCP library installed correctly by running pip list and looking for "mcp" in the output

Building Your First MCP Server

Now comes the exciting part—writing the actual server code that will power your custom tool. We'll create a robust, production-ready server that handles errors gracefully while remaining simple enough to understand and modify.

Understanding the Server Architecture

Create a new file called server.py in your project folder. This file will contain all the logic for your MCP server, including tool definitions, error handling, and server configuration.

The server we're building follows a specific architecture pattern that makes it both reliable and extensible. While you could create a minimal MCP server with just a few lines of code, adding proper error handling and graceful shutdown capabilities makes your tool more professional and reliable.

from mcp.server.fastmcp import FastMCP
import time
import signal
import sys

# Signal handler for graceful shutdown
def signal_handler(sig, frame):
   print("\nShutting down MCP server gracefully...")
   sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

This opening section imports the necessary libraries and sets up a signal handler. The signal handler ensures that when you stop your server (using Ctrl+C), it shuts down cleanly rather than abruptly terminating.

Configuring Your MCP Server

Next, we initialize the FastMCP server with specific configuration parameters that define how your tool operates and communicates.

# Initialize the MCP server
mcp = FastMCP(
   name="count-r",
   host="127.0.0.1",
   port=5000,
   timeout=30
)

Each parameter serves a specific purpose:

  • name: This identifier becomes the reference name for your tool. When you want Claude Desktop to use this specific tool, you'll reference it by this name.
  • host: Since we're running locally, we use the localhost address (127.0.0.1). If you were deploying this server to a remote machine, you'd change this to that server's address.
  • port: This defines which port your server listens on. Port 5000 is commonly used for development servers and rarely conflicts with other services.
  • timeout: This 30-second timeout prevents your server from hanging indefinitely if something goes wrong during tool execution.

Creating Your Custom Tool

The heart of your MCP server is the actual tool definition. This is where you specify what your tool does, what inputs it expects, and what outputs it provides.

@mcp.tool()
def count_r(word: str) -> int:
   """Count the number of 'R' letters in a given word."""
   try:
       # Validate input
       if not isinstance(word, str):
           raise ValueError("Input must be a string")
       
       # Count 'R' letters (case-insensitive)
       return word.lower().count('r')
   
   except Exception as e:
       print(f"Error in count_r tool: {e}")
       return 0

This tool definition demonstrates several important concepts:

The @mcp.tool() decorator tells FastMCP that this function should be exposed as a tool. The function signature count_r(word: str) -> int clearly defines that this tool expects a string input and returns an integer output.

The docstring provides a human-readable description that Claude Desktop can use to understand what this tool does. This description helps Claude decide when and how to use your tool appropriately.

The error handling ensures that even if something unexpected happens, your tool returns a sensible default value rather than crashing the entire server.

Launching Your Server

Finally, we need code that actually starts the server and keeps it running:

if __name__ == "__main__":
   print("Starting MCP server 'count-r' on 127.0.0.1:5000")
   mcp.run()

This standard Python pattern ensures the server only starts when you run the script directly. The mcp.run() call starts the server and keeps it running until you stop it.

Did You Know?

The Model Context Protocol was designed to standardize how AI assistants interact with external tools and data sources. This standardization means that tools you build for Claude Desktop using MCP could potentially work with other AI assistants that support the protocol, making your development efforts more valuable and portable.

Configuring Claude Desktop Integration

Creating the server is only half the battle. Now you need to tell Claude Desktop where to find your MCP server and how to communicate with it. This configuration step is crucial for establishing the connection between your custom tool and Claude's interface.

Accessing Claude Desktop Configuration

Claude Desktop stores its configuration in a specific JSON file that you need to edit. The easiest way to access this file is through Claude Desktop's built-in settings interface.

Open Claude Desktop and navigate to the hamburger menu (three horizontal lines), then select "File" → "Settings" → "Developer". You'll see an "Edit Config" button that opens the configuration file directly in your default text editor.

Initially, this file is completely empty, which is normal for new installations. You'll be adding JSON configuration that tells Claude Desktop about your MCP server.

Understanding the Configuration Structure

The configuration file uses a specific JSON structure that Claude Desktop expects. Here's the complete configuration you need to add:

{
 "mcpServers": {
   "count-r": {
     "command": "python",
     "args": [
       "/absolute/path/to/your/count-r-server/server.py",
       "--host", "127.0.0.1",
       "--port", "5000",
       "--timeout", "30"
     ]
   }
 }
}

Critical Configuration Details:

The most important part of this configuration is the absolute path to your server.py file. This must be the complete file path, not a relative path. For example:

  • Windows: "C:\\Users\\YourName\\Projects\\count-r-server\\server.py"
  • Mac/Linux: "/Users/YourName/Projects/count-r-server/server.py"

The "command" field specifies how to run your server. Since we're using Python, this should be "python" (or "python3" on some systems).

The "args" array contains all the arguments passed to your Python script, including the script path and any additional parameters your server needs.

Configuration Troubleshooting

If Claude Desktop doesn't recognize your MCP server after configuration, the most common issues are:

  1. Incorrect file path: Double-check that the path to your server.py file is absolutely correct and uses the proper path separators for your operating system.
  2. Python executable: If "python" doesn't work, try "python3" or the full path to your Python executable.
  3. Virtual environment: If you're using a virtual environment (which you should be), you might need to specify the Python executable from within that environment.

Testing Your MCP Server

With both your server code written and Claude Desktop configured, it's time to test whether everything works together properly.

Starting Your Server

First, ensure your virtual environment is active, then start your MCP server:

python server.py

You should see output indicating that your server has started successfully:

Starting MCP server 'count-r' on 127.0.0.1:5000

Leave this terminal window open—your server needs to keep running for Claude Desktop to communicate with it.

Connecting Claude Desktop

Here's where you might encounter a common issue: Claude Desktop sometimes doesn't immediately recognize newly configured MCP servers. If you don't see your tool available, try these troubleshooting steps:

  1. Restart Claude Desktop completely - Close the application entirely and reopen it.
  2. If restarting doesn't work, you may need to reinstall Claude Desktop. This seems to be a known issue where the application needs a fresh start to recognize new MCP configurations.
  3. Verify server status - Check that your MCP server is still running in the terminal and hasn't crashed.

Verifying Tool Availability

Once Claude Desktop recognizes your MCP server, you'll see visual indicators of its availability:

  • A small hammer icon appears in the Claude Desktop interface
  • Clicking this icon shows "1 tool available: count-r"
  • The tool description reads "Count the number of R letters in a given word"

These indicators confirm that Claude Desktop has successfully connected to your MCP server and recognizes your custom tool.

Try It Yourself

Now for the moment of truth—let's test your custom tool:

  • In Claude Desktop, type: "Use the count-r tool to count the Rs in the word 'strawberry'"
  • Claude will ask for permission to use your tool—click "Allow for this chat"
  • Watch as Claude executes your custom tool and returns the result

You should see Claude respond with something like:
"I'll use the count-r tool to count the number of R letters in the word strawberry. The word 'strawberry' contains 3 letter Rs."

Expanding Your MCP Server Capabilities

Now that you have a working MCP server, you can expand it with additional tools or enhance existing ones. The architecture we've built is designed to accommodate growth and modifications easily.

Adding Multiple Tools

You can add as many tools as you want to a single MCP server. Each tool follows the same pattern:

@mcp.tool()
def your_new_tool(parameter: type) -> return_type:
   """Description of what your tool does."""
   try:
       # Your tool logic here
       return result
   except Exception as e:
       print(f"Error in your_new_tool: {e}")
       return default_value

Real-World Tool Ideas

Consider these practical applications for MCP servers:

Weather Integration: Create a tool that fetches current weather conditions using a weather API. This tool could accept location parameters and return formatted weather information.

Database Queries: Build tools that safely query databases and return formatted results. This is particularly useful for business applications where you need to retrieve specific data sets.

File Processing: Develop tools that process various file types—reading CSVs, parsing JSON, or extracting text from documents.

API Wrappers: Wrap existing REST APIs to make them easily accessible through Claude Desktop. This approach lets you integrate virtually any web service.

Did You Know?

The MCP ecosystem is rapidly growing, with developers creating servers for everything from calendar management to complex data analysis. The "awesome-mcp-servers" repository on GitHub (by app-cipher) contains a curated list of existing MCP servers you can use immediately, saving you development time for common functionality.

Advanced Configuration and Best Practices

As you develop more sophisticated MCP servers, certain best practices will help you create more reliable and maintainable tools.

Error Handling Strategies

Robust error handling is crucial for production MCP servers. Your tools should gracefully handle various failure scenarios:

  • Invalid input validation: Always validate inputs before processing them
  • Network timeouts: If your tool makes external API calls, implement proper timeout handling
  • Resource availability: Check that required files, databases, or services are accessible
  • Graceful degradation: Return meaningful error messages or fallback values when operations fail

Security Considerations

When building MCP servers that handle sensitive data or make external connections, consider these security practices:

  • Input sanitization: Never trust user input without validation
  • API key management: Store sensitive credentials securely, never in your source code
  • Access controls: Implement appropriate restrictions on what your tools can access
  • Logging: Maintain appropriate logs for debugging without exposing sensitive information

Performance Optimization

For tools that process large amounts of data or make multiple external calls:

  • Caching: Cache frequently requested data to reduce processing time
  • Async operations: Use asynchronous programming for I/O-bound operations
  • Resource management: Properly manage database connections, file handles, and memory usage
  • Monitoring: Track tool performance to identify bottlenecks

Troubleshooting Common Issues

Even with careful setup, you might encounter various issues when developing and deploying MCP servers. Here are solutions to the most common problems:

Server Won't Start

If your MCP server fails to start:

  1. Check your virtual environment: Ensure it's activated and the MCP library is installed
  2. Verify Python syntax: Look for syntax errors in your server.py file
  3. Port conflicts: Make sure port 5000 isn't already in use by another application
  4. Path issues: Confirm all file paths in your code are correct

Claude Desktop Can't Find Your Server

When Claude Desktop doesn't recognize your MCP server:

  1. Configuration file location: Verify you're editing the correct config file
  2. JSON syntax: Ensure your configuration JSON is valid (use a JSON validator if needed)
  3. Absolute paths: Double-check that all file paths are absolute, not relative
  4. Application restart: Try completely restarting Claude Desktop or reinstalling it

Tool Execution Errors

If your tool is recognized but fails during execution:

  1. Check server logs: Look at your terminal running the MCP server for error messages
  2. Input validation: Ensure your tool properly handles the inputs Claude Desktop sends
  3. Exception handling: Verify your try-catch blocks are working correctly
  4. Return types: Confirm your tool returns the expected data type

Key Takeaways

Remember these essential points as you continue developing MCP servers:

Architecture matters: The robust server structure we built—complete with error handling and graceful shutdown—serves as a template for all future projects.

Configuration is critical: Proper Claude Desktop configuration, including absolute file paths and correct JSON syntax, determines whether your tools work at all.

Testing is iterative: Always test your tools thoroughly, starting with simple inputs and gradually increasing complexity.

Documentation helps: Clear tool descriptions and proper type hints make your tools easier for both Claude and future developers to understand.

Conclusion: Your Journey into Custom AI Tools

You've successfully built your first MCP server and integrated it with Claude Desktop. This achievement represents more than just counting letters in words—you've mastered the fundamental concepts that enable you to create sophisticated, custom tools for AI assistants.

The skills you've developed here scale directly to more complex applications. Whether you want to integrate with weather APIs, process business data, or create specialized text analysis tools, the patterns and practices you've learned provide the foundation for any MCP server you might build.

Table of contents
Teacher
Astro
All
Astro
lessons

https://forwardfuture.ai/lessons/building-your-first-mcp-server