news 2026/11/3 19:10:56

Strata MCP 服务器源码解析:9 个工具让 AI 助手替你装、跑、停本地大模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Strata MCP 服务器源码解析:9 个工具让 AI 助手替你装、跑、停本地大模型

Strata MCP 服务器源码解析:9 个工具让 AI 助手替你装、跑、停本地大模型

【免费下载链接】StrataQwen3.8-Flash-Next on any consumer hardware: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, optional image input.项目地址: https://gitcode.com/gh_mirrors/strata11/Strata

Strata 的 tools/strata_mcp.py 是一个基于 Python 标准库的 MCP(Model Context Protocol)服务器:把它注册进 Claude Code、Cursor、VS Code 或 Codex CLI 之后,"帮我装个 Strata""Strata 跑起来了吗"这类自然语言请求,会被 AI 助手翻译成对这个服务器里 9 个工具的调用——安装、启动、停止、查状态、看日志、跑测速,全程不用你碰终端。本文从源码层面拆解它怎么做到的:两条阶段式安装/停止时序、一套"PID+启动时间"的进程防误杀机制,以及它在参数、路径、网络上划下的安全线。

它是什么,又不是什么

一句话定位:它是给你正在用的 AI 助手调用的 MCP 服务器,替你管理 Strata 本体(一个把 Qwen3.8-Flash-Next 这类 MoE 模型跑在消费级显卡+内存上、在127.0.0.1:8080提供 OpenAI/Anthropic 兼容 API 的本地推理服务)。

先澄清一个极易混淆的方向问题。仓库里有两个都叫 "MCP" 的东西:serve/mcp.py 是Strata 模型自己当 MCP客户端——模型在聊天页里调用你配置的第三方工具;而 tools/strata_mcp.py 是反方向,它是个 MCP服务器,服务对象是外部 AI 助手。文件头部注释(L19-L20)和 docs/MCP_SERVER.md 都专门写了这一句"Not to be confused",防止两件事搅在一起。

工程上有三个直接决定代码形态的特性:

  • 纯标准库。只用argparse、json、subprocess、urllib、threading,Windows 下加ctypes。原因很实际:它必须在setup.py创建.venv之前就能运行,所以不能用任何 pip 包。入口(main,L2705-L2721)会检查sys.version_info < (3, 10)并直接以退出码 2 拒绝,Windows 上还要求 64 位。
  • stdio 传输的 JSON-RPC 2.0,每条消息一行 JSON。main里先抓住sys.stdout.buffer作为协议输出,再把sys.stdout重定向到stderr(L2722-L2723)——任何杂散print都不可能污染协议流,诊断信息一律走stderr的log()。
  • 工具调用跑在独立线程。serve循环(L2611-L2633)对tools/call和批量请求起守护线程,于是模型加载那 1~3 分钟里,ping和其他状态查询依然能被及时应答。

五分钟接上你的 AI 助手

前提是有一份仓库副本(git clone https://gitcode.com/gh_mirrors/strata11/Strata),下文以/home/you/Strata(Linux)/C:\Users\you\Strata(Windows)指代。挑三个有代表性的客户端:

Claude Code——一行命令完成注册:

claude mcp add strata -- python3 /home/you/Strata/tools/strata_mcp.py

这条命令让 Claude Code 把"启动这个 Python 脚本"记入 MCP 服务器列表;进入会话后输入/mcp可确认连接。加--scope user则对所有项目可见。

VS Code(Copilot agent 模式)——工作区放.vscode/mcp.json:

{ "servers": { "strata": { "type": "stdio", "command": "python3", "args": ["/home/you/Strata/tools/strata_mcp.py"] } } }

注意 VS Code 的键名是servers而不是 Claude Desktop 系用的mcpServers,且需要显式"type": "stdio",照抄别的客户端配置会静默失败。

Codex CLI——~/.codex/config.toml:

[mcp_servers.strata] command = "python3" args = ["/home/you/Strata/tools/strata_mcp.py"] tool_timeout_sec = 180

tool_timeout_sec = 180不是装饰:strata_stop会先向运行中的引擎发卸载请求(/unload的 HTTP 超时是 120 秒),strata_benchmark的固定请求本身也要 10~60 秒,客户端默认 60 秒超时会把一次合法调用掐死。

任何其它 MCP 客户端也一样:命令就是python <Strata 目录>/tools/strata_mcp.py,支持协议修订版2025-06-18、2025-03-26、2024-11-05(PROTOCOLS常量,L42),从2025-06-18起工具结果会同时以text和structuredContent两种形式返回(McpServer.content,L2604-L2609)。文件还支持--root <目录>参数去管理"文件所在目录之外"的另一个 Strata 目录;启动时校验该目录必须同时有setup.py和serve/server.py,否则打印not a Strata folder并以退出码 2 结束。

能力地图:9 个工具,四个域

服务器在tools/list中动态生成工具定义(tool_defs,L1821-L1950):模型族、尺寸、上下文长度这些枚举值直接取自setup.py导入的MODELS/FAMILIES/CONTEXTS表,所以工具描述永远和安装脚本的可选项一致,不会漂移。按能力分四组看更清楚:

状态与硬件查询——strata_status、strata_models。前者一次回答"有没有模型在跑(模型名、引擎版本、上下文、忙/闲、VRAM/RAM 占用)、装了哪些模型、有没有安装在进行中、本机硬件(OS/CPU/内存/GPU/页面文件/空闲磁盘)、setup 对本机推荐什么";后者给出全部模型族与尺寸的下载体积、所需内存、本机是否放得下。strata_status返回的summary字段是一句人话,比如Strata is running on port 8080: ... , idle,AI 助手可以直接念给用户听。

安装与变更——strata_install、strata_remove。前者是整个服务器里逻辑最重的工具:不带confirm: true只返回计划(下载体积、磁盘余量、将要执行的确切 setup 命令),确认后后台运行,再调用看进度,cancel: true中止(可断点续装)。后者删除一个已装模型自己的文件,同样先计划后执行,且绝不动其他模型还在引用的共享文件(如共享的 MTP 草稿层)。

运行控制——strata_start、strata_stop、strata_benchmark。启动后工具等待模型应答,超时返回loading;停止走"先 API 卸载、再结束进程"的有序路径;strata_benchmark发一个固定短请求(贪心、关闭思考)报出输出/提示词 token/s,模型忙时拒绝执行。

日志与信息导出——strata_logs、strata_connect_info。前者取 server/engine/setup 三类日志的尾部行;后者给出 OpenAI/Anthropic base URL、模型 id、是否需要密钥,外加 Claude Code、Codex、OpenAI SDK、curl、Cursor/Open WebUI 的即贴即用配置。

机制深潜一:两阶段安装、自重启后台任务与 100GB 进度解析

strata_install的设计核心是复用setup.py自己的表和逻辑,而不是另写一份。setup_module()(L511-L532)把setup.py当模块导入(导入期间临时把sys.stdout指到stderr,防 setup 的打印混进协议流),直接取它的MODELS、FAMILIES、CONTEXTS和 RAM 校验函数;只有导入失败才退回文件内置的FALLBACK_MODELS常量表(L54-L99)。[tools/test_strata_mcp.py](https://link.gitcode.com/i/3b4afce5f84be38476761d031c27037d)里有个断言测试(test_builtin_table_matches_setup)保证这两份表不漂移——否则工具报的"下载 75.8 GB"和 setup 实际下的量就可能对不上。

推荐规则(recommend,L1137-L1222)与 setup 的预选项同源:按MEMORY_TIERS(L120)用 RAM+VRAM 合计减 5 GB 系统预留(TIER_SYSTEM_RESERVE_GB)落在 62/46/38 GB 三档,分别预选 IQ3_S、IQ3_XXS、IQ2_XS;再低则落到 Coder(IQ1_M)或低内存模式(GPU 显存补足内存缺口)。上下文按显存预填:vram < 14给 32768,< 20给 65536,否则 131072(L1201)。

调用时序上是严格的两阶段:

# strata_install 内的关键分叉(L2147-L2154) if not confirm: return {"summary": "Plan: install ... Nothing was done yet: ...", "plan": plan} if plan["disk_short"]: raise ToolError(plan["disk_short"]) return self.launch_install(plan, args)

第一次调用(不带confirm)零副作用:算出完整计划——下载体积(工具描述里写的是 58-111 GB 量级)、目标盘剩余空间对比、内存是否放得下、将要执行的确切命令(形如START-HERE.bat --yes --no-start --family qwen --model IQ3_XXS --context 32768 --vision no)——然后原样返回。计划阶段磁盘不足会写入disk_short,confirm阶段直接抛ToolError拒绝。

第二次调用(confirm: true)启动安装并立即返回。launch_install(L2259-L2293)做的事很有意思:它把作业参数写成.strata-mcp/install-job.json,然后用--install-job隐藏参数把自己重新启动成一个脱离父进程的后台子进程(spawn_detached),由这个子进程负责建 venv、跑 setup、把退出码写进.strata-mcp/install-result.json。为什么要这么绕?因为如果安装线程直接挂在 MCP 服务器进程里,AI 客户端一退出,stdio 管道断开,安装就陪葬了;自己重启成独立会话后,"即使 AI 应用整个关闭,安装照样继续"。

装完后反复调用strata_install查进度。进度来自两条并行的信息源:一是install_progress(L1666-L1689)正则解析日志里的=== Step N: ... ===步骤头、名称: x.xx / y.yy GB (p%)下载行和[X]错误行;二是combined_progress(L1625-L1663)直接扫磁盘上.gguf/.part文件的真实字节数算总进度——这一步解决了"两分片模型进度条 70GB→0→重新爬升"的视觉 bug:单个文件各自 0-100% 没有意义,以整个模型的落盘字节为准才有意义。setup 的断点续传特性在这里同样生效:cancel杀掉进程树后,重新确认安装时已完成步骤自动跳过。

机制深潜二:PID 复用不是问题——为什么进程不会被误杀

AI 助手"替你做系统操作",最危险的动作就是杀错进程。操作系统会复用 PID:你的安装进程死了,同一个数字可能被分配给一个完全无关的新进程。这个服务器的对策是记录进程 id 加启动时间这对组合,结束进程前两者必须都匹配。

proc_identity(L164-L200)跨平台取"启动时间":

# Linux 分支(L187-L195) stat = Path(f"/proc/{pid}/stat") fields = stat.read_text().rsplit(")", 1)[1].split() if fields[0] in ("Z", "X"): # 僵尸进程算已死 return None return f"linux:{fields[19]}" # stat 第 22 字段:启动时钟 tick

Windows 分支用ctypes调GetProcessTimes拿创建时间戳。拿到的是个不透明 token 而非裸数字。之后所有终止操作都过proc_alive这一关:

def proc_terminate(pid, ident) -> bool: """Ask a process WE started to end ... Never touches a process whose start time differs.""" if not proc_alive(pid, ident): return False

也就是说proc_kill_tree、kill_snapshot(杀进程树)每个环节都先验身份。test_never_kills_an_unrelated_process这个测试专门构造"PID 被复用给无关进程"的场景来验证它绝不会动手。

进程树清理还有两个细节值得一提。spawn_detached(L329-L342)让被拉起的服务器/安装进程逃逸出 AI 客户端的进程树:POSIX 用start_new_session=True(自己成为会话组长,进程组独立);Windows 先试CREATE_BREAKAWAY_FROM_JOB,失败退回普通启动——如果 AI 客户端把工具子进程关进一个不允许逃逸的 Windows job 里,模型就会随应用一起结束,这是文档里明说的前提条件。另一处是proc_tree_snapshot(L255-L269):Windows 上先自己快照整棵进程树再taskkill /T /F,因为 taskkill 靠父子链向上走,链条中间断一环后面的就漏杀了(源码注释里挂着 issue #3257:一次取消的安装留下了mtp_fetch.py孤儿进程在写盘)。

机制深潜三:停止的三步顺序,与"自己起的"和"外面起的"之分

strata_stop(L2373-L2422)的顺序是刻意的:

  1. 先查忙闲:GET /status,发现busy且没传force就抛ToolError——正在出 token 的请求不能被腰斩。
  2. 通过 API 卸载模型:POST /unload(120 秒超时)。服务器收到后向引擎发QUIT,引擎自行释放 VRAM 和 pinned RAM——这与手动关窗口的释放路径相同,返回{"status": "unloaded"}记入结果。服务器返回 409(有请求排队/在跑)时,没force同样拒绝。
  3. 结束服务器进程:POSIX 发SIGTERM,走服务器自己的 Ctrl+C 清理路径;等 30 秒(wait_gone)没退干净,升级proc_kill_tree强杀,再等 15 秒;最后end_group_leftovers对进程组补一刀(SIGTERM 等 20 秒、SIGKILL 等 5 秒),兜住"停止时引擎还在加载、服务器自己的 SIGTERM handler 还没装上"的窗口。

关键在于第一步和第三步的前提:这条路径只对"本 MCP 服务器启动的"服务器生效——tracked_server()会核对记录在.strata-mcp/server.json里的 PID 加启动时间是否仍活着。对于别处启动的 Strata(自己的窗口、run 脚本或系统服务),它只做第 2 步:通过 API 请求卸载模型,释放显存但服务继续监听,返回里明确告诉用户"要彻底结束得关掉它自己的窗口"(L2417-L2421)。不杀不是保守,是原则:这个服务器只拥有它自己拉起的进程。

边界线:这个服务器明确拒绝做什么

check_schema(L427-L467) 是所有工具的统一入口校验:未知参数名、setup 不提供的模型/模型族、gpus里出现数字和逗号之外的字符,都会在执行任何命令之前被ToolError拒绝;所有子进程都以参数列表方式传递,从不经过 shell。逐条列出它划的线:

  • 路径白名单。唯一的路径参数是data_dir(check_data_dir,L2081-L2105):必须是当前 Strata 数据目录、Strata 目录内的子目录、或一个名字以Strata开头的新绝对目录(父目录已存在、不在system_folders()清单内)。..、相对路径、UNC 网络路径一律拒绝。日志读取同样受限:只读.strata-mcp/下的日志,或配置指定的引擎日志——且该日志必须落在 Strata 目录或数据目录内(strata_logs,L2440-L2441),否则直接抛错。
  • 仅本机。所有 HTTP 请求固定打127.0.0.1(probe,L1414-L1461),用禁用了代理的 opener(L387,防止系统代理把 localhost 请求拐走)。它从不用--host 0.0.0.0或 API key 方式安装,要在局域网共享得手动跑 setup;实验性选项一律关闭——qwen/coder 族显式追加--experimental-speed-projection off(L2218-L2219)。
  • 大下载必须有人点头。strata_install不带confirm时零副作用;计划里disk_short的在 confirm 阶段直接抛错。
  • 互斥状态显式拒绝,每条都有原因:模型运行中禁止安装(setup 可能替换该模型正在用的引擎文件,L2143-L2146);安装进行中禁止启动模型(L2300-L2302);模型运行中禁止删除(先停);配置引用的文件缺失禁止启动(提示重跑安装修复,L2305-L2307);端口被其他程序占用直接报出而非硬试(L2322-L2323)。
  • 探测不误认。probe要求/health应答里service == "strata"才算 Strata 服务器,否则以ports_used_by_other_programs明确报"别的程序占着这个端口"(L1421-L1422)。若配置里设了api_key,它自己的探测请求会带上这把 key(api_key_for,L1400-L1412),但绝不在任何返回结果中显示它。

离线验证:用假 setup 和假服务器跑完整链路

python -m unittest tools/test_strata_mcp.py

tools/test_strata_mcp.py 全程离线:它在临时目录里搭一个假的 Strata 文件夹(替身setup.py会打印=== Step 5 ... ===和假的下载进度行,替身serve/server.py是本地假 HTTP 服务器,支持/health、/status、/unload、/v1/chat/completions),不下载任何东西、不碰 GPU,却覆盖:JSON-RPC 握手(含旧协议版和错误码)、参数校验、data_dir路径白名单、真实后台进程的安装/进度/取消/失败上报、启动崩溃时日志尾部的回传、busy 时停止需要force、外部服务器只卸载不杀、"绝不杀无关进程",以及上文提到的内置表与setup.py的一致性断言。改动了 tools/strata_mcp.py 的话,先跑这个套件再谈其它。

收尾:什么时候用,什么时候不用

适合的场景:你在 Claude Code / Cursor / VS Code / Codex 里常驻工作,想让"装模型、等加载、看日志、换端口、跑测速、把 OpenAI SDK 指过来"这些运维动作变成一句话;你愿意用源码 checkout 而非发布版(docs/MCP_SERVER.md开头就标注这是 optional 的 source-checkout 工具)。不适合的场景:只是想在终端自己操作——直接跑START-HERE.bat/./setup.sh更直接;需要局域网共享、--build、超过 262K 上下文的 rope scaling 这类实验选项时,这个服务器会刻意不代劳,留给你手动执行。

它的工程取舍可以总结成一句:用纯标准库保证"装之前就能用",用导入setup.py的表保证"说的和装的一致",用两阶段 confirm、PID+启动时间双重身份、路径白名单和 127.0.0.1 的访问面,把"让 AI 代跑系统命令"的风险压到最小——一个两千七百余行的单文件,协议处理、进程管理、进度解析、校验层俱全,也是研究"如何写一个克制的 stdio MCP 服务器"的完整样本。

【免费下载链接】StrataQwen3.8-Flash-Next on any consumer hardware: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, optional image input.项目地址: https://gitcode.com/gh_mirrors/strata11/Strata

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 19:07:16

11-从 JDK 8 迁移到 JDK 25 / 26 实战:风险评估与落地清单

一、先决定升到哪&#xff1a;2026 年的目标版本 不要追非 LTS&#xff0c;也不要一步跳到最新。2026 年的现实选择&#xff1a;目标定位建议JDK 11老 LTS&#xff0c;Oracle 免费更新已于 2023 年结束只当跳板&#xff0c;不停留JDK 17LTS&#xff0c;Oracle 免费&#xff08;…

作者头像 李华
网站建设 2026/11/3 19:02:27

grpcurl 快速安装:一次打通 gRPC 调用不踩坑

grpcurl 快速安装&#xff1a;一次打通 gRPC 调用不踩坑 【免费下载链接】grpcurl Like cURL, but for gRPC: Command-line tool for interacting with gRPC servers 项目地址: https://gitcode.com/gh_mirrors/gr/grpcurl 拿到一个 gRPC 端点&#xff0c;手上没有 SDK&…

作者头像 李华
网站建设 2026/11/3 18:59:59

企业级落地 :织信如何成为企业级信息化系统的底座

织信如何成为企业级信息化系统的底座企业级信息化落地&#xff0c;不能只看上线了几个系统。真正难的地方&#xff0c;是这些系统能不能在同一个底座上运行。生产、设备、质量、仓库、供应链、客户、项目、办公&#xff0c;如果每个系统都是单独建设&#xff0c;短期看都能解决…

作者头像 李华