Skip to main content
Glama

tutu-mcp-proxy

lint lint-pages tests pages

mcp.tutu.ru 之前的压缩/接地 MCP-прокси,为 Туту 黑客马拉松(第 2 赛道——“工具优化”)而做。同样的 16 个工具,同样的行为,外加:

  • 精简的常驻目录。 真实服务器上的 tools/list 在第一次搜索前就约有 108 KB(执行 uv run python tutu.py measure 可验证,并且可用 fixtures/ 复现)。三个最重的工具(search_railget_rail_seatmapsearch_hotels)获得一个简短顶层 description;被裁掉的文案不会丢失,而是移入成对 get_<domain>_instructions调用结果中(tutu_mcp/proxy/compact_tools.py)——只有真正读取该结果的会话才会付出代价。inputSchema 在任意位置都未被触碰。

  • check_groundedness 将回答草稿与它所依据的 tool_result 进行确定性比对:从文本中抽取价格/时间/列车航班号/链接,并检查它们是否真实存在于 JSON 中,无需任何 LLM 评判者(tutu_mcp/groundedness.py)。

  • 对空结果的说明。 最常见的失败:代理(агент)把过滤后为空的搜索结果读成“这趟列车不运行”,而工具只是返回了在售的选项。Туту 自己的计数器 meta.post_filter_dropped_* 能指出是哪个过滤条件清空了列表——代理把它们展开成一句话并附加到结果上(_empty_result_note),让代理承认事实,而不是去猜测它从未获得的时刻表(tutu_mcp/proxy/empty_results.py)。

  • 前提门槛 + assess_request check_groundedness 检查回合的输出,而这是输入:用于收窄搜索的取值必须来自用户或之前的 tool_result。代理凭空捏造的过滤条件(经典场景:默默假定活动结束时间,并按这个时间过滤晚班车次)会得到 clarification_required 而不是数据(tutu_mcp/premises.py)。

  • Mock 模式。 用已录好的 fixtures 响应替代真实服务器——可以随时随意运行,不消耗黑客马拉松的共享速率限制。

追踪查看器

每次 eval 运行都会变成一个自包含 HTML 文件:双击即开,无需服务器,也无需网络。已发布的可视化展示见 https://trum-ok.github.io/tutu-mcp-hackathon/trace-viewer.html

追踪查看器:一次运行的指标头部和单个场景的拆解

make viewer        # из последнего настоящего прогона эвалов
make viewer-demo   # из рукописных демо-трейсов — без модели и без ключа

在界面中:概览模式——把全部场景 × 变体的矩阵放在一张表里;只看失败把列表收窄到出问题的项;再一个并排展示同一场景的两个变体,并高亮两者不一致的检查。点击响应中任意高亮值,会打开一个抽屉,显示该值取自的服务端响应片段;如果它不存在于任何响应中,则直接明确说明。合成运行(demo:/scripted:)会带“非真实测试”的琥珀色徽标——不会把手写演示与真实测量混淆。

它如何构建——见 docs/deploy.md

Related MCP server: Yourttoo MCP Server

结果

gpt-5.6-luna 上用 --effort low 跑了四次,每次 22 个场景,时间为 2026 年 8 月 19 日。多次运行之间的分散来自模型自身:后端相同,场景集也相同。

指标

baseline

proxy

工具暴露面,tokens

25 269

15 364

同样,按字节计

115 329

74 971

任务成功

17–18 / 22

19–21 / 22

断言的合理性

97–98 %

99 %

每次运行中的虚构断言数

4

1

每次运行输入 tokens

3.3–4.4 百万

减少 0.43–0.67 百万

前提门槛触发次数

0

8–12

多余澄清提问

0

0

关于虚构断言这一行,应该先看绝对数字:189 条可检查断言中的 4 条和 184 条中的 1 条,对应 97.9% 与 99.5%,差距看起来像噪声。而绝对数量上,它意味着到达用户那里的错误事件少了四倍——用户接收的正是错的事实,而不是比例。百分比的分母是“可检查断言”:用户自己指定的阈值(“低于 3000 卢比”)不用在 payload 里再被确认,也不计入分母。

工具暴露面的节省是 39%,而且它不依赖每一次 run:这是一个静态数字,代理在每次会话的第一次搜索之前都要花掉它。其余所有变化都来自模型行为,因此给出的是一段区间。

最后一行一点也不比第一行不重要:门槛在每次运行中触发 8–12 次,但与此同时从未一次没在不需要提问的场景上多问一句(负向控制场景 no_overask 加检查 did_not_over_ask)。一个会对所有东西都去追问的机制,get到完美的 premise 指标,却会毁掉产品。

两个变体在五个场景中有所分化,而且这五个场景全部由 proxy 赢下:空的过滤结果不再被读成“列车停运”,星期几的拼写错误在搜索前就能被发现,默默带入的客人数量被门槛拦下,相邻座位用正确的工具来查找。proxy 唯一稳定缺陷是 multitransport_basic:代理计算出价格差额(2 275,07 − 1 700 = 575),它的两个输入都已被 payload 验证,但这个数字本身并不存在。确定性检查无法把这样的算术同错误的算术(例如把酒店价格乘以住宿天数——这是另一个场景,在那里确实是错误)区分开;这是该方法的边界,而非代理的缺陷。

为了报告的诚实,有两件事需要说明:夹具失配与工具本地错误是分别统计的——记录里的缺口不应被理解成 Туту 跑挂了;以及** token 数字如果估算值,就会标上 ~**。OpenAI 没有 token 计数的端点,精确数字只能来自一次真实试运行(usage.prompt_tokens);而 --estimate-tokens 会用 tiktoken 的离线估计代替。

模型与推理强度按整次运行传入(--model/OPENAI_MODEL--effort/OPENAI_EFFORT);两者都不传时,reasoning 字段完全不发送,模型使用自己的默认值——这和显式 --effort none 不是一回事。runner 默认指向 /v1/responses;对当前带推理能力的模型,Chat Completions 不能与 function calls 同时使用;--api chat 用于没有 /v1/responses 的 OpenAI 兼容网关。适配器在做 fixture 匹配时会忽略来自 inputSchema 的默认值(模型总会写 page: 1sort: "price_asc" 等,而人在录制 fixture 时不会写这些)——否则几乎每次模型调用都会发生在父匹配。

具体一次运行如何组织,每个指标到底在算什么,以及 harness 为什么在 CI 里有自检——见 docs/evals.md

快速开始

需要 uv 和 Python ≥ 3.13(uv sync 会安装它)。

git clone https://github.com/Trum-ok/tutu-mcp-hackathon
cd tutu-mcp-hackathon
uv sync
uv run python tutu.py serve            # mock-режим (по умолчанию) — http://127.0.0.1:8800/mcp
TUTU_PROXY_MODE=live uv run python tutu.py serve   # проксирует настоящий mcp.tutu.ru

任意 MCP 客户端都可以连接到 http://127.0.0.1:8800/mcp(Streamable HTTP,无鉴权,与上游一致)。下文中的 <URL> 既可以是这个地址,也可以是已部署的代理地址(见 docs/deploy.md)。

claude mcp add --transport http tutu <URL>          # Claude Code
// Cursor · ~/.cursor/mcp.json
{ "mcpServers": { "tutu": { "url": "<URL>" } } }

// Claude Desktop · claude_desktop_config.json — через mcp-remote, он не умеет HTTP напрямую
{ "mcpServers": { "tutu": { "command": "npx", "args": ["-y", "mcp-remote", "<URL>"] } } }

应该看到什么。 日志里有两行:模式和监听地址。客户端连接后应被列出 18 个工具:16 个原生 Туту 工具,加上 assess_requestcheck_groundedness。如果只有 16 个,说明客户端连的是 Туту 本身,而不是 proxy。

削减了多少

tools/list:110 164 → 79 411 字节(−27.9 %);如果连 initialize 时两侧的说明一起算,则为 −33.1 %(proxy 输出自己的说明块只有 1.9 KB,而 Туту 是 11.2 KB)。这两个数都已加入 proxy 自己的两个工具(assess_request 1 313 字节,check_groundedness 1 100 字节)。

目录按层的拆分、明确标出的压缩代价,以及我们刻意不越过的边界,见 docs/compaction.md

文档

更贴近用户视角的说明是单独的一页:make docs 会在 site/index.html 下生成,也可以直接打开已发布页:https://trum-ok.github.io/tutu-mcp-hackathon/

文件

内容

docs/findings.md

对真实服务器的原生测量数据,以及启动这个项目的原因

docs/compaction.md

具体压缩了什么、付出的代价是什么、哪些事情没有做

docs/evals.md

Eval harness 的结构、fixture、一次运行的完整产出

docs/structure.md

仓库结构,以及依赖的方向

docs/configuration.md

环境变量,以及所有 make 目标

docs/deploy.md

Docker、Render、GitHub Pages,以及两个页面的构建

Команда rezo

  • Артамонов Аркадий (@OpSonata)

许可

MIT

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • TravelMind: 8 MCP tools for travel (12306 trains, flights, hotels, geocode, planning, policy).

  • AI marketplace — flights, tours, activities, transport & more via MCP. No auth required.

  • Geo-based flight search MCP server. Find more flights between any two places on earth

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Trum-ok/tutu-mcp-hackathon'

If you have feedback or need assistance with the MCP directory API, please join our Discord server