rf-log-mcp
rf-log-mcp
用于检查 Robot Framework 结果文件的 MCP Server,面向 LLM 提供简洁证据视图。
功能概览
支持输入:
output.xml:Robot / Rebot 6.0.x / 6.1+ / 7.xoutput.json:Robot / Rebot 7.2+
暴露的 MCP 能力:
Tools
parse_resultget_viewsearch_messages
Resources
rf://runs/{run_id}/summaryrf://runs/{run_id}/tests/{test_id}
支持的视图:
summaryfailure_pathstep_windowtree(按节点逐层展开,支持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 sync2. 推荐的 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.whldist/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_window 的 selector 可以传测试节点,也可以传关键字/步骤节点。传步骤节点时,返回会自动定位到所属测试,并尽量把该节点放在窗口中间。
分页示例:
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_cursor与run_id、selector、projection和顺序绑定,不能跨查询复用。
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-mcpMCP 配置示例:
{
"mcpServers": {
"rf-log-mcp": {
"command": "rf-log-mcp",
"args": [],
"env": {
"RF_LOG_MCP_DB": "D:\\data\\rf-log-mcp\\store.sqlite3"
}
}
}
}常见问题
1. 为什么使用uv
本地环境的依赖版本可能和 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、控制流和消息之间的结构。现有 summary、failure_path、step_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 个发生任意截断:
summary43/89、failure_path41/95、step_window117/133、search_messages216/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_id、selector、projection 和排序条件,不能跨查询条件复用。
Tree View 使用 append-only 的公开 Schema:已发布字段不删除、不改名;新增字段保持可选。节点默认只返回摘要和非空的类型专属字段,不展开大量 TRACE/INFO 正文。
所有节点的公共字段:
node_id、parent_id、owner_test_id和sequence规范化节点类型与原始
keyword_type,覆盖 SUITE、TEST、SETUP、TEARDOWN、KEYWORD、FOR、ITERATION、IF、ELSE、TRY、EXCEPT、FINALLY、WHILE 等结构name、status、elapsed_ms和libnamechild_count、failed_descendant_count、max_descendant_level和has_children用于继续展开的节点引用和分页 cursor
借鉴 RobotCode,按节点类型补充非空字段:
KEYWORD / SETUP / TEARDOWN:
args、assignFOR / ITERATION:
flavor、循环变量和值IF / ELSE IF:
conditionTRY / EXCEPT:
patterns、pattern_type、assignVAR:变量名、值、
scope、separatorMESSAGE:
level、timestamp、is_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 输入生成一致的规范化节点语义
现有
summary、failure_path、step_window和search_messages保持兼容缺少 selector、selector 不存在和节点不属于 Test 时返回可区分的错误,不再统一表现为
TEST_NOT_FOUND
普通日志可基于现有 NodeRecord.parent_id 和 sequence 构建内存索引;独立节点存储同时为超大日志和后续子树查询提供持久化基础。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至少提供一个。level与min_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:
source、lineno、documentation 和 metadataKEYWORD / SETUP / TEARDOWN:定义侧
doc、tags和timeoutHTML 消息:结构化的附件类型、原始引用、是否内嵌和大小估算
该阶段需要明确字段来源和可信度,例如节点直接提供、从所属 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
不在只读查询中自动提取附件或写入文件
实施顺序
增加不完整结果识别、分批节点/消息存储和失败回滚,先消除超大文件与半截 XML 的已知阻塞。
定义 append-only Tree Schema、类型专属字段、projection、cursor 和循环压缩契约。
增加深循环、失败迭代、完整 Suite/Test 生命周期、条件/异常分支、Continue On Failure 和运行级 ERROR 测试夹具。
实现完整树索引、后代严重级别聚合、直接子节点展开和 PASS 迭代压缩。
增加纯级别过滤、子树限定搜索、运行时调用路径和响应脱敏。
补齐源码字段、关键字定义元数据、附件引用及其来源规则。
更新 MCP 文档、Windows 宿主配置、健康检查和相关 Skill 能力说明。
用历史问题基线和新的真实调用记录评估性能,再决定高级索引、分组、长消息分片和
tree_snapshot。
开发检查
uv run ruff check .
uv run pytest