返回市场
MCP服务器模板

MCP服务器模板

作者:shubhamgupta-dat3 星标更新:2025-04-15

项目介绍

MCP Server Cookiecutter 模板

一个全面的 Cookiecutter 模板,用于使用 Python 创建 Model Context Protocol (MCP) 服务器。

什么是 MCP?

Model Context Protocol (MCP) 是一个开放标准,允许应用程序以标准化的方式为大型语言模型(如 Claude)提供上下文。MCP 服务器可以暴露:

  • 工具:LLM 可执行的功能来执行操作
  • 资源:LLM 可访问的数据源以获取上下文
  • 提示:可重复使用的模板,用于与 LLM 的交互

特性

  • 🚀 完整的项目结构,所有必要的组件都已预配置
  • 🔧 工具、资源和提示的示例实现
  • 📦 与 FastMCP 集成,支持基于装饰器的简单开发
  • 🧩 生命周期管理,包括适当的资源初始化和清理
  • 🐍 现代 Python 实践,包括类型提示和文档
  • 🛠️ 开发工具,包括 Makefile、测试和类型检查
  • 🐋 Docker 支持,用于容器化部署
  • 🔌 与 Claude Desktop 集成,无缝测试与 Claude

快速开始

要求

  • Python 3.12+
  • Cookiecutter

创建项目

# 如果需要,请安装 cookiecutter
pip install cookiecutter

# 从模板生成一个新的 MCP 服务器项目
cookiecutter gh:shubhamgupta-dat/mcp-server-cookiecutter

# 或者从本地副本生成
cookiecutter path/to/mcp-server-cookiecutter

开始使用你的新服务器

# 导航到你的新项目
cd your-project-name

# 设置环境(底层使用 uv)
make setup

# 激活虚拟环境
source .venv/bin/activate  # 在 Unix/MacOS 上
# 或者
.venv\Scripts\activate     # 在 Windows 上

# 使用 MCP Inspector 在开发模式下运行服务器
make dev

# 在 Claude Desktop 中安装服务器(用于本地测试)
make install

文件结构

mcp-server-template/
├── cookiecutter.json
└── {{cookiecutter.project_name}}/
    ├── README.md
    ├── Makefile
    ├── Dockerfile
    ├── .gitignore
    ├── pyproject.toml
    └── {{cookiecutter.module_name}}/
        ├── __init__.py
        ├── server.py
        ├── config.py
        ├── tools/
        │   ├── __init__.py
        │   └── sample_tools.py
        ├── resources/
        │   ├── __init__.py
        │   └── sample_resources.py
        └── prompts/
            ├── __init__.py
            └── sample_prompts.py

文件内容

cookiecutter.json

{
  "project_name": "mcp-server",
  "module_name": "{{ cookiecutter.project_name.lower().replace('-', '_') }}",
  "project_description": "一个 Model Context Protocol (MCP) 服务器",
  "author_name": "你的名字",
  "author_email": "your.email@example.com",
  "version": "0.1.0",
  "python_version": "3.10"
}

{{cookiecutter.project_name}}/README.md

# {{cookiecutter.project_name}}

{{cookiecutter.project_description}}

## 概述

这是一个 Model Context Protocol (MCP) 服务器,它暴露了工具、资源和提示,用于与像 Claude 这样的 LLM 应用程序交互。MCP 服务器让你能够通过自定义功能、数据源和模板化的交互来扩展 AI 应用程序。

## 快速开始

### 使用 uv 设置(推荐)

```bash
# 设置环境
make setup

# 激活虚拟环境
source .venv/bin/activate  # 在 Unix/MacOS 上
# 或者
.venv\Scripts\activate     # 在 Windows 上

# 使用 MCP Inspector 在开发模式下运行服务器
make dev

# 在 Claude Desktop 中安装服务器
make install

手动设置

# 如果没有安装 uv,请先安装
pip install uv

# 创建虚拟环境
uv venv

# 激活虚拟环境
source .venv/bin/activate  # 在 Unix/MacOS 上
# 或者
.venv\Scripts\activate     # 在 Windows 上

# 以开发模式安装包
uv pip install -e .

# 在开发模式下运行
mcp dev {{cookiecutter.module_name}}.server

# 在 Claude Desktop 中安装
mcp install {{cookiecutter.module_name}}.server

Docker

使用 Docker 构建和运行:

# 构建 Docker 镜像
make docker-build
# 或者
docker build -t {{cookiecutter.project_name}} .

# 运行容器
make docker-run
# 或者
docker run -p 8000:8000 {{cookiecutter.project_name}}

服务器架构

服务器组织成几个组件:

  • server.py:主要的 MCP 服务器设置和配置
  • config.py:配置管理
  • tools/:工具实现(LLM 可执行的功能)
  • resources/:资源实现(LLM 可访问的数据)
  • prompts/:提示模板实现(可重复使用的对话模板)

MCP 功能

此服务器实现了所有三个 MCP 原语:

  1. 工具:LLM 可调用的功能来执行操作

    • 示例:calculatefetch_datalong_task
  2. 资源:提供上下文给 LLM 的数据源

    • 示例:static://exampledynamic://{parameter}config://{section}
  3. 提示:用于 LLM 交互的可重复使用模板

    • 示例:simple_promptstructured_promptdata_analysis_prompt

添加自己的组件

添加新的工具

tools/ 目录中创建或修改文件:

@mcp.tool()
def my_custom_tool(param1: str, param2: int = 42) -> str:
    """
    一个有用的自定义工具。
    
    参数:
        param1: 第一个参数的描述
        param2: 第二个参数的描述,默认值为 42
        
    返回:
        返回值的描述
    """
    # 你的实现代码
    return f"结果: {param1}, {param2}"

添加新的资源

resources/ 目录中创建或修改文件:

@mcp.resource("my-custom-resource://{param}")
def my_custom_resource(param: str) -> str:
    """
    提供有用数据的自定义资源。
    
    参数:
        param: 参数的描述
        
    返回:
        资源内容
    """
    # 你的实现代码
    return f"资源内容为: {param}"

添加新的提示

prompts/ 目录中创建或修改文件:

@mcp.prompt()
def my_custom_prompt(param: str) -> str:
    """
    自定义提示模板。
    
    参数:
        param: 参数的描述
        
    返回:
        格式化的提示
    """
    return f"""
    # 自定义提示模板
    
    上下文: {param}
    
    请根据上述上下文进行分析并回复。
    """

配置

服务器支持通过以下方式配置:

  1. 环境变量:前缀为 MCP_(例如,MCP_API_KEY=xyz123

    • 嵌套配置:使用双下划线(MCP_DATABASE__HOST=localhost
  2. 配置文件:通过 MCP_CONFIG_FILE 环境变量指定

示例配置:

{
  "api": {
    "key": "xyz123",
    "url": "https://api.example.com"
  },
  "database": {
    "host": "localhost",
    "port":  5432
  }
}

开发

# 运行测试
make test

# 格式化代码
make format

# 类型检查
make type-check

# 清理构建工件
make clean

许可证

[在此处包含你的许可证信息]


### {{cookiecutter.project_name}}/Makefile

```makefile
.PHONY: setup run dev install deploy test clean format type-check

# 从 cookiecutter 或默认为 3.10 设置 Python 版本
PYTHON_VERSION := {{cookiecutter.python_version}}

# 使用 uv 设置
setup:
	# 检查是否已安装 uv,如果没有则安装
	@which uv >/dev/null || pip install uv
	# 创建虚拟环境
	uv venv
	# 安装带有开发额外项的依赖
	uv pip install -e ".[dev]"
	@echo "✅ 环境设置完成。激活它使用 'source .venv/bin/activate' (Unix/macOS) 或 '.venv\\Scripts\\activate' (Windows)"

# 直接运行服务器
run:
	python -m {{cookiecutter.module_name}}.server

# 使用 MCP inspector 在开发模式下运行
dev:
	mcp dev {{cookiecutter.module_name}}.server

# 在 Claude Desktop 中安装
install:
	mcp install {{cookiecutter.module_name}}.server

# 运行测试
test:
	pytest

# 使用 black 和 isort 格式化代码
format:
	black {{cookiecutter.module_name}}
	isort {{cookiecutter.module_name}}

# 使用 mypy 进行类型检查
type-check:
	mypy {{cookiecutter.module_name}}

# 清理构建工件
clean:
	rm -rf build/
	rm -rf dist/
	rm -rf *.egg-info/
	find . -type d -name __pycache__ -exec rm -rf {} +
	find . -type f -name "*.pyc" -delete

# Docker 构建
docker-build:
	docker build -t {{cookiecutter.project_name}}:latest .

# 使用 Docker 运行
docker-run:
	docker run -p 8000:8000 {{cookiecutter.project_name}}:latest

{{cookiecutter.project_name}}/Dockerfile

# 使用特定版本的 Python
FROM python:{{cookiecutter.python_version}}-slim AS builder

# 设置构建参数
ARG APP_USER=mcp
ARG APP_UID=1000
ARG APP_GID=1000

# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 设置应用用户
RUN groupadd -g $APP_GID $APP_USER && \
    useradd -m -u $APP_UID -g $APP_GID -s /bin/bash $APP_USER

# 设置工作目录
WORKDIR /app

# 安装 uv 用于依赖管理
RUN pip install --no-cache-dir uv

# 复制项目文件
COPY pyproject.toml README.md ./

# 复制应用代码
COPY {{cookiecutter.module_name}} ./{{cookiecutter.module_name}}

# 以开发模式安装应用
RUN uv pip install --no-cache-dir -e .

# 切换到更小的最终镜像
FROM python:{{cookiecutter.python_version}}-slim

# 从构建器复制
COPY --from=builder /usr/local/lib/python{{cookiecutter.python_version}}/site-packages /usr/local/lib/python{{cookiecutter.python_version}}/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /app /app

# 设置工作目录
WORKDIR /app

# 设置环境变量
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV MCP_ENV=production

# 暴露端口用于基于 HTTP 的传输(SSE)
EXPOSE 8000

# 使用生产传输(SSE)运行服务器
CMD ["python", "-m", "{{cookiecutter.module_name}}.server"]

{{cookiecutter.project_name}}/.gitignore

# Python 字节码
__pycache__/
*.py[cod]
*$py.class
*.so
.Python

# 分发/打包
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# 虚拟环境
venv/
env/
ENV/
.venv/
.env/

# 单元测试/覆盖率报告
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
pytest_cache/

# 编辑器文件
.idea/
.vscode/
*.swp
*.swo
*~

# 操作系统特定
.DS_Store
Thumbs.db

# 项目特定
*.log
.env
.env.*
!.env.example

# MCP 特定
claude_desktop_config.json

{{cookiecutter.project_name}}/pyproject.toml

[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "{{cookiecutter.project_name}}"
version = "{{cookiecutter.version}}"
description = "{{cookiecutter.project_description}}"
authors = [
    {name = "{{cookiecutter.author_name}}", email = "{{cookiecutter.author_email}}"},
]
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
    "mcp>=1.0",
    "httpx>=0.24.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0",
    "black>=23.0",
    "isort>=5.0",
    "mypy>=1.0",
    "ruff>=0.2.0",
]

[tool.setuptools]
packages = ["{{cookiecutter.module_name}}"]

[tool.black]
line-length = 88
target-version = ["py310"]

[tool.isort]
profile = "black"
line_length = 88

[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true

[tool.ruff]
line-length = 88
target-version = "py310"
select = ["E", "F", "I"]

{{cookiecutter.module_name}}/init.py

"""{{cookiecutter.project_description}}"""

__version__ = "{{cookiecutter.version}}"

{{cookiecutter.module_name}}/server.py

"""
主要的 MCP 服务器实现。
此文件初始化 FastMCP 服务器,并导入所有工具、资源和提示。
"""

from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
from dataclasses import dataclass

from mcp.server.fastmcp import Context, FastMCP

# 导入配置管理
from .config import load_config


@dataclass
class AppContext:
    """
    类型安全的应用程序上下文容器。
    在这里存储任何全局状态或连接。
    """
    config: dict


@asynccontextmanager
async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
    """
    应用程序生命周期管理器。
    处理启动和关闭操作,具有正确的资源管理。
    
    参数:
        server: FastMCP 服务器实例
        
    产生:
        初始化资源的应用程序上下文
    """
    # 加载配置
    config = load_config()
    
    # 初始化连接和资源
    print("🚀 服务器正在启动...")
    
    try:
        # 创建并产生应用程序上下文
        yield AppContext(config=config)
    finally:
        # 关闭时清理资源
        print("🛑 服务器正在关闭...")


# 创建具有生命周期支持的 MCP 服务器
mcp = FastMCP(
    "{{cookiecutter.project_name}}",  # 服务器名称
    lifespan=app_lifespan,           # 生命周期管理器
    dependencies=["mcp>=1.0"],       # 必需的依赖项
)

# 导入所有工具、资源和提示
# 这些导入必须在初始化 MCP 服务器之后进行
from .tools.sample_tools import *
from .resources.sample_resources import *
from .prompts.sample_prompts import *

# 将服务器实例提供给其他模块
server = mcp

if __name__ == "__main__":
    # 当直接执行时,运行服务器
    mcp.run()

{{cookiecutter.module_name}}/config.py

"""
MCP 服务器的配置管理。
处理从环境变量和/或配置文件加载配置。
"""

import os
import json
from pathlib import Path
from typing import Dict, Any, Optional


def load_config(config_path: Optional[str] = None) -> Dict[str, Any]:
    """
    从环境变量和/或配置文件加载配置。
    
    前缀为 MCP_ 的环境变量会自动包含在配置中(移除前缀并转换为小写)。
    
    参数:
        config_path: 可选的 JSON 配置文件路径
        
    返回:
        包含配置值的字典
    """
    # 从空配置开始
    config = {
        "server": {
            "name": "{{cookiecutter.project_name}}",
            "version": "{{cookiecutter.version}}"
        }
    }
    
    # 如果提供了文件路径,则加载
    if config_path:
        config_file = Path(config_path)
        if config_file.exists():
            try:
                with open(config_file, 'r') as f:
                    file_config = json.load(f)
                    # 深度合并配置
                    _deep_merge(config, file_config)
            except Exception as e:
                print(f"警告:无法加载配置文件:{e}")
    
    # 还检查环境中的配置文件路径
    env_config_path = os.environ.get("MCP_CONFIG_FILE")
    if env_config_path and env_config_path != config_path:
        try:
            with open