使用说明
MCP服务器模板
一种通用的、可生产的建筑脚手架 模型上下文协议(MCP) 使用Python和 FastMCP.
此模板保留了真实生产MCP服务器的架构、模式和最佳实践,去掉了所有特定于域的代码,这样您就可以分叉并构建自己的代码。
它也作为一个 入职培训项目 和一个 编码代理的参考代码库 (例如克劳德、光标、副驾驶)。结构、内联注释和文档都是有意设计的,这样AI代理就可以读取代码库,理解约定,并在没有人工干预的情况下快速构建新的工具、工作流程和包。
建筑
mcp-template/
├── packages/
│ ├── equator/ # Prompt-toolkit TUI foundation — base layer for all terminal UIs
│ ├── beetle/ # Live log interpreter — ingests logs, explains them with a local LLM
│ ├── tropical/ # MCP protocol inspector — browse tools, resources, and prompts
│ ├── lab_mouse/ # Pydantic-AI agent REPL — tests whether the LLM uses your tools correctly
│ └── mcp_shared/ # Shared utilities (response builders, schemas, logging)
├── mcp_server/ # Main MCP Server
│ └── src/mcp_server/
│ ├── __main__.py # Server entry point
│ ├── instructions/ # Agent instructions (4-layer framework)
│ ├── tool_box/ # Tool registration + _tools_template reference
│ └── workflows/ # Multi-step workflow orchestration
├── tests/
│ ├── unit/ # Unit tests for packages
│ └── agentic/ # Agentic integration tests (requires running server)
├── start.py # One-command startup: mcp_server + lab_mouse
└── docs/ # Architecture and best practices documentation
关键设计决策
mcp_shared--所有工具都使用共享响应构建器(SummaryResponse,ErrorResponse)以及ResponseFormat枚举来控制输出的详细程度和令牌的使用。_tools_template--一个完全注释的参考实现。每个架构决策都是内联记录的。在创建第一个工具之前,请阅读此内容。- Docstring注册表 --工具描述与逻辑分开进行版本控制,实现了A/B测试和提示工程,而无需触及业务逻辑。
- 工具名称注册表 --所有工具名称都是常量。无内联字符串——允许在其他工具响应中建议工具调用。
快速入门
先决条件
1.安装
git clone <your-repo-url> mcp-template
cd mcp-template
uv sync --all-packages
2.拉动Olama车型
两者 实验室 和 甲虫 通过Ollama在 http://localhost:11434 (标准Ollama端口——如果Ollama正常安装,则无需配置)。
| Agent | 用途 | 默认型号 | 推荐 |
|---|---|---|---|
| 实验室 | 代理REPL——调用MCP工具,原因多于结果 | phi4-mini:3.8b |
qwen3:4b |
| 甲虫 | 日志解释器——讲述实时日志输出 | phi4-mini:3.8b |
phi4-mini:3.8b |
# Minimum — default model for both agents
ollama pull phi4-mini:3.8b
# Recommended — better reasoning for lab_mouse
ollama pull qwen3:4b
# Low-memory alternative
ollama pull qwen3:1.7b
为中的每个代理设置模型 .env (或作为环境变量):
AGENT_MODEL=ollama:qwen3:4b # lab_mouse (default: ollama:phi4-mini:3.8b)
BEETLE_MODEL=ollama:phi4-mini:3.8b # beetle (default: ollama:phi4-mini:3.8b)
# Only needed if Ollama is NOT on the default port (11434)
# OLLAMA_BASE_URL=http://localhost:11434
使用云模型而不是Ollama? 集
AGENT_MODEL对任何 pydantic ai模型串 并添加相应的API密钥。在这种情况下,实验室不需要Ollama。
供应商 AGENT_MODEL示例API密钥env var 谷歌双子座 google-gla:gemini-2.0-flashGEMINI_API_KEY人类学 anthropic:claude-sonnet-4-6ANTHROPIC_API_KEYOpenAI openai:gpt-4oOPENAI_API_KEY
3.配置环境
cp .env.sample .env
# Edit .env — at minimum set AGENT_MODEL if not using the default
4.开始一切
一个命令 --在新终端中启动mcp_server,等待它准备就绪,然后启动lab_mouse:
uv run python start.py
或者分别启动它们:
# Terminal 1
uv run mcp_server
# Terminal 2 (once the server is ready)
uv run lab_mouse
健康检查:
curl http://127.0.0.1:8000/healthcheck
# → OK
5.使用甲虫(可选)
在lab_mouse内部,键入 /beetle 在一个新的终端中打开甲虫,预装当前日志并连接实时转发。
赤道TUI指南
所有终端应用程序-- 实验室 和 甲虫 --共享相同的TUI 赤道.
布局
┌──────────────────────── lab_mouse ─────────────────────────┐
│ │
│ Conversation history │
│ │
│ ▏ ((o)) what sections does the resume have? │
│ │
│ ▏ ))o(( ⚙ md_list_sections(document="RESUME")… │
│ ▏ ))o(( ⚙ md_list_sections… ✓ 8 sections found │
│ ▏ ))o(( I found 8 sections: Summary, Experience, … │
│ │
├─────────────────────────────────────────────────────────────┤
│ AGENT · 312 chars │
│ Preview: I found 8 sections: Summary, Experience, … │
│ Tools: 1/1 completed F2 inspect │
├─────────────────────────────────────────────────────────────┤
│ [INF] httpx: POST /mcp 200 │
│ [DBG] mcp: tool result received │
├─────────────────────────────────────────────────────────────┤
│ > type here │
│ │
├─────────────────────────────────────────────────────────────┤
│ ollama:qwen3:4b | MCP: ✓ | ●DBG ●INF ●WRN ●ERR ●CRT │
│ Context ████░░░░░░░░░░░░░░░░░░ 4,200 / 32,768 (13%) │
│ TAB = toggle help │
└─────────────────────────────────────────────────────────────┘
视觉识别:
| 符号 | 含义 |
|---|---|
((o)) |
您(用户) |
))o(( |
代理人 |
=){ |
甲虫 |
按键绑定
| 关键 | 行动 |
|---|---|
Enter |
发送消息 |
Esc+Enter |
插入换行符 |
↑ / ↓ |
浏览对话历史记录(当输入为空时) |
↑ / ↓ |
滚动检查器内容(处于扩展检查模式时) |
Esc |
清除消息光标(返回自动跟随) |
Ctrl+O |
切换日志面板 |
Shift+Tab |
切换内部日志面板 |
← / → |
浏览日志(当日志面板打开时) |
← / → |
循环工具调用(当选择消息时) |
F2 |
切换检查/细节展开 |
Tab |
切换帮助侧栏 |
↑ / ↓ |
导航模型选择器(打开时) |
Enter |
确认型号选择 |
Esc |
取消型号选择器 |
Ctrl+X |
退出 |
斜杠命令
键入任意 /command 在输入中。选项卡完成可用。
通用(实验室+甲虫):
| 命令 | 描述 |
|---|---|
/help |
在日志面板中显示键绑定和所有命令 |
/logs |
显示当前活动日志级别 |
/logs err crt |
仅显示ERR和CRT |
/logs all |
启用所有五个级别(启动时默认) |
/logs none |
静音所有级别 |
/clear |
清除对话历史记录 |
/clearlogs |
清除日志面板 |
/q |
退出 |
仅限lab_mouse:
| 命令 | 描述 |
|---|---|
/beetle |
在具有实时日志转发功能的新终端中启动甲虫 |
/tropical |
打开热带检查器,自动连接到活动的MCP服务器 |
/tropical <url> |
打开连接到特定URL的热带 |
/tools |
列出连接的MCP服务器中的工具 |
/model <name> |
内联切换模型——例如。 /model ollama:qwen3:4b |
日志级别
状态栏显示哪些级别处于活动状态(填充点=打开,空=关闭)。默认情况下,所有级别都处于打开状态。
●DBG ●INF ●WRN ●ERR ●CRT
检查模式(F2)
当选择消息时(↑ / ↓):
- 紧凑:消息下方显示了一行摘要——角色、时间、工具计数。
- 扩展的 (按
F2):完整的工具参数+JSON语法高亮显示的结果。← / →在同一转弯内循环工具调用。↑ / ↓滚动浏览长长的检查器内容。F2再次坍塌;Esc完全清除选择。
开发者工具链
赤道——TUI基金会
共享提示工具包库 beetle 和 lab_mouse 不是一个独立的工具,而是一个库。如果您想将自己的pydantic ai代理包装在完整的终端界面中,请直接使用它:
import equator
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP
agent = Agent("openai:gpt-4o", toolsets=[MCPServerStreamableHTTP("http://localhost:8000/mcp")])
equator.run(agent, name="my-tester")
下层(protocol.py, state.py, components/)没有pydantic ai依赖关系——任何实现的异步后端 SessionProtocol 可以驾驶TUI。 beetle 使用此功能可以使用相同的渲染基础架构运行完全不同的会话类型。
自定义命令通过以下方式注册 CommandRegistry 并传递给 equator.run().三种: ACTION (执行TUI侧逻辑), PROMPT (预先填充输入框), SCRIPT (向代理发送固定消息)。
看 packages/equator/README.md 以获取完整参考。
甲虫——实时日志解释器
使用全屏TUI包装任何Python进程,该TUI通过TCP接收日志,并使用本地LLM以普通语言解释它们。不需要API密钥-在上运行 奥拉玛.
uv run beetle # listens on localhost:9020
将应用程序与内置处理程序连接起来:
from beetle.log_server import BeetleHandler
import logging
logging.getLogger().addHandler(BeetleHandler())
或者,如果你不想使用零依赖代码段 beetle 作为项目依赖关系:
import json, socket, logging
class BeetleHandler(logging.Handler):
def __init__(self, host="localhost", port=9020):
super().__init__()
self._sock = socket.create_connection((host, port))
def emit(self, record):
import traceback
exc = traceback.format_exc() if record.exc_info else None
data = json.dumps({
"level": record.levelno, "name": record.name,
"msg": record.getMessage(), "exc": exc,
}) + "\n"
try:
self._sock.sendall(data.encode())
except OSError:
self.handleError(record)
logging.getLogger().addHandler(BeetleHandler())
选项:
beetle --port 9021 # custom port (default: 9020)
beetle --logs ./app.log # pre-load a log file on startup
beetle --no-server # disable TCP listener (static analysis)
cat app.log | beetle # pipe mode
BEETLE_MODEL=ollama:phi4-mini:3.8b # interpreter model (default: ollama:phi4-mini:3.8b)
看 packages/beetle/README.md 以获取完整参考。
热带MCP协议检查员
用于原始MCP协议检查的全屏TUI。浏览工具、资源和提示;执行请求;使用语法高亮显示和标记渲染查看响应。不需要API键。
uv run tropical # standalone
uv run tropical connect-http http://localhost:8000/mcp # connect directly
uv run tropical connect-http http://localhost:8000/mcp --header "Authorization=Bearer <token>"
支持STDIO、HTTP(流式传输)和TCP传输。服务器配置持续存在 ~/.config/tropical/servers.yaml.
lab_mouse--代理REPL
连接到MCP服务器的交互式终端代理。测试LLM是否真正正确使用了您的工具,而不仅仅是工具是否返回了正确的数据。
uv run python start.py # starts both mcp_server and lab_mouse
或手动:
uv run mcp_server # Terminal 1
uv run lab_mouse # Terminal 2
运行测试
uv run pytest
代理测试需要一个正在运行的服务器:
# Terminal 1: start the server
uv run mcp_server
# Terminal 2: run agentic tests
uv run pytest tests/agentic/ -v
覆盖率阈值:80%(在CI中强制执行)。
如何创建新工具
-
创建功能文件夹 在...之下
mcp_server/src/mcp_server/tool_box/:tool_box/ └── my_feature/ ├── __init__.py ├── tools.py # add_tool(mcp) function ├── schemas.py # Pydantic input/output models ├── tool_names.py # ToolNames constants └── docstrings/ ├── __init__.py # DOCSTRINGS registry └── my_tool_docs.py -
使用
_tools_template/tools.py作为您的参考 --每个架构决策都有注释。 -
注册您的工具 在
tool_box/__init__.py:from .my_feature.tools import add_tool as add_my_feature_tool def register_all_tools(mcp): add_template_tool(mcp) add_my_feature_tool(mcp) # ← add here -
添加您的工具名称 根本
ToolNames注册表在tool_box/tool_names.py.
如何编写有效的工具文档字符串
看 docs/TOOLS_BEST_PRACTICES.md 完整的指南。关键原则:
- 一切都很迅速 --函数名、参数名、文档字符串和响应都会影响代理行为。
- 例如合同 --向代理人展示成功是什么样子的;它将遵循这种模式。
- 平面参数>嵌套 --代理在深度嵌套的输入中挣扎;更喜欢扁平的Pydantic模型。
- ResponseFormat枚举 --让代理控制输出冗长程度,以管理令牌预算。
- 代币预算 --在编写工具之前,为每个工具分配一个最大的令牌预算。
如何编写代理指令
看 docs/MCP_INSTRUCTIONS_FRAMEWORK.md 对于4层框架:
- 心智模型 --领域特定解释透镜
- 类别 --互斥用例分类槽
- 程序性知识 --按类别划分的工具链和护栏
- 示例 --很少射击意图→ 行动示威
编辑 mcp_server/src/mcp_server/instructions/instructions.py 用您的域说明替换通用模板。
VS代码调试
添加 .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "MCP Server",
"type": "python",
"request": "launch",
"module": "mcp_server",
"justMyCode": false,
"env": {
"PYTHONPATH": "${workspaceFolder}/mcp_server/src:${workspaceFolder}/packages/mcp_shared/src"
}
}
]
}
文档
| 文档 | 描述 |
|---|---|
| docs/TOOLS_BEST_PRACTICS.md | 设计MCP工具的最佳实践 |
| docs/MCP_结构_框架.md | 4层代理指令设计框架 |
| docs/WORKSPACES.md | UV工作空间机制和包管理 |
| docs/PACKAGES.md | 创建和使用工作空间包 |
| docs/PYTHON.md | Python和UV外部资源 |
| 软件包/赤道/README.md | 赤道全参考 |
| 软件包/bittel/README.md | 甲虫完整参考 |
