使用 Flet MCP 服务器:为 LLM Agent 提供精确、版本相关的 Flet API 知识
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
Flet MCP 服务器(flet-mcp)是一个基于 Model Context Protocol(MCP)的服务器,它把 Flet 的真实 API 索引、示例工程、图标库和 CLI 帮助暴露给 LLM Agent 与 AI 编程助手。本文围绕 website/docs/cookbook/flet-mcp.md 展开,讲解安装、启动、客户端配置、工具组开关,以及如何在 Pydantic AI、FastMCP 等自有 Agent 中直接使用它,并结合仓库源码说明其底层实现原理。读完本文,你将掌握如何用flet-mcp消除模型幻觉,让 Agent 生成、重构出真正可运行的 Flet 代码。
为什么需要 Flet MCP:对抗训练数据漂移
LLM 的预训练数据会随着时间推移而过时:Flet 新增控件、属性签名变化、枚举成员改名后,模型仍可能输出旧 API,导致幻觉(hallucination)——编造不存在的控件、属性和枚举成员。flet-mcp的思路是把"知识查询"从模型记忆迁移到实时工具调用:Agent 按需查询真实 Flet API、搜索示例工程、查找图标、检查 CLI 选项。
它同时适用于两类场景:
- AI 编辑器内:Claude Desktop、Cursor、VS Code 等支持 MCP 的客户端;
- 自有 Agent:自己构建的、需要生成或重构 Flet 代码的 Agent 程序。
从仓库源码看,flet-mcp包(sdk/python/packages/flet-mcp)体积很小,核心逻辑集中在 server.py,它基于 FastMCP 构建,附带预生成的api.json(Griffe 内省产物)、图标元数据icons.json以及可选构建的 SQLite 索引mcp.db。包运行时只依赖fastmcp>=2.0.0(见 pyproject.toml),因此不安装 Flet 本体也能作为查询服务器运行。
安装
pip install flet-mcp安装后注册flet mcp命令(fletCLI 必须已安装——任何正常的 Flet 项目都已具备)。包内附带预构建的 API 索引,开箱即用,无需额外构建步骤。
补充说明:从 pyproject.toml 可以看到,flet-mcp要求 Python >= 3.10,并将fastmcp >=2.0.0作为唯一运行时依赖;构建索引所需的markdownify、griffe、flet、flet-cli被放在可选依赖组build中,只有需要重新生成数据文件时才安装。
启动服务器
默认使用stdio传输(大多数桌面 AI 客户端采用):
flet mcp或通过 HTTP 暴露:
flet mcp --transport streamable-http --port 8000从 CLI 命令实现 mcp.py 可以看到完整的参数面:--transport可选stdio(默认)或streamable-http,--port默认 8000,仅对 HTTP 传输生效。此外还有build子命令用于重建索引数据(--examples、--docs、--output),下文"构建数据文件"一节会展开。
配置 AI 客户端
大多数支持 MCP 的客户端通过一段 JSON 配置。以 Claude Desktop 的claude_desktop_config.json为例:
{ "mcpServers": { "flet": { "command": "flet", "args": ["mcp"] } } }Cursor、VS Code 等客户端在各自的 MCP 设置中使用相同的command/args结构,只是配置文件的存放位置与编辑入口不同。
工具组与开关
工具按组组织,通过服务器启动时读取的FLET_MCP_ENABLE_*环境变量控制开关。默认聚焦"反幻觉"起步组合——API与icons开启,其余关闭:
| 组 | 变量 | 默认 | 工具 |
|---|---|---|---|
| API | FLET_MCP_ENABLE_API | 开 | list_controls,get_api,get_enum,search_enum_members,enum_has_member |
| Icons | FLET_MCP_ENABLE_ICONS | 开 | find_icon |
| Examples | FLET_MCP_ENABLE_EXAMPLES | 关 | search_examples,get_example |
| CLI | FLET_MCP_ENABLE_CLI | 关 | get_cli_help |
文档搜索组(search_docs/get_doc)由FLET_MCP_ENABLE_DOCS控制,目前处于规划中但尚未启用——正在重构以索引基于 Docusaurus 的文档站点。
接受的"真值"为1、true、yes(大小写不敏感)。例如开启示例搜索工具:
FLET_MCP_ENABLE_EXAMPLES=1 flet mcp实现细节:在 server.py 中,_enabled()读取FLET_MCP_ENABLE_<name>并归一化为小写判断;_API_ON、_ICONS_ON默认"1",_EXAMPLES_ON、_DOCS_ON、_CLI_ON默认"0",据此构造_enabled_groups列表。活跃组还会写进服务器的启动指令(instructions)字符串,MCP 客户端若把这些指令转发给模型(例如 Pydantic AI 的MCPToolset(..., include_instructions=True)),模型得到的引导就与实际注册的工具保持同步。
注意:工具组开关与索引数据是两回事。开启EXAMPLES只注册工具,还需先执行flet mcp build --examples <path>生成 SQLite 索引;没有索引时工具正常注册但返回空结果。
各工具职责
| 工具 | 说明 |
|---|---|
get_api | 核心校验工具。按名称查找任意 Flet 符号——控件、服务、dataclass 类型(ButtonStyle、Padding等)、事件或枚举。对已安装的 Flet 版本而言,"not found" 是确定性结论。异步方法标记"async": true,每条目带"package"字段标明其所属 pip 包("flet"为核心,其余如"flet-audio"为扩展)。 |
list_controls | 浏览可用控件与服务,支持按类别/种类过滤。 |
get_enum | 获取枚举的成员。 |
search_enum_members | 按子串搜索大型枚举(Icons、CupertinoIcons)。 |
enum_has_member | 使用前校验某个枚举成员是否存在。 |
find_icon | 按关键字搜索 Material 与 Cupertino 图标,支持同义词匹配(如 "user" 能命中account_circle)。 |
search_examples | 按关键字搜索 Flet 示例工程,可选按平台过滤。 |
get_example | 获取search_examples返回示例的完整源码与元数据。 |
get_cli_help | 获取fletCLI 各命令及其选项的结构化帮助。 |
get_api:主要校验器的工作原理
get_api是设计上的"第一查询"工具。它的默认输出是紧凑的签名风格文本(而非 JSON),每个成员一行,例如:
Page (control) — High-level root control for an app view. bases: AdaptiveControl properties: bgcolor: ColorValue? — Background color of the page. multi_views: list[MultiView] = [] — The list of multi-views... events: on_route_change(RouteChangeEvent) — Called when route changes. methods: async push_route(route, kwargs) -> None — Pushes a new route...布局约定(api_store.py 的render_text实现):
- 符号名后的
(control)/(service)/(type)/(event)/(enum)标明命中桶; - 属性类型后的
?表示可选(可为 None); on_x(SomeEvent)表示处理器接收SomeEvent参数;async前缀表示方法必须被 await(调用它的事件处理器必须是async def);package: <name>行表示该类位于该 pip 包中,使用前须加入项目依赖——要把它提示给用户;无此行即核心flet,始终可用;DEPRECATED: <reason>表示不要使用,改用 reason 中指定的替代品;- 成员 docstring 被裁剪为第一句,
note:行提示如何下钻。
get_api还支持下钻与过滤参数:
member="push_route"—— 获取单个成员的完整未裁剪 docstring 与精确类型;query="border"—— 仅保留名称包含该子串(大小写不敏感)的成员;两者同时传入时member优先;- 名称冲突处理:少数名字被多个类共享(如 Text 控件与 canvas 的 Text shape),返回主条目,
note:行列出其余同名符号及其点分限定名,例如get_api("canvas.Text"); - 对枚举使用
member/query时,会内联解析为排序的成员搜索(等价于search_enum_members),而不是报错——例如get_api("Colors", query="RED");概念式图标查找("delete"、"user")优先用find_icon;大型枚举(Icons、CupertinoIcons)整体获取时截断为样本; - 错误以 JSON 对象返回(
{"error": ...}),有时附带available_members/available_files提示。
底层实现上,ApiStore懒加载捆绑的api.json(api_store.py),把 controls/types/events/enums/functions 五个桶构建为按名字索引的字典,并保留"一名多义"的全部候选,按桶优先级排序(_BUCKET_RANK:controls > types > events > functions > enums),同名时 canvas 模块符号排后。query=过滤还会递归走一遍基类(如 TextField 的 border 属性定义在FormFieldControl上),把继承命中归入inherited块返回——test_api_store.py 用Page继承AdaptiveControl的例子验证了这一点。
文本渲染选择签名风格而非 JSON,是刻意的:同样的信息量下字符数约少 44%(键名与引号在每个成员上重复),显著节省 token;需要结构化数据时可传format="json"。
图标搜索:find_icon
find_icon由IconStore(icons_store.py)支撑。图标名来自捆绑api.json中的Icons/CupertinoIcons枚举成员,而 Material 的同义词标签与流行度来自提交的data/icons.json(源自 Google fonts.google.com 的图标搜索元数据,Apache-2.0)。运行时消费者不安装flet,所以图标名不依赖 flet 包。
检索是纯内存倒排索引:名称 token 与同义词 tag 进入同一索引,命中加分;精确全名匹配额外加分;排序按"分数 → Google 流行度 → 名称长度 → 字母序"确定性展开,保证模型每次看到一致的结果。Material 的_OUTLINED/_ROUNDED/_SHARP风格变体在基图标也命中时会被折叠,避免一个图标占多个结果位。返回形如Icons.ARROW_BACK、CupertinoIcons.BACK的限定名。
枚举工具
get_enum(name):小枚举(< 50 成员)返回全部成员;大型枚举返回元数据与样本成员,并提示用find_icon()或search_enum_members()查找。search_enum_members(name, query, limit):按子串匹配,排序分三档——精确 > 前缀 > 子串,档内再按长度与字母序;Material 风格变体折叠。例如search_enum_members("Icons", "remove")返回REMOVE、REMOVE_CIRCLE、GROUP_REMOVE、BOOKMARK_REMOVE(test_api_store.py 验证)。enum_has_member(name, member):大小写不敏感地校验成员存在性,返回{"enum": ..., "member": ..., "exists": bool},供模型在写代码前确认枚举值有效。
示例与 CLI 工具
search_examples/get_example查询 SQLite 全文索引(mcp.db中的examples_fts,BM25 排序,权重 title=8、description=5、tags=4、controls=5、layout_pattern=6、features=4、search_text=2、code=1),get_example对小型示例整包返回,大型多文件示例先列出各文件大小,按 24,000 字符预算内联内容,剩余文件可通过filename参数逐个获取。
get_cli_help直接读取api.json中的cli段:无参数返回全部命令概览,带命令名返回详细 flags 与 options。
响应尺寸预算是个刻意的工程决策:工具输出会进入 Agent 对话历史并在后续每次 LLM 调用中被重新发送与计费,因此超大载荷被分页/截断并附下钻提示(server.py 注释:最大捆绑示例约 111k 字符)。
在自有 Agent 中使用
服务器本身是一个可导入的 FastMCP 实例,自定义 Agent 可直接消费它。
配合 Pydantic AI:
from pydantic_ai import Agent from pydantic_ai.toolsets import MCPToolset from flet_mcp import mcp agent = Agent("anthropic:claude-sonnet-4-6", toolsets=[MCPToolset(mcp)]) result = agent.run_sync("Create a Flet app with a login form")或通过 FastMCP 客户端进程内调用——无子进程、无传输。在导入flet_mcp之前设置FLET_MCP_ENABLE_*变量,使目标工具组完成注册;客户端把结构化结果反序列化到.data:
import asyncio from fastmcp import Client from flet_mcp import mcp async def main(): async with Client(mcp) as client: api = (await client.call_tool("get_api", {"name": "TextField"})).data print(api["kind"], api["package"], len(api["properties"])) asyncio.run(main())从源码看,flet_mcp/__init__.py仅导出一件事——from flet_mcp.server import mcp,即 server.py 中FastMCP("flet-mcp", instructions=...)的实例。这也解释了为何必须"先设环境变量、后导入":工具注册发生在模块导入时(if _API_ON:等条件装饰器),导入完成后开关已定型。
用 fastmcp CLI 验证工具
开发调试时可用 fastmcp 命令行直接调用服务器内的工具:
# 查看注册的工具 fastmcp list packages/flet-mcp/src/flet_mcp/server.py # 搜索示例 fastmcp call packages/flet-mcp/src/flet_mcp/server.py search_examples '{"query": "dropdown"}' # 获取完整示例代码 fastmcp call packages/flet-mcp/src/flet_mcp/server.py get_example '{"example_id": "controls_dropdown_styled"}' # 查询任意符号的 API 参考 fastmcp call packages/flet-mcp/src/flet_mcp/server.py get_api '{"name": "TextField"}' # 查找图标 fastmcp call packages/flet-mcp/src/flet_mcp/server.py find_icon '{"query": "settings"}' # 搜索大型枚举 fastmcp call packages/flet-mcp/src/flet_mcp/server.py search_enum_members '{"name": "Icons", "query": "arrow"}' # 获取 CLI 帮助 fastmcp call packages/flet-mcp/src/flet_mcp/server.py get_cli_help '{"command": "run"}'构建数据文件(进阶)
flet-mcp读取 Griffe 内省的api.json,以及(可选)示例与文档的 SQLite 索引。在 flet SDK 工作区内部构建,可保证每个 Flet 扩展包(flet-audio、flet-map等)都可导入——工作区把它们全部声明为成员,但需安装mcp-build依赖组才能拿到构建期依赖(markdownify、griffe):
cd sdk/python uv sync --group mcp-build uv run flet mcp build # 仅 api.json uv run flet mcp build --examples ./examples # 追加示例索引图标搜索元数据(data/icons.json)是提交入库的文件而非构建产物——它由 Google fonts.google.com 的图标元数据生成,仅当 Google 发布新图标时才需要刷新:
uv run python -m flet_mcp.build.icons文档索引当前暂缓:--docs标志仍期待 mkdocs 的search_index.json,而站点迁移到 Docusaurus + Algolia 后已不再生成该文件。DOCS工具组保持默认关闭;针对 Docusaurus 重建文档搜索被列为后续工作。
另请注意:在只安装核心flet的下游项目 venv 中运行构建也可行,但生成的api.json会缺少该 venv 中未安装的扩展包控件——索引器会对每个缺失包记录一行 "Failed to load" 并跳过。
源码位置速查
- 服务器与全部工具定义:sdk/python/packages/flet-mcp/src/flet_mcp/server.py
- API 索引查询与文本渲染:sdk/python/packages/flet-mcp/src/flet_mcp/api_store.py
- 图标搜索:sdk/python/packages/flet-mcp/src/flet_mcp/icons_store.py
- SQLite 索引访问:sdk/python/packages/flet-mcp/src/flet_mcp/db.py
- CLI 命令
flet mcp注册与参数解析:sdk/python/packages/flet-cli/src/flet_cli/commands/mcp.py - 单元测试(渲染、排序、继承查询、同名消歧):sdk/python/packages/flet-mcp/tests/test_api_store.py、sdk/python/packages/flet-mcp/tests/test_icons_store.py
- 官方用法文档:website/docs/cookbook/flet-mcp.md
小结
flet-mcp以极低的接入成本(一次pip install+ 一段 JSON 配置)把"模型记忆中的过时 Flet API"替换为"可实时查询的版本相关 API 知识"。核心设计包括:预构建的 Griffe API 索引保证离线可用与确定性结论;FLET_MCP_ENABLE_*按需裁剪工具面并把活跃组写入启动指令;签名风格文本输出大幅降低 token 消耗;预算分页保护对话历史不被超大载荷撑爆。无论是 Claude Desktop / Cursor / VS Code 等现成客户端,还是基于 Pydantic AI / FastMCP 的自有 Agent,都能用它获得准确、可验证的 Flet 开发能力。
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考