
Nushell MCP 响应被截断时如何用 history_index 和 $history 取回完整结果【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell当客户端通过 MCP 调用 Nushell 的evaluate工具执行命令时如果输出超过了内联大小限制工具响应里就不会出现完整的output字段取而代之的是一条note。此时结果并没有丢失完整输出已经自动存入会话内的$history列表响应中携带的history_index就是定位它的句柄。本文讲清楚如何识别截断、如何用$history.index取回完整结果、如何只取需要的部分以及哪些边界情况不适用这套方法。前提是 Nushell 启用了 MCP 功能mcpfeature并在运行 MCP server。构建与启动方式来自 README# 编译出带 MCP 支持的二进制 cargo build --features mcp # 启动 MCP serverstdio 为默认传输方式 nu --mcp启动后服务端提供evaluate、list_commands、command_help三个工具响应与$history的完整行为描述在 instructions.md 中evaluate_tool.md 是evaluate工具自身的说明。先识别截断看响应里是 output 还是 note每次evaluate成功执行后返回一个 NUON 记录字段固定见 instructions.md 的 Response Format字段含义cwd命令执行后的当前工作目录history_index本次结果在$history中的 0-based 下标this is your handle for re-slicing later需要从响应里读出来timestamp执行时刻output命令输出在限制之内时note仅当被截断时替代output出现内容指向 history index判断规则就一条响应里出现note而不是output说明这次被截断完整结果在$history.那个下标。实现上evaluation.rs先用output_nuon.len()与上限比较超限就走note分支见 evaluation.rs# 文档示例cargo build | complete 的结果超限后响应形如 { history_index: 7, ... }其中7是文档给出的示例下标实际值以你响应里的history_index为准note的文案是output truncated, full result in $history.7。主路径用 history_index 取回完整结果第一步永远是从被截断的响应里读出history_index假设读出来是 7。然后直接按显式下标取$history.7 # 完整、未截断的结果即响应中 history_index 为 7 的那次求值验证取到了什么$history | length # 当前持有的条目数$history | length可以告诉你缓冲区里还剩多少条而取回的确实是完整结果这一点由机制本身保证——$history存的本来就是全量输出截断只发生在响应层instructions.mdThe full value is always in$historyregardless of this setting。如果该次结果未超限、响应里直接有output则无需走note路径直接对比output字段与$history.index即可确认二者一致。只取需要的部分对已保存结果切片取回完整结果后通常只需要其中一部分。对已保存的$history.N做分页、过滤是允许的——Never cap 规则约束的是首次执行时的实时管道不是对历史结果的再处理instructions.md 原文paging a saved result is fine# 文档示例从 cargo build | complete 捕获的 { stdout, stderr, exit_code } 中提取错误行 $history.7.stderr | lines | where $it ~ ^error # 对已保存结果分页跳过前 30 行再取 30 行 $history.7.stderr | lines | where $it ~ ^error | skip 30 | first 30两个要点where本身是过滤不算截断first N、last N用在已保存的$history.N上才是合规的分页方式。另外complete已经把stdout和stderr拆成独立列默认用| complete保持分流即可只有需要交错顺序如构建日志中 stderr 警告要紧跟其前面的 stdout 行才用oe| complete。两条容易混淆的边界后台任务提升走的是 job 体系不是 $history如果命令运行时间超过NU_MCP_PROMOTE_AFTER默认 120 秒或被客户端取消这次求值会被自动提升为后台任务响应是一条形如Operation promoted to background job (id: 1). Use job list to see it and job recv to get the result.的错误。注意被提升的任务绕过$history完整输出通过job recv送达而不是成为 history 条目instructions.md Long-running commands and background jobsjob list # 查看是否还在运行注意没有 job ls 这个写法 job recv # 阻塞直到结果到达返回完整未截断输出 job recv --timeout 60sec # 限定等待时间 job kill 1 # 取消任务所以遇到 promoted to background job 错误时不要去找history_index应改用job recv取结果。不要用 $history | last条目被驱逐后下标仍有效每次新的evaluate都会把自己的输出压入$history。第二次调用时执行$history | last取到的是当前这条求值自己而不是你最初运行的那条命令——所以必须始终用响应里的显式history_index重新索引$history.7、$history.0| last只在你之后没有再执行任何东西时才是对的。另一个边界是环形缓冲区$history默认最多保留 100 条history.rs 中push在达到上限时pop_front驱逐最旧条目。条目被驱逐后对应的旧下标会失效这一点在 test_history_ring_buffer 中有具体演示。调整截断阈值可选如果经常需要更大的内联响应可以在会话里直接改环境变量这些设置在 REPL 语义下跨evaluate调用持久且每次修改本身也会占用一个$history条目instructions.md Limits$env.NU_MCP_OUTPUT_LIMIT 50kb # 更大的内联响应 $env.NU_MCP_OUTPUT_LIMIT 0b # 完全禁用截断 $env.NU_MCP_HISTORY_LIMIT 200 # 记住更多条目NU_MCP_OUTPUT_LIMIT默认 10kb无论设成多少完整值始终在$history里所以禁用截断只是省掉note路径不改变取回方式。小结与验证口径完成一次取回的判定标准是被截断响应的note里指向的下标 N$history.N能返回对应求值的完整结果需要更小切片时对$history.N做where/skip/first即可且这些操作不会再产生新的截断问题切片结果本身若超限仍按同一套note 新下标的规则处理。真正不适用$history的只有一种情况求值被提升为后台任务此时按文档指引改用job list/job recv取结果。【免费下载链接】nushellA new type of shell项目地址: https://gitcode.com/GitHub_Trending/nu/nushell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考