这是一个使用 FastMCP 和 Docker (Devcontainer) 高效开发基于 Python 的模型上下文协议 (MCP) 服务器的模板项目。它提供了基本 MCP 服务器功能的示例(例如,一个 add 工具和一个 greeting 资源),利用类型提示,包含 Ruff 进行静态分析和格式化,测试环境,并支持开箱即用的开发环境设置。
此仓库是一个用于 MCP 的流式就绪端到端 (E2E) 测试模板,并附带了Docker/Devcontainer 设置。
详细解释文章已发布!
appuser) 运行,增强安全性。uv 进行包管理: 使用 uv,一个快速的 Python 包安装器和解析器。Ruff 进行代码检查和格式化。pytest 和 pytest-asyncio,并带有执行环境。LOG_LEVEL 环境变量控制日志输出(例如,DEBUG、INFO、WARNING)。pyproject.toml。Dockerfile 使用 3.13-slim)uv(Python 包管理工具)从这个模板创建一个新的仓库或克隆仓库。 使用 GitHub 上的“使用此模板”按钮或如下克隆:
git clone https://github.com/akitana-airtanker/mcp-python-streamable-e2e-test-template.git <your-project-name>
cd <your-project-name>
将 <your-project-name> 替换为你的项目名称。
创建虚拟环境并安装依赖项。 在项目的根目录下运行以下命令:
uv venv
uv pip install -e ".[test,dev]" # 同时安装测试和开发依赖项
这将在 .venv 目录中创建一个虚拟环境,并根据 pyproject.toml 安装必要的包(包括测试和开发所需的包)。
此模板使用 Ruff。要本地使用它:
# 安装 Ruff(应已与开发依赖项一起安装,但可以单独安装)
# uv pip install ruff
# 检查代码
ruff check .
# 格式化代码
ruff format .
建议设置 pre-commit 钩子以自动化此过程:
pre-commit install
激活虚拟环境(如果尚未激活)。
source .venv/bin/activate
启动服务器。
mcp-server-demo
服务器将在 http://0.0.0.0:8000 启动并监听 MCP 请求。
你可以通过设置 LOG_LEVEL 环境变量来改变日志详细程度(例如,LOG_LEVEL=DEBUG mcp-server-demo)。
cd <your-project-name> # 导航到项目根目录
source .venv/bin/activate
mcp-client-demo
客户端将连接到服务器,调用 add 工具,并将结果(Result of add(10, 5): 15)打印到控制台。
你可以使用 --quiet 或 --verbose 标志控制客户端输出详细程度:
mcp-client-demo --quiet # 抑制打印语句,仅记录 WARNING 及以上级别
mcp-client-demo --verbose # 启用 DEBUG 日志记录和打印语句
也可以使用 LOG_LEVEL 环境变量设置日志级别,如果指定了 CLI 标志,则优先使用 CLI 标志。使用 VS Code Dev Containers 可以轻松设置一个包含所有必要工具和配置的一致开发环境。
前提条件:
打开开发容器:
.devcontainer/devcontainer.json 文件,并在右下角显示“重新打开在容器中”的通知。点击此通知。在容器内工作:
mcp-server-demo 和 mcp-client-demo。
# 在容器终端中启动服务器
mcp-server-demo
# 在另一个容器终端中运行客户端
mcp-client-demo
test 和 dev 额外项)通过 Dockerfile 和 devcontainer.json 中的 postCreateCommand 安装,因此当容器启动时,所有必要的包都可用。预提交钩子也已安装。Ruff 的代码检查和格式化将自动进行。appuser) 运行。http://localhost:8000/mcp(用于 MCP Inspector)。构建 Docker 镜像。 在项目的根目录下运行以下命令:
docker build -t mcp-server .
运行 Docker 容器。
docker run -p 8000:8000 -e LOG_LEVEL=DEBUG mcp-server
这将在容器内启动 MCP 服务器,并将其映射到主机上的端口 8000。可以通过传递环境变量如 -e LOG_LEVEL=DEBUG 来控制容器内服务器的日志级别。容器以非 root 用户 (appuser) 运行。
此仓库包括位于 tests/ 目录中的最小测试设置(例如,tests/test_client.py)。测试会在一个专用端口 8001(在 tests/conftest.py 中配置)上启动 FastMCP 服务器,并验证工具调用是否正确。
tests/conftest.py 固件在启动服务器进程时作为环境变量传递 MCP_SERVER_PORT=8001 给子进程。src/mcp_python_streamable_e2e_test_template/server.py 中,Config 类读取 MCP_SERVER_PORT 和 FASTMCP_PORT。如果设置了 MCP_SERVER_PORT 而未设置 FASTMCP_PORT,则 FASTMCP_PORT(由 FastMCP 使用)默认为 MCP_SERVER_PORT 的值。
# src/mcp_python_streamable_e2e_test_template/server.py
# ...
from .config import Config
cfg = Config()
if cfg.mcp_server_port and not cfg.fastmcp_port:
os.environ.setdefault("FASTMCP_PORT", cfg.mcp_server_port)
# ...
这确保了正常启动 (mcp-server-demo) 默认使用端口 8000(或设置的 FASTMCP_PORT / MCP_SERVER_PORT 的值),而pytest 执行使用端口 8001。# 假设虚拟环境已激活
pytest
如果测试通过,你会看到类似以下的输出:
collected 1 item
test_client.py . [100%]
============================= 1 passed in X.XXs =============================
无论服务器是在本地还是 Docker 中运行,都可以使用 MCP Inspector 连接到它以验证其行为。
启动 MCP Inspector。 在新的终端中运行以下命令:
npx --yes @modelcontextprotocol/inspector
连接到 MCP Inspector。 一旦 MCP Inspector 在浏览器中打开,使用以下设置连接:
Streamable HTTPhttp://localhost:8000/mcpadd 工具: 添加两个数字。
{"a": 10, "b": 5}15(作为 TextContent)greeting 资源: 返回指定名字的问候语。
greeting://World"Hello, World!"此项目采用 MIT 许可证。详情请参阅 LICENSE 文件。