功能 0:项目骨架与 /health #
0.1 新建目录 #
my-backend/
pyproject.toml
app/
__init__.py # 可为空
main.py0.2 pyproject.toml(整文件) #
可直接复用本仓库 backend/pyproject.toml:
[project]
name = "mcp-admin-backend"
version = "0.1.0"
description = "MCP 管理后台 API"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"python-multipart>=0.0.9",
"fastapi==0.115.6",
"uvicorn[standard]==0.32.1",
"sqlalchemy==2.0.36",
"pymysql==1.1.1",
"cryptography==44.0.0",
"pydantic==2.10.3",
"pydantic-settings==2.6.1",
"httpx==0.28.1",
"python-dotenv==1.0.1",
"mcp[cli]>=1.12.4",
"langchain>=1.2.13",
"langchain-deepseek>=1.0.1",
]
[tool.uv]
package = false说明:
langchain在本后端源码中未直接 import,可与生产依赖再精简;此处与现仓库保持一致。
0.3 app/main.py(整文件,仅健康检查) #
from fastapi import FastAPI
app = FastAPI(title="MCP 管理服务", version="0.1.0")
@app.get("/health")
def health():
return {"status": "ok"}0.4 安装与验收 #
cd my-backend
uv sync
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000浏览器打开 http://127.0.0.1:8000/health 应看到 {"status":"ok"}。
功能 1:配置与数据库连接 #
1.1 MySQL 建库 #
CREATE DATABASE agent CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;1.2 app/config.py(整文件) #
复制本仓库 app/config.py(含 database_url、cors_origins、upload_dir、upload_path())。
1.3 app/database.py(整文件) #
复制本仓库 app/database.py(Base、engine、SessionLocal、get_db)。
1.4 .env(与 backend/my-backend 根目录同级,勿提交 Git) #
pydantic-settings 会把 大写环境变量 映射到字段 database_url、cors_origins、upload_dir(与字段同名,仅大小写不同)。示例:
DATABASE_URL=mysql+pymysql://root:你的密码@127.0.0.1:3306/agent?charset=utf8mb4
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
UPLOAD_DIR=uploads字段语义以本仓库 app/config.py 为准;README 中若提到 .env.example,可按其上键名自建 .env。
1.5 验收 #
在 Python 里测试:
uv run python -c "from app.database import engine; print(engine.url)"无异常即可。
功能 2:数据模型(全部表) #
2.1 app/models.py(整文件) #
整文件替换为与本仓库一致的 app/models.py(含 McpService、LlmModel、Agent、AgentChatSession、AgentChatMessage)。
这一节不写业务接口,只定义 ORM。
2.2 验收 #
暂无 HTTP 验收;下一节启动时会 create_all。
功能 3:应用入口 —— 建表、CORS、注册路由占位 #
3.1 app/main.py(整文件替换为下列逻辑) #
把本仓库 app/main.py 中 除 include_router 与 uploads 挂载以外先搬过来也可以;更稳妥是分段添加:
logging、FastAPI、CORSMiddleware- `@app.on_event("startup")
里Base.metadata.create_all(bind=engine)与_ensure_agent_columns()`- 第一次实现可先不写
_ensure_agent_columns,等 Agent 字段稳定后再从仓库拷贝该函数(与现仓库一致避免老库缺列)。
- 第一次实现可先不写
GET /health- 暂不
include_router、暂不StaticFiles
本节结束时 main.py 至少包含:创建表、CORS、/health。
3.2 验收 #
启动后连接 MySQL,应出现各表(或首次为空库自动建表)。
功能 4:MCP 服务管理(CRUD + 探测) #
4.1 app/schemas.py #
在空文件或现有文件中,写入 至少 下列类(与本仓库前半部分一致):
McpProtocol枚举McpServiceBase/McpServiceCreate/McpServiceUpdate/McpServiceOutMcpTestRequest/McpTestResult
最简单:直接复制本仓库 app/schemas.py 从文件开头到 McpTestResult 结束(约第 1–92 行)。
4.2 app/repositories/mcp_repository.py(整文件) #
复制本仓库同名文件。
4.3 app/services/mcp_tester.py(整文件) #
复制本仓库同名文件(stdio / sse / streamable-http 探测)。
4.4 app/services/__init__.py #
可为空文件,保证 services 为包。
4.5 app/routers/mcp_services.py(整文件) #
复制本仓库同名文件。
4.6 app/repositories/__init__.py #
from . import mcp_repository
__all__ = ["mcp_repository"]4.7 修改 app/main.py #
from app.routers import mcp_services
app.include_router(mcp_services.router)4.8 验收 #
GET http://127.0.0.1:8000/api/mcp-services→[]POST /api/mcp-services创建一条(protocol+config合法)POST /api/mcp-services/test用真实可连的配置探测
功能 5:大语言模型管理(CRUD + 探针) #
5.1 扩展 app/schemas.py #
在 McpTestResult 之后追加(或整文件替换为本仓库完整 schemas.py 中 LLM 相关段落):
LlmModelBase/LlmModelCreate/LlmModelUpdate/LlmModelOutLlmModelTestRequest/LlmModelTestResult
推荐:本节完成后直接用本仓库完整 schemas.py 覆盖,并暂时删除尚未实现的 Agent、Chat 相关类 —— 若删除则下一节要再贴回。更省事的做法:功能 5 直接把 schemas.py 换成仓库完整版中「MCP + LLM」两段都存在,即复制 schemas.py 里从开头到 LlmModelTestResult(约至 171 行),Agent/Chat 留到功能 6、7。
5.2 app/repositories/llm_repository.py(整文件) #
复制本仓库文件。
5.3 app/routers/llm_models.py(整文件) #
复制本仓库文件(含 httpx 调 GET .../models 的 /probe)。
5.4 app/repositories/__init__.py #
from . import agent_chat_repository, agent_repository, llm_repository, mcp_repository
__all__ = ["mcp_repository", "llm_repository", "agent_repository", "agent_chat_repository"]若尚未有 agent_chat_repository、agent_repository,请改为仅:
from . import llm_repository, mcp_repository
__all__ = ["mcp_repository", "llm_repository"](等功能 6、7 再补全,与仓库一致。)
5.5 app/main.py #
若已完成功能 4,则仅追加一行 include_router(llm_models.router);不要在同一文件里重复注册 mcp_services。
from app.routers import llm_models # 与 mcp_services 等并列 import
app.include_router(llm_models.router)5.6 验收 #
列表、创建、更新、删除、/api/llm-models/probe 用真实 Key 探测。
功能 6:智能体管理 #
6.1 扩展 app/schemas.py #
追加 AgentBase / AgentCreate / AgentUpdate / AgentOut 及 _normalize_ask_variables(与仓库一致)。
6.2 app/repositories/agent_repository.py(整文件) #
复制本仓库文件。
6.3 app/routers/agents.py(整文件) #
复制本仓库文件(含 _validate_refs)。
6.4 app/repositories/__init__.py #
补全为仓库版本(含 agent_repository)。
6.5 app/main.py #
app.include_router(agents.router)6.6 验收 #
创建智能体时:错误的 llm_model_name、不存在的 mcp_service_id 应返回 400。
功能 7:对话会话与消息(非流式部分) #
7.1 扩展 app/schemas.py #
追加:
AgentChatSessionCreate/AgentChatSessionOutAgentChatMessageOut/AgentChatMessageCreateAgentChatSendRequest(流式接口也要用,可先加上)
7.2 app/repositories/agent_chat_repository.py(整文件) #
复制本仓库文件。
7.3 app/routers/agent_chat.py —— 先只放非流式路由 #
从本仓库 agent_chat.py 复制下列路由即可:
GET/POST /api/agents/{agent_id}/chat-sessionsDELETE /api/agent-chat-sessions/{session_id}GET/POST /api/agent-chat-sessions/{session_id}/messages
暂时不要复制 POST .../messages/stream 与文件顶部的 generate_with_tools 导入。
7.4 app/repositories/__init__.py #
补全 agent_chat_repository。
7.5 app/main.py #
app.include_router(agent_chat.router)7.6 验收 #
创建会话、拉消息、POST 一条 user 消息存库。
功能 8:流式对话 + MCP 工具(核心服务层) #
8.1 app/services/agent_chat.py(整文件) #
整文件复制本仓库 app/services/agent_chat.py(约 560+ 行)。
其中包含:httpx 调 OpenAI 兼容 chat/completions、MCP 三协议连工具、generate_with_tools / stream_final_answer。
8.2 补全 app/routers/agent_chat.py #
在上一节文件基础上:
- 增加 import:
asyncio、json、AsyncGenerator、StreamingResponse、generate_with_tools、stream_final_answer - 整段追加本仓库中
stream_message路由及辅助函数_build_session_title_from_question、_split_text_for_stream
最简单:将 app/routers/agent_chat.py 整文件替换为本仓库最终版。
8.3 验收 #
- 对
POST /api/agent-chat-sessions/{id}/messages/stream使用curl或前端,观察 SSEdata:行。 - 智能体绑定 MCP 后,对话中应出现
tool_start/tool_end事件(视模型是否发起工具调用而定)。
功能 9:图片上传与静态访问 #
9.1 app/routers/uploads.py(整文件) #
复制本仓库文件。
9.2 app/main.py #
在 include_router(uploads.router) 之后:
upload_root = settings.upload_path()
upload_root.mkdir(parents=True, exist_ok=True)
app.mount("/uploads", StaticFiles(directory=str(upload_root)), name="uploads")并确保顶部有 StaticFiles 与 uploads 路由引入(与本仓库 main.py 一致)。
9.3 验收 #
POST /api/uploads/image(multipart)返回 /uploads/xxx;浏览器访问 http://127.0.0.1:8000/uploads/xxx。
功能 10:与线上一致的最后补丁 #
10.1 _ensure_agent_columns #
将本仓库 main.py 中 _ensure_agent_columns 及 on_startup 里对它的调用合并进你的 main.py,避免旧数据库缺列导致 Agent 读写失败。
10.2 根目录 main.py(可选) #
复制本仓库 backend/main.py(与 app 包同级),用于执行:
uv run main.py等价于 uvicorn app.main:app --reload --host 0.0.0.0 --port 8000。
10.3 最终 schemas.py、models.py、main.py #
务必与本仓库逐文件对比,确保:
schemas.py:Ask 变量规范化、Chat 请求体等与线上一致。models.py:字段齐全。main.py:路由顺序、挂载顺序与线上一致(先 API 再/uploads)。
附录 A:一键同步源码(等价实现) #
若你已跟做到 功能 7 之前,希望直接对齐现仓库,可在 backend 目录执行(自行备份):
git checkout -- app/或手动将下列路径 整体覆盖为仓库版本:
app/config.py
app/database.py
app/models.py
app/schemas.py
app/main.py
app/repositories/*.py
app/routers/*.py
app/services/*.py附录 B:全功能自检清单 #
| 功能 | 方法 | 预期 |
|---|---|---|
| 健康 | GET /health |
ok |
| MCP | CRUD + POST /api/mcp-services/test |
200/409 符合预期 |
| LLM | CRUD + /api/llm-models/probe |
返回模型列表或明确失败 |
| 智能体 | CRUD | 外键校验 400 |
| 会话 | 列表/创建/删除 | 会话存在于 DB |
| 消息 | 列表/创建 | 消息落库 |
| 流式 | POST .../messages/stream |
SSE 有 start/delta/done |
| 上传 | POST /api/uploads/image |
返回路径且可 GET |
附录 C:教程与「概念导读」的关系 #
仓库中另有 新手教程-分步搭建后端.md,偏结构说明与读码顺序。
本文偏按功能落地代码。建议两文一起看:概念不清时翻到导读,动手时以本文为准。
完成标志:上述自检全部通过,且 app/ 与仓库 diff 仅为本地配置或无关紧要的格式差异。