Skip to main content
Glama

rf-log-mcp

用于检查 Robot Framework 结果文件的 MCP Server,面向 LLM 提供简洁证据视图。

功能概览

支持输入:

  • output.xml:Robot / Rebot 6.0.x / 6.1+ / 7.x

  • output.json:Robot / Rebot 7.2+

暴露的 MCP 能力:

  • Tools

    • parse_result

    • get_view

    • search_messages

  • Resources

    • rf://runs/{run_id}/summary

    • rf://runs/{run_id}/tests/{test_id}

支持的视图:

  • summary

  • failure_path

  • step_window

  • tree(按节点逐层展开,支持 all / failures / warnings 投影)

通用返回字段:

  • run_id:整数运行编号,推荐后续调用都使用它

  • estimated_tokens:当前返回体的估算 token 数

  • truncated:兼容字段,只表示返回内容发生过任意截断

  • message_truncated:长消息被缩短

  • budget_truncated:为了满足 budget 限制裁剪了返回内容

  • page_truncated:当前页后面还有更多数据

  • next_cursor:分页游标;为空表示没有下一页

关键说明

  • 这个项目是 MCP stdio server

  • 正确方式是:MCP 宿主启动 rf-log-mcp 进程,再通过 stdio 调用工具和资源


快速开始

1. 安装依赖

uv sync

2. 推荐的 MCP 配置示例(Windows)

{
  "mcpServers": {
    "rf-log-mcp": {
      "command": "D:\\project\\rf_log_mcp\\.venv\\Scripts\\python.exe",
      "args": [
        "-m",
        "rf_log_mcp"
      ]
    }
  }
}

打包与安装

构建

uv build

构建后生成:

  • dist/rf_log_mcp-0.2.0-py3-none-any.whl

  • dist/rf_log_mcp-0.2.0.tar.gz

安装 wheel

uv pip install dist/rf_log_mcp-0.2.0-py3-none-any.whl

安装后可直接启动:

rf-log-mcp

已安装包的 MCP 配置示例

{
  "mcpServers": {
    "rf-log-mcp": {
      "command": "rf-log-mcp",
      "args": []
    }
  }
}

Windows 显式路径示例

{
  "mcpServers": {
    "rf-log-mcp": {
      "command": "D:\\project\\rf_log_mcp\\.venv\\Scripts\\python.exe",
      "args": [
        "-m",
        "rf_log_mcp"
      ]
    }
  }
}

典型调用流程

第一步:解析结果文件

parse_result(path="tests/fixtures/single_failure_611.xml")

典型返回:

{
  "ok": true,
  "run_id": 1,
  "source_format": "xml"
}

第二步:获取摘要

get_view(run_id=1, view="summary")

如果失败用例较多,可以指定分页大小:

get_view(run_id=1, view="summary", page_size=10)
get_view(run_id=1, view="summary", cursor="<next_cursor>", page_size=10)

第三步:获取失败路径

get_view(run_id=1, view="failure_path")
get_view(run_id=1, view="failure_path", selector="s1-t2")

failure_path 会从失败测试中选择更短、更关键的失败分支;当同层分支长度相同,会优先返回包含更高严重级别消息的分支。

第四步:查看步骤窗口

get_view(run_id=1, view="step_window", selector="s1-t2")

step_windowselector 可以传测试节点,也可以传关键字/步骤节点。传步骤节点时,返回会自动定位到所属测试,并尽量把该节点放在窗口中间。

分页示例:

get_view(run_id=1, view="step_window", selector="s1-t2-k13", page_size=20)
get_view(run_id=1, view="step_window", selector="s1-t2-k13", cursor="<next_cursor>", page_size=20)

第五步:检索消息

search_messages(run_id=1, query="timeout")

search_messages 按普通文本匹配。%_\ 会作为字面量处理,不会被当成 SQL LIKE 通配符。

Tree View:按需展开执行树

从运行根开始展开:

get_view(run_id=1, view="tree", projection="failures")

继续展开返回节点:

get_view(
  run_id=1,
  view="tree",
  selector="s1-t2",
  projection="all",
  page_size=25
)
  • all 返回全部直接子节点。

  • failures 只返回失败节点或包含失败后代的节点。

  • warnings 返回 WARN、ERROR、FAIL 节点或包含这些后代的节点。

  • 连续 25 个及以上的成功 ITERATION 会返回为 ITERATION_GROUP;使用其 expand_selector 可以分页读取原始迭代。

  • next_cursorrun_idselectorprojection 和顺序绑定,不能跨查询复用。

Tree View 会返回运行根、Suite/Test Setup 与 Teardown、控制流、消息和运行级错误。 类型专属字段仅在非空时返回,例如关键字的 args / assign、IF 的 condition、 FOR 的变量和值,以及 VAR 的作用域。


环境变量

RF_LOG_MCP_DB

用于覆盖默认 SQLite 数据库路径。

PowerShell 示例:

$env:RF_LOG_MCP_DB="D:\data\rf-log-mcp\store.sqlite3"
rf-log-mcp

MCP 配置示例:

{
  "mcpServers": {
    "rf-log-mcp": {
      "command": "rf-log-mcp",
      "args": [],
      "env": {
        "RF_LOG_MCP_DB": "D:\\data\\rf-log-mcp\\store.sqlite3"
      }
    }
  }
}

常见问题

1. 为什么使用uv

  1. 本地环境的依赖版本可能和 mcp的冲突, 需要venv 来隔离依赖冲突(conda 太慢, uv快)

2. truncated 和三个细分字段有什么区别?

truncated 是总开关,任意一种截断都会为 true

  • message_truncated=true:消息字段太长,被缩短显示

  • budget_truncated=true:返回体超过 budget,服务主动裁剪了条目或消息

  • page_truncated=true:还有下一页,应继续传 next_cursor

排查失败链时优先关注 budget_truncated。如果它为 true,可以调大 budget 或缩小 page_size 后重新查询。

3. get_view / search_messages 能传文件路径吗?

可以。
如果该文件已经被解析过,服务会先把路径转换成对应的 run_id 再查询。
但仍然推荐优先使用 parse_result() 返回的整数 run_id

4. Windows 上推荐用哪种启动方式?

开发临时验证可以使用:

uv run python -m rf_log_mcp

接入 MCP 宿主时,更推荐使用虚拟环境里的解释器直接启动,减少 uv.exe 启动器额外进程带来的文件占用问题:

{
  "mcpServers": {
    "rf-log-mcp": {
      "command": "D:\\project\\rf_log_mcp\\.venv\\Scripts\\python.exe",
      "args": [
        "-m",
        "rf_log_mcp"
      ]
    }
  }
}

5. 什么情况下不能直接使用这个项目?

如果你的 LLM 平台:

  • 不支持 MCP

  • 或不支持启动本地进程

那就不能直接接入,需要额外做一层集成。


开发路线图

路线图由真实使用问题和两个参考实现共同驱动:

  • Robot Framework VS Code 插件 Output View:先建立完整运行树,再按节点及后代的严重级别过滤和折叠,并压缩大量成功迭代。

  • RobotCode results log:用递归 LogEntry.body 表达 KEYWORD、控制流和消息,并为不同节点保留参数、赋值、条件和异常匹配等类型专属字段。

本项目继续使用扁平的 NodeRecord + parent_id + sequence 作为唯一事实来源,通过 MCP 按节点展开、投影和分页。不会把 RobotCode 的完整递归 body 存入数据库,也不会在一次结构化调用中默认返回整个 Test Tree。

Tree View 用于理解 Suite、Test、Keyword、控制流和消息之间的结构。现有 summaryfailure_pathstep_window、cursor 和全局消息搜索继续保留,用于结果分类、还原完整时序和跨分支追踪。

真实使用问题基线

2026-05-21 至 2026-07-21 的本地 Codex 使用记录包含 43 个任务、854 次 MCP 调用:101 次 parse_result、317 次 get_view 和 436 次 search_messages。这些数据不是产品遥测,只作为后续版本的验收基线。

已确认的问题:

  • 一个约 2.3 GB 的 output.xml 在 55.6 秒后以 string longer than INT_MAX bytes 失败。当前整次运行被序列化进单个 payload_json,超大结果不能继续依赖单字段完整存储。

  • 两次 parse_result 返回 INVALID_XML,其中至少一次是执行中断留下的文件,缺少 </robot>。需要区分格式不支持、仍在写入和结果被截断。

  • 四次 step_window 返回 TEST_NOT_FOUND。缺少 selector 时错误码不准确,Suite Setup/Teardown 等没有 owner_test_id 的节点也无法通过测试窗口展开。

  • 两次按 WARN/ERROR 级别搜索时因 query="" 返回 INVALID_QUERY。消息搜索需要支持纯级别过滤。

  • 853 个结构化返回中有 417 个发生任意截断:summary 43/89、failure_path 41/95、step_window 117/133、search_messages 216/436。消息截断和分页经常触发二次查询。

  • 全局搜索普通数字或 HTTP 状态码会命中大量无关 TRACE/INFO,并可能返回登录载荷中的敏感字段。需要子树范围、级别阈值和响应脱敏。

  • Windows 下运行中的 rf-log-mcp.exe 会阻止 uv 替换入口程序;部分 Codex 会话没有暴露 MCP 工具。宿主启动、健康检查和回退方式需要标准化。

以上问题改变了原先“没有性能证据前不增加持久化节点索引”的前提:普通日志仍可先使用内存索引,但超大日志已经证明不能继续把完整运行保存为单个 JSON 字段。

v0.2:输入可靠性与 Tree Projection MVP(已于 2026-07-21 实现)

实现状态:以下输入检测、规范化分表、Tree Projection、绑定 cursor、类型专属字段、 迭代压缩和精确 selector 错误均已落地;后续兼容性修复继续在 v0.2.x 完成。

输入与存储前置修复

  • 在解析前检查文件类型、XML 根节点、结束标签和文件稳定性。对仍在写入或缺少闭合根节点的结果返回 INCOMPLETE_RESULT,对已稳定但无法解析的文件保留 INVALID_XML / INVALID_JSON

  • runs 只保存运行元数据和统计信息;节点、消息和错误使用可分批写入的独立记录,避免把整次运行序列化成单个 payload_json

  • 保留按内容哈希复用 run_id 的缓存语义。大文件写入失败时不得留下可被后续查询误认为完整的 run。

  • Windows MCP 配置默认使用虚拟环境解释器执行 python -m rf_log_mcp;开发检查使用虚拟环境中的 Python 和 Ruff,避免正在运行的入口程序被 uv 替换。

Tree 查询契约

增加 tree 视图,支持从运行根节点、测试或任意节点开始按需展开直接子节点:

get_view(
  run_id=1,
  view="tree",
  selector="s1-t1",
  projection="failures",
  cursor=None,
  page_size=25
)

selector=None 表示运行根节点。首版支持以下投影:

  • all:返回全部直接子节点

  • failures:返回自身失败或包含失败后代的节点,并保留必要祖先

  • warnings:返回子树最高严重度达到 WARN 或 FAIL 的节点,并保留必要祖先

投影必须基于完整树计算,不能先删除 PASS 节点或原始事件。先确定当前 selector 下符合投影的子节点,再按稳定的 sequence 顺序分页。cursor 应绑定 run_idselectorprojection 和排序条件,不能跨查询条件复用。

Tree View 使用 append-only 的公开 Schema:已发布字段不删除、不改名;新增字段保持可选。节点默认只返回摘要和非空的类型专属字段,不展开大量 TRACE/INFO 正文。

所有节点的公共字段:

  • node_idparent_idowner_test_idsequence

  • 规范化节点类型与原始 keyword_type,覆盖 SUITE、TEST、SETUP、TEARDOWN、KEYWORD、FOR、ITERATION、IF、ELSE、TRY、EXCEPT、FINALLY、WHILE 等结构

  • namestatuselapsed_mslibname

  • child_countfailed_descendant_countmax_descendant_levelhas_children

  • 用于继续展开的节点引用和分页 cursor

借鉴 RobotCode,按节点类型补充非空字段:

  • KEYWORD / SETUP / TEARDOWN:argsassign

  • FOR / ITERATION:flavor、循环变量和值

  • IF / ELSE IF:condition

  • TRY / EXCEPT:patternspattern_typeassign

  • VAR:变量名、值、scopeseparator

  • MESSAGE:leveltimestampis_html

运行根节点、Suite Setup/Teardown、Test Setup/Teardown 和运行级 ERROR 都必须进入同一棵可寻址树。不能像 RobotCode results log 一样跳过 Suite 生命周期,再用独立列表补偿。

大循环压缩

参考 Output View 对大量成功迭代的处理,Tree View 应压缩同一父节点下连续的 PASS ITERATION,但保留原始节点的可查询性。聚合节点示例:

{
  "group_id": "ig:s1-t1-k2:1-949",
  "kind": "ITERATION_GROUP",
  "status": "PASS",
  "count": 949,
  "first_node_id": "s1-t1-k2-k1",
  "last_node_id": "s1-t1-k2-k949",
  "expand_selector": "ig:s1-t1-k2:1-949"
}

压缩规则:

  • 只压缩达到阈值的连续 PASS 迭代

  • 自身不是 PASS,或子树包含 WARN、FAIL、ERROR 的迭代不参与压缩

  • 失败投影必须直接暴露失败迭代及其必要祖先

  • 聚合节点使用稳定的 group_id;将其作为 selector 时,按 sequence 和分页返回覆盖范围内的原始迭代

重点验收场景:

  • 1000 次循环中只有一个失败迭代时,可以直接定位该 ITERATION,其余连续成功迭代被压缩

  • Run Keyword And Continue On Failure 场景保留实际失败分支和后续执行结果

  • Suite Setup、Test Setup、Test、Test Teardown 和 Suite Teardown 分别失败时可以独立展开

  • IF/ELSE、TRY/EXCEPT/FINALLY、FOR/WHILE、VAR、RETURN、BREAK、CONTINUE 和 GROUP 保持正确父子关系及类型专属字段

  • XML 和 RF 7.2+ JSON 输入生成一致的规范化节点语义

  • 现有 summaryfailure_pathstep_windowsearch_messages 保持兼容

  • 缺少 selector、selector 不存在和节点不属于 Test 时返回可区分的错误,不再统一表现为 TEST_NOT_FOUND

普通日志可基于现有 NodeRecord.parent_idsequence 构建内存索引;独立节点存储同时为超大日志和后续子树查询提供持久化基础。Tree View 不复制一份递归 body

v0.3:限定范围的消息搜索

扩展 search_messages,允许把检索范围限制到测试、节点或子树:

search_messages(
  run_id=1,
  query="param invalid",
  selector="s1-t1-k2",
  scope="subtree",
  level=None,
  min_level="WARN",
  cursor=None
)
  • query 改为可选;query、精确 level 和严重度阈值 min_level 至少提供一个。

  • levelmin_level 不能同时提供;前者精确匹配,后者按 TRACE < DEBUG < INFO < WARN < ERROR < FAIL 过滤。

  • 范围搜索必须使用完整节点关系确定目标子树,再搜索该范围内的消息,不能先过滤原始事件后重新建树。

  • 搜索结果补充所属节点、节点状态、sequence、所属 ITERATION/分支和简短运行时调用路径。

  • 返回层对 password、token、cookie、authorization、private key 等常见敏感字段的值做掩码,保留字段名和诊断上下文;索引和原始 artifact 不被修改。

模型可以在失败 ITERATION 内查询请求、回包和变量,也可以继续使用全局搜索追踪对象在 Setup、Test 和 Teardown 中的完整生命周期。

如果真实数据表明内存子树扫描或现有消息索引无法满足延迟目标,再增加节点关系表、递归索引或消息范围索引。

v0.4:源码与节点元数据增强

在 v0.2 执行语义之上,借鉴 RobotCode 的 Suite/Test/Keyword 元数据,同时补齐不同 Robot XML/JSON 版本中的来源差异:

{
  "source": "path/to/case.robot",
  "lineno": 123,
  "libname": "SystemIntegrationCommon",
  "source_origin": "node"
}
  • Suite / Test:sourcelineno、documentation 和 metadata

  • KEYWORD / SETUP / TEARDOWN:定义侧 doctagstimeout

  • HTML 消息:结构化的附件类型、原始引用、是否内嵌和大小估算

该阶段需要明确字段来源和可信度,例如节点直接提供、从所属 Suite 继承、从关键字定义解析或输入格式不支持。缺失字段保持为空,不通过关键字名称猜测文件位置。

MCP 默认保持只读,只返回附件引用和元数据,不像 RobotCode --extract 那样自动解码、复制或写入附件文件。

v0.5:真实使用评估

Tree View 上线后,通过真实日志分析记录以下聚合指标:

  • Tree View 的展开深度、分页次数、返回 token 和 projection 使用比例

  • PASS 迭代压缩前后的节点数量及失败迭代命中率

  • step_window 是否仍被频繁用于大范围查询

  • 子树搜索是否减少跨测试或跨迭代的无关命中

  • 消息截断是否经常导致二次查询

  • 循环、retry 和重复 TRACE/INFO 是否仍是主要返回体积来源

  • 类型专属字段、关键字定义元数据和 HTML 附件引用的实际使用比例

  • 输入大小、解析时间、峰值内存、存储大小和失败恢复情况

在积累足够使用记录后,再决定是否增加:

  • 按循环迭代或运行节点分组的搜索结果

  • 重复消息折叠及首次、末次样本

  • 单条长消息的分片读取

  • 更复杂的节点筛选和专用递归索引

  • 面向小型结果的一次性 tree_snapshot(selector, max_depth) 便捷视图

tree_snapshot 即使增加,也只能作为有大小上限的便捷视图,不能替代分页 Tree API。结构化查询仍作为可选能力;get_view 保留自定义 budget 和 cursor 分页,search_messages 保留全局搜索和 cursor 分页。工具只提供数据与结构,不负责判断根因或建议模型下一步操作。

明确不采用的 RobotCode 设计

  • 不把完整递归 body 作为数据库中的主存储结构

  • 不在一次 MCP 调用中默认返回完整 Test Tree

  • 不让结构化输出忽略深度和 budget 限制

  • 不先按 Test 状态删除原始节点,再从裁剪后的树生成视图

  • 不跳过 Suite Setup/Teardown

  • 不在只读查询中自动提取附件或写入文件

实施顺序

  1. 增加不完整结果识别、分批节点/消息存储和失败回滚,先消除超大文件与半截 XML 的已知阻塞。

  2. 定义 append-only Tree Schema、类型专属字段、projection、cursor 和循环压缩契约。

  3. 增加深循环、失败迭代、完整 Suite/Test 生命周期、条件/异常分支、Continue On Failure 和运行级 ERROR 测试夹具。

  4. 实现完整树索引、后代严重级别聚合、直接子节点展开和 PASS 迭代压缩。

  5. 增加纯级别过滤、子树限定搜索、运行时调用路径和响应脱敏。

  6. 补齐源码字段、关键字定义元数据、附件引用及其来源规则。

  7. 更新 MCP 文档、Windows 宿主配置、健康检查和相关 Skill 能力说明。

  8. 用历史问题基线和新的真实调用记录评估性能,再决定高级索引、分组、长消息分片和 tree_snapshot


开发检查

uv run ruff check .
uv run pytest