Skip to content

v2.1.3 — MCP 会话永不过期 + 依赖/基础镜像可复现 + 容器日志修复

Latest

Choose a tag to compare

@sopyk sopyk released this 29 Oct 01:46
· 2 commits to main since this release

重点:MCP 会话不再过期(修复 transport session expired / tools 为空)

根因:fastmcp 4.1.0 起,Streamable HTTP 会话默认空闲 1800 秒就销毁(4.0.x 永不过期)。
由于依赖此前只做范围锁定,同一个 commit 在不同时间构建会装到不同 fastmcp 版本(4.0.3 / 4.1.4)——代码没改、行为变了。
长连接客户端(Hermes 等)空闲后会收到 404 Session not found,表现为 transport session expired、tools 列表为空、反复重连。

修复

  • MCP 会话永不过期:新增 core/mcp_session.py,默认 http_session_idle_timeout = None;可用 MCP_SESSION_IDLE_TIMEOUT=<秒数|none> 覆盖(想回收孤儿会话可设 86400)。
  • 依赖锁到传递依赖:requirements.txt 精确 pin + 新增 requirements.lock(71 包全锁),Docker 构建只从 lock 安装。
  • 基础镜像按 digest 固定:FROM python:3.11-alpine@sha256:79440cc1...(manifest list,含 amd64 + arm64),上游重发 tag 不再影响构建结果。
  • 容器日志 get_container_logs:tail 之前完全失效(docker-py 7.x 要求 int,传字符串会被静默降级为全量);超大日志现在按最终响应体积截断(保留末尾约 350KB + 提示),不再触发客户端 1MiB SSE 上限报错。
  • 关于页「复制」按钮:内网 HTTP(非安全上下文)下 navigator.clipboard 不存在导致按钮无反应,改为能力检测 + execCommand 兜底。
  • 静态文件路由路径穿越(安全):/ui/static/{path} 未归一化,编码后的 ..%2f 可越界读取仓库文件(如 secrets/auth.yaml);现在越界一律 404。
  • INITIAL_API_KEYS 幂等更新:已存在的同名 key 现在会按环境变量覆盖,而不是静默跳过。
  • 移除 MCP 请求级超时中间件:避免请求级超时打断长连接(SSE)会话。

升级须知

  • 容器重启会让所有 MCP 会话失效:会话表在内存中,重启后客户端会收到一次 404 Session not found(服务端日志 Rejected request with unknown or expired session ID),随后自动重新 initialize 恢复。属预期行为,不是故障。
  • Missing session ID(400)是 MCP 规范行为,需客户端保存并回传 mcp-session-id。
  • 读容器日志请用 get_container_logs(container_id, tail, since),不要 exec cat /proc/1/fd/1(会阻塞并拖死 SSE 流)。

镜像

ghcr.io/sopyk/docker-mcpilots:v2.1.3   (latest)
sopyk/docker-mcpilots:v2.1.3           (latest)
digest: sha256:fbe2926a5b75d1a41b2cd1892380d8afd69813bff575dddcf89f9795117cafc7

校验版本标签(避免拉到旧镜像):

docker image inspect ghcr.io/sopyk/docker-mcpilots:v2.1.3 \
  --format '{{index .Config.Labels "org.opencontainers.image.version"}}'
# 期望输出 2.1.3

验证

  • pytest tests/ 205 passed;scripts/audit.sh E2E 7 passed
  • 默认容器空闲 65 秒后 tools/list 仍 200(24 个工具)
  • MCP_SESSION_IDLE_TIMEOUT=2 的容器 5 秒后 404(超时路径可用)
  • tail=50 在 4 万行日志容器上恰好返回 50 行
  • 2.8MB 日志不传 tail:成功返回末尾约 350KB + 截断提示,响应 715KB(低于 1MiB 上限)
  • 标准 MCP SDK 客户端:initialize / 24 tools / list_containers / get_container_logs 全部成功
  • 实景(NAS + Hermes):enable → 24 tools → 调用成功;空闲 30 分钟后再调用,无 transport session expired