MCP ExplorerExplorer

Easy Mcp Python

@ground-creativeon 9 months ago
2 MIT
FreeCommunity
AI Systems
A simple Python framework for building services with MCP servers using FastAPI.

Overview

What is Easy Mcp Python

Easy MCP Python is a simple Python framework designed to work with MCP servers, utilizing FastAPI to create services efficiently.

Use cases

Use cases include creating tools for GitHub, Google Drive, and Gmail, as well as implementing custom middleware for handling requests.

How to use

To use easy-mcp-python, clone the repository, configure environment variables, create a virtual environment, install requirements, and run the server using FastAPI or directly via MCP server commands.

Key features

Key features include a FastAPI application for service creation, support for middleware integration, and a structured approach for adding tools and functionalities.

Where to use

Easy MCP Python can be used in various fields such as web development, automation tools, and integration with Google services.

Content

Easy MCP Python

A simple python framework to work with mcp servers.

The framework uses a fastapi application to create services.

Applications

Here are few applications using the mvc container:

GitHub Tools

Google Drive Tools

Gmail Tools

Middlewares

Google oAuth

Installation

  1. Clone the repository
git clone https://github.com/ground-creative/easy-mcp-python.git
  1. Change environment variables in env.sample file and rename it to .env

  2. Create venv environment

python3 -m venv venv
source venv/bin/activate
  1. Clone the core repository:
git clone https://github.com/ground-creative/easy-mcp-core-python.git core
  1. Install requirements:
pip install -r core/requirements.txt

Run the server

To run the server you can use one of the following commands:

# Run via fastapi wrapper
python3 run.py -s fastapi

# Run the mcp server directly
python3 run.py -s fastmcp

Adding Tools

Create tools in folder app/tools. Use {function_name}_tool name convention like this example:

# app/tools/add.py

from mcp.server.fastmcp import Context      # Use `ctx: Context` as function param to get mcp context
from core.utils.state import global_state   # Use to add and read global vars
from core.utils.logger import logger        # Use to import the logger instance

def add_numbers_tool(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

Adding Middleware To MCP Server Requests

  1. Create middleware class in app/middleware folder as shown in the example:
# app/middleware/MyMiddleware.py

from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import Request
from mcp.server.fastmcp import Context      # Use `ctx: Context` as function param to get mcp context
from core.utils.logger import logger        # Use to add logging capabilities
from core.utils.state import global_state   # Use to add and read global vars

class MyMiddleware(BaseHTTPMiddleware):
    def __init__(
        self, app, *args, **kwargs
    ):
        super().__init__(app)

    async def dispatch(self, request: Request, call_next):

        """ Your code here """

        response = await call_next(request)
        return response

  1. Create app/config/app.py file if it does not exist and add your middlewares:
# app/config/app.py

MIDDLEWARE = {"mcp": [{"middleware": "app.middleware.MyMiddleware", "priority": 1}]}

Otionally, you can pass arguments to the middleware:

class MyMiddleware(BaseHTTPMiddleware):
    def __init__(
        self, app, some_arg, *args, **kwargs
    ):
        self._some_arg = some_arg
        super().__init__(app)

    async def dispatch(self, request: Request, call_next):

        """ Your code here """

        response = await call_next(request)
        return response

{
    "middleware": "app.middleware.MyMiddleware",
    "priority": 1,
    "args": {
        "some_arg": "some value"
    }
}

StartUp Hook Usage

  1. Create a hook in app/utils folder:
# app/utils/my_prestart_hook

import sqlite3
from core.utils.logger import logger        # Use to add logging capabilities
from core.utils.state import global_state   # Use to add and read global vars
from core.utils.env import EnvConfig        # Use to get env variables

def init_db(server_name):
    db_path = EnvConfig.get("DB_PATH")
    db_handler = DatabaseHandler(db_path)
    global_state.set("db_handler", db_handler)          # make db_handler available globally
    logger.info("Database initialized successfully.")
  1. Create app/config/app.py file if it does not exist and add your hooks:
# app/config/app.py

PRESTART_HOOKS = {
    "fastapi": ["app.utils.my_prestart_hook.init_db"],
}

Adding Services

  1. Create your services in app/services folder:
# app/services/my_services.py

from fastapi import APIRouter
from fastapi.responses import HTMLResponse
from core.utils.env import EnvConfig            # Use to get env variables
from core.utils.logger import logger            # Use to add logging capabilities
from core.utils.state import global_state       # use to add and read global vars

router = APIRouter()


@router.get("/my-route")
async def my_route():
    html_content = (
        f"<h1>{EnvConfig.get("SERVER_NAME")}</h1>" f"<p>Test service working</p>"
    )
    return HTMLResponse(html_content)

  1. Create app/config/app.py file if it does not exist and add your services:
SERVICES = [
    "app.services.my_services",
]

Using the server info html page:

If you want to use the server info page, create app/config/app.py file if it does not exist and add this service:

SERVICES = [
    "core.services.server_info",    # server info html page
]

# Optional, add configuration for the info server
INFO_SERVICE_CONFIG = {
    "service_uri": "/", # the uri for the info service page
    "login_url": "'Full path to authentication URL'",
    "site_url": "Full path application main site URL",
    "site_name": "Application main site name",
    "show_tools_specs": True,   # show specs for tools (name, description, parameters)
    "header_params": {}, # a set of header parameters to document in the info page. ex: {"X-ACCESS_TOKEN": "Some description"}
    "notes": [], # a list of notes for the server information
    "privacy_policy_url": "'Privacy Policy URL'"
    "terms_of_service_url": "'Terms of Service URL'"
}

# Optionally, add a logo and favicon urls to the env file

SERVICES_LOGO_URL=http://yourdomain.com/your_logo.jpg
SERVICES_FAVICON_URL=http://yourdomain.com/your_favicon.png

Server info page specs decorators

It’s possible to use decorators to add tags to tools specs and to exclude tools from the specs:

from core.utils.tools import doc_tag, doc_name

@doc_tag("Files")               # add tag for info page specs
@doc_name("Create File")        # add custom tool name for info page specs
def create_file_tool()



from core.utils.tools import doc_exclude

doc_exclude   # exclude tool from specs info page
def edit_file_tool()

Using Global Variables

To use global variables, simply import the GlobalState class:

from core.utils.state import global_state

def some_tool():
    all = global_state.get_all()
    var = global_state.get("some-var")
    global_state.set("some_var", "somevalue", True) # The last parameter edits value if key already exists when set to true

Using Environment Variables

To get environment variables added in the .env, use EnvConfig utility:

from core.utils.env import EnvConfig

var = EnvConfig.get("VARIABLE_NAME")

Using Config Variables

To get config variables added in app/config/app.py you can use the config object:

from core.utils.config import config

var = config.get("VARIABLE_NAME")

all = config.get_all()

Folder Structure

The following folder structure is expected from the core:

app/
    config/         # config folder
    middleware/     # mcp middleware
    services/       # fastapi services
    tools/          # tools folder
    templates/      # templates folder
    static/         # static folder
    utils/          # utils folder

Storage

Use the storage folder to store static data such as databases or images.

Sample Application

You can find a sample application here:

https://github.com/ground-creative/easy-mcp-python-test-app

Tools

No tools

Comments

Recommend MCP Servers

View All MCP Servers