Project Structure

Required Python Modules

First of all, it's important to use at least Python 3.10, because FastMCP doesn't run on older versions. The project actually only requires two important libraries:

pip install FastMCP    
pip install IMAPClient

Open Architecture

Great emphasis was placed on an open and extensible structure: the server is very minimal; it simply starts the MCP server itself and registers the tools. The tools themselves are located in the “tools” module. The good thing about it is that you can very easily expand the server with additional tools, for example, to add features to the calendar.

Logging was also outsourced, as was reading the mail server configuration.

Why data classes as "models"?

The “models” module contains the data classes that describe the objects; for the tutorial, only the ‘email_summary’ model was implemented. But of course, it would be very easy to extend it to include additional objects such as “email” or a calendar entry. This makes the code easier to read. Instead of

mail[“subject”]

write

mail.subject

I like that much better. Dataclasses offer yet another advantage for our MCP server. We can easily convert them into dictionaries: from

dataclasses import asdict

return asdict(mail)

the following is automatically generated:

{
  "uid": 512,
  "subject": "Meeting",
  "sender": "max@example.com",
  "date": "...",
  "unread": true
}

This is exactly the format that the MCP server can return to Claude.

Overview

Establish The Connection

To connect Claude Desktop to a local Model Context Protocol (MCP) server, you need to add the server's execution details to the "claude_desktop_config.json" configuration file. This allows Claude to run the server locally and communicate with it directly.To add a local MCP server, follow these exact steps:

Locate or Open the Configuration File:In Claude Desktop, click the menu or press Ctrl+, (Windows/Linux) or Cmd+, (macOS) to open Settings.

Access the Developer Settings:Navigate to the Developer tab and click Edit Config. This will open claude_desktop_config.json in your default text editor.

Add Your Server Definition:Insert the server’s execution command under the "mcpServers" key.

{
  "mcpServers": {
    "IMAP MCP Server": {
      "command": "C:\\PythonEnvironments\\MCP_Server\\Scripts\\python.exe",
      "args": [
        "C:\\Users\\hager\\Schule\\6 Workspaces\\Schule\\Python\\MCP_Server\\run.py"
      ]
    }
  },
  ....

The MCP server should be available after the next restart.

Why Comments Are Key To Success

In the Model Context Protocol (MCP), special tool comments (docstrings or annotations) act as the primary user interface for the AI. They are critical because Large Language Models (LLMs) cannot execute code natively and rely entirely on these descriptions to know what a tool does, when to trigger it, and how to format the input parameters. Because agents process hundreds of tool schemas at once, unclear comments can lead to tool overload, hallucinations, and critical errors.

This example shows a method that returns a list of the most recent emails. The comment is absolutely necessary so that the LLM knows how to use the method! That's also why the comments are in German: I want to be able to communicate with the Mail Assistant in my native language.

  
     @mcp.tool()
    def list_recent_emails(count: int = 10):
        """
        Gibt die Liste der neuesten E-Mails zurück.
        Args:
            count: Anzahl der zurückzugebenden E-Mails.
        """

        mails = mail_account.list_recent_emails(count)

        return [
            asdict(mail)
            for mail in mails
        ]