
Nushell 的 MCP 接入指南用--mcp将 nushell 引擎变成 LLM 可调用工具【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell本篇文章围绕 nushell 仓库中的nu-mcpcrate 展开系统讲解 Nushell 如何以 Model Context ProtocolMCP服务器的身份把自身引擎含内建命令与外部命令作为工具暴露给 Claude、Cursor 等 MCP 客户端。你将掌握 MCP 特性的编译期开关与构建命令、nu --mcp的 stdio / HTTP 双传输启动方式、端口配置与启动参数解析细节并理解其背后“常驻求值器 命令历史 后台任务提升”的运行时设计。nu-mcp 是什么nu-mcp是 nushell 工作区中新增的一个 crate其Cargo.toml中的描述为Modules to run a model context protocol (MCP) server that provides Nushell as a tool.也就是说它负责运行一个 MCP 服务器将“Nushell”本身作为一个可执行的工具交给 MCP 客户端即各类 AI Agent / LLM 宿主。与 nu-lsp把 Nushell 语言服务暴露给编辑器不同nu-mcp 的目标是让大模型能在一个有状态的、可持久化变量与环境变量的 nushell REPL 上下文中执行真实命令。crate 内部由四个模块构成见 lib.rslib.rsMCP 传输层stdio / HTTP与服务器初始化入口server.rs基于rmcp注册的三个 MCP 工具evaluation.rs核心求值器REPL 状态、取消、后台任务提升、历史记录history.rs$history环形缓冲区的实现。编译期接入mcpfeature 是如何逐层生效的README 指出mcpfeature flag 控制 MCP 功能是否编译进 Nushell。这个开关实际存在于两层 Cargo 清单中。第一层nu-mcpcrate 自身crates/nu-mcp/Cargo.toml[features] default [] mcp []default []说明单独依赖该 crate 时默认不引入任何额外依赖组合mcp []仅是 crate 内部的统一特性命名。第二层仓库根nu包Cargo.tomlmcp [ dep:nu-mcp, nu-mcp/mcp, ]根包的mcpfeature 把可选的nu-mcp依赖拉进编译图Cargo.toml并同时开启其子 feature。值得注意的是根包的defaultfeature 列表本身就包含mcpCargo.toml因此执行cargo build默认产物即包含 MCP 能力。README 中显式构建带 MCP 支持的版本cargo build --features mcp--features mcp会在默认 feature 基础上追加开启除非另行--no-default-features因此该命令保证 MCP 被编译进去是官方推荐的显式写法。仓库还提供了fullfeatureCargo.toml一次性开启lsp、mcp、network、plugin、sqlite等互不冲突的特性用于--all-features编译失败时的备选。启动 MCP 服务器nu --mcp带 MCP 支持编译后直接运行nu --mcp--mcp开关定义于 src/command.rs作用描述为 “start nus model context protocol server”。当nu --mcp被解析后主程序会走一条与正常 REPL 完全不同的启动路径src/main.rs提前把engine_state.is_mcp true写入引擎状态注释明确指出这是在配置求值之前标记以便启动脚本能据此调整行为除非显式传入--no-config-file否则仍会执行setup_config加载配置但若走 stdio 传输会使用Stack::new().collect_value()捕获启动脚本的 stdout避免启动输出污染 MCP 协议帧MCP 主机对 stdout 的占用是独占的根据传输类型构造nu_mcp::McpTransport调用initialize_mcp_server后直接return不再进入交互式 REPLMCP 模式下还会跳过主程序的 Ctrl-C 保护src/main.rs因为 HTTP 会话的自定义信号处理由服务器内部接管。启动后服务器通过 MCP 握手上报自己的身份信息见 server.rsserverInfo.name为nushell-mcp-server、标题为Nushell MCP Server、版本取CARGO_PKG_VERSION能力声明enable_tools()并附带一份内嵌的 instructions来自 instructions.md指导 MCP 宿主如何正确使用 nushell。双传输模式stdio 与 HTTPMcpTransport枚举定义在 lib.rsREADME 给出了两种模式传输说明适用场景stdio默认标准输入 / 输出上的 JSON-RPC本地、单客户端如 Claude Desktop、Cursor 的子进程式 MCP serverhttp基于 SSE 的 Streamable HTTP远程访问允许多会话stdio默认的本地位不额外传参即为 stdio。其服务流程见 run_stdio_server创建NushellMcpServer后通过rmcp的serve(stdio())常驻等待消息。由于是机器对机器的协议stdio 模式在 initialize_mcp_server 中做了几处关键铺垫日志走 stderr 且禁止内联错误回退MCP 主机持有 stderr 管道并在退出时关闭它一旦管道破裂默认的eprintln!回退会因 broken pipe 触发 panic故显式关闭 ANSI 并设置log_internal_errors(false)Unix 下执行setsid()lib.rs脱离控制终端使ssh、sudo、psql等会绕过 stdin 直接打开/dev/tty的程序快速失败而不是无限挂起等待密码输入engine_state.is_mcp true外部命令不应继承 stdin避免交互提示造成阻塞。HTTPStreamable HTTP SSEnu --mcp --mcp-transport http默认端口为8080指定自定义端口nu --mcp --mcp-transport http --mcp-port 3000HTTP 服务实现在 run_http_server可拆解为以下几点监听地址固定为0.0.0.0:{port}默认 8080并在启动时向 stderr 打印MCP HTTP server listening on http://{addr}每个会话通过LocalSessionManager管理缓冲通道容量为 16SESSION_CHANNEL_CAPACITYlib.rs会话空闲 30 分钟后清理SESSION_KEEP_ALIVElib.rs每个 TCP 连接被提升为独立 tokio 任务服务基于StreamableHttpServicermcp 的 SSE 流式 HTTP 实现收到 Ctrl-C 时通过CancellationToken广播取消信号让所有会话与 SSE 流优雅退出。端口参数在 CLI 解析层有严格校验parse_port_valuesrc/command.rs要求端口必须是 1~65535 范围内的整数否则报Provide a TCP port between 1 and 65535。未编译 MCP 时的表现README 记录了如下约定如果 Nushell 在未开启 mcp feature的情况下编译仍尝试使用--mcp会得到一条提示重新编译的错误信息。对照源码原因很直接--mcp、--mcp-transport、--mcp-port三个 CLI 标志全部由#[cfg(feature mcp)]包裹src/command.rs未开启该 feature 时它们根本不会注册进CLI_FLAGS于是词法解析会在 unknown_long_flag 处报Unknown flag --mcp并附带 “Did you mean ... / Use nu --help” 的提示引导。也就是说判断当前二进制是否支持 MCP最可靠的方法是执行nu --help查看是否列出--mcp相关选项。三个 MCP 工具list_commands / command_help / evaluateNushellMcpServer通过#[tool_router]宏注册了恰好三个工具server.rs工具参数作用list_commandsfind: OptionString列出所有 nushell 内建命令可按名称、描述、搜索词过滤command_helpname: String获取某个内建命令的帮助含 usage、flags、参数类型evaluateinput: String在 nushell 中执行一段源码并返回结构化结果参数结构体均用schemars派生 JSON Schemaserver.rs保证 MCP 客户端能自动补全参数。其中evaluate工具的长篇行为说明直接通过#[doc include_str!(evaluate_tool.md)]内嵌server.rs。对应的单元测试印证了这些契约server.rs 的#[cfg(test)]模块工具路由表恰为[command_help, evaluate, list_commands]server.rsevaluate的输入 schema 只允许input一个属性测试注释明确说明“单次调用的超时必须完全由NU_MCP_PROMOTE_AFTER环境变量控制”server.rslist_commands返回非空帮助且能按关键词命中server.rsevaluate 5 2的structuredContent.output 7server.rs连续两次求值的history_index依次递增 0、1server.rs。响应格式NUON 记录 JSON 镜像evaluate成功时返回一条结构化 NUON 记录evaluation.rs字段如下字段含义cwd命令执行后的当前工作目录history_index本次结果在$history中的 0 起始下标timestamp执行时刻datetime 类型output命令输出未超限时出现note输出超限时取代output出现指向完整结果的 history 下标同一条响应还会被序列化为 JSON 写入 MCP 的structuredContentevaluation.rs供支持结构化输出的宿主直接消费文本与结构化两种形态互为镜像。执行失败解析/编译/运行错误时则返回 NUON 格式的错误记录包含code如nu::parser::parse_mismatch、msg、severity、help、url、labelstext/span/line/column行列为 1 起始等结构化字段evaluation.rs并按错误类别映射到 MCP 标准错误码——用户输入错误为invalid_params-32602运行期内部错误为internal_error-32603。REPL 式求值、$history与三个可调环境变量这是 nu-mcp 区别于“跑一个 shell 命令就退出”的普通 exec 型 MCP 工具的核心设计。常驻状态 fork 提交模型Evaluator持有持久的EngineState与Stackevaluation.rs行为与交互式 REPL 完全一致一次调用里let x 42或$env.MY_VAR hello下一次调用仍可读到。每次求值并不直接在共享状态上执行而是先fork()出带独立中断信号的副本跑完后再整体提交commit回持久状态evaluation.rs一旦发生取消或超时fork 出的状态直接丢弃保证主状态不被半途修改。由于求值可能被中断客户端取消或执行过久真正执行逻辑被放到spawn_blocking线程中主循环用tokio::select!监听三个事件取消令牌、结果就绪、promote-after 定时器到期evaluation.rs。$history不截断流水线的底气History是一个VecDequeValue环形缓冲区容量满时弹出最旧条目history.rs在引擎中注册为$history: listany合成变量history.rs。每次求值都会把完整输出压入 history无论响应是否被截断。配套的环境变量可在持久栈上用 nushell 语法设置源码常量见 evaluation.rs 与 history.rs$env.NU_MCP_OUTPUT_LIMIT 50kb # 更大的内联响应默认 10kb $env.NU_MCP_OUTPUT_LIMIT 0b # 彻底关闭截断 $env.NU_MCP_HISTORY_LIMIT 200 # 记忆更多条目默认 100环形淘汰 $env.NU_MCP_PROMOTE_AFTER 10min # 延长同步窗口默认 120 秒三个变量的语义与生效细节NU_MCP_OUTPUT_LIMIT响应截断阈值默认 10kb按 filesize 解析output_limit设为0b表示不截断。无论该值如何完整输出总是存在于$historyNU_MCP_HISTORY_LIMIT环形缓冲区容量默认 100按 int 解析history_limit。淘汰最旧条目时下标不回移——早先条目只是不可再访问已有history_index语义不变NU_MCP_PROMOTE_AFTER运行多久后自动把调用提升为后台任务默认 120 秒DEFAULT_PROMOTE_AFTERevaluation.rs按 duration 解析promote_timeout。超时 / 取消后的后台任务提升当一次求值超过 promote-after 阈值或客户端取消时它不会被粗暴打断而是被提升为后台任务promote_to_background_job以 fork 状态的共享中断信号注册一个ThreadJob任务描述以mcp: 首行前 40 字符截断job_description工具调用立即返回错误文本Operation promoted to background job (id: N). Use \job list to see it and job recv to get the result.后台任务完成时通过主线程信箱job 0投递完整非截断输出——被提升的任务绕过$history只能靠job recv取回。MCP 宿主随后在 nushell 内使用作业命令取回结果job list # 查看是否仍在运行 job recv # 阻塞等待完整结果 job recv --timeout 60sec # 限时等待 job kill 1 # 取消任务也支持手工后台化常驻进程如启动开发服务器job spawn { uvicorn main:app } job spawn --tag web-server { ... } job spawn { ls | job send 0 }; job recv # 主线程编号为 0注意事项命令名是job list而非job lsjob recv读取当前作业信箱且不接受 idjob send必须显式给出目标 id。内建指令规范nu-mcp 如何“教导”LLM 使用 shellinstructions.md 随服务器元数据下发给 MCP 宿主是一份面向 LLM 的 nushell 使用契约值得所有希望在自己的 Agent 里嵌入 nushell 的开发者借鉴核心规则如下。第一条铁律绝不在首次运行的流水线内截断输出Never cap output inside a pipeline you are running for the first time.禁止head、tail、first N、take N、head -c等任何尺寸限制器。理由是完整的求值结果总会被$history捕获响应即使被内联截断也会携带可回卷的history_index# 错误示范 —— 在实时流水线里截断 ls **/*.rs | first 20 # 正确做法 —— 先完整运行一次再从 $history 里切片 cargo build | complete $history.7.stderr | lines | where $it ~ ^error | skip 30 | first 30 # 对已保存结果分页是允许的complete会把 stdout / stderr / exit_code 拆成独立列默认保持两路流分离仅当确实需要交错顺序如构建日志中告警紧跟其前置 stdout才用oe| complete。求值细节与命令习惯变量与环境变量跨调用持久REPL 语义但外部进程只继承环境变量、不继承let绑定内建命令返回结构化 NUON不要再接| to json外部命令返回字符串按需from json/from yaml/from csv解析字符串字面量单引号不转义适合 Windows 路径与 SQL双引号支持\n \t \ \\反引号用于含空格的路径插值必须写作$hello ($name)圆括号不可省控制字符用char escape/char newline/char tabnushell 不支持\uXXXX重定向cmd file→cmd o file追加用o丢弃输出用| ignore合并两路流用oe| next无21语法HTTP 已自动解析http get/post/...依据 Content-Type 自动解析 JSONhttp get https://api.example.com/users | get 0.name直接可用-t json不生效须传完整 MIME 类型application/json并行与文件发现顺序无关的重活优先par-each查文件用glob而非find/ls -r后者会遍历隐藏目录导致输出爆炸Polars 插件处理 parquet/jsonl/ndjson/csv/avro 时plugin use polars后使用polars open ... | polars select ... | polars save out.parquet显著更快polars into-nu可转回 nushell 表结构化列式输出用detect columns如launchctl list | detect columns而非手写parse。evaluate工具自身的说明evaluate_tool.md还附有一张 Bash→Nushell 速查表涵盖mkdir -p→mkdir、rm -rf→rm -r、cat file→open --raw file、grep→where $it ~ ...、$(cmd)→(cmd)、echo $?→$env.LAST_EXIT_CODE、FOObar ./bin原样保留、续行符\→括号包裹等常见转换。关键实现索引若想深入研读可沿以下路径继续探索本仓库工具契约与服务器元数据server.rs含完整单测求值、取消、后台任务与超时逻辑evaluation.rs$history环形缓冲区history.rs传输层与启动流程lib.rsCLI 标志定义与端口校验src/command.rs主程序 MCP 启动分支与 Ctrl-C 处理src/main.rsMCP 模式下print等命令改走 stderr 以保护协议通道crates/nu-cli/src/commands/print.rs 与 crates/nu-cli/src/util.rs依赖与特性清单nu-mcp/Cargo.toml、根 Cargo.toml小结把 nushell 用作 MCP 工具的价值在于结构化流水线让 LLM 无需反复重跑命令即可过滤、切片与二次加工结果。使用上只需三步——用cargo build --features mcp或直接采用默认 feature编译出带 MCP 的二进制以nu --mcp本地挂接stdio或以nu --mcp --mcp-transport http --mcp-port port提供远程服务然后在客户端里通过list_commands/command_help/evaluate三个工具驱动即可。理解其背后的常驻 REPL 状态、$history回卷、后台任务提升与三个NU_MCP_*环境变量能帮助你避免踩到“截断即丢失”“长任务阻塞”“取错历史下标”等常见坑。【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考