关于 flanner
flanner 是面向 Claude Code、Codex 等编码 Agent 的计划文件管理器,可通过 MCP 使用。它将计划集中存放于项目的 `.plans/`,自动版本化并防止意外提交,并提供浏览界面和历史记录。
主要功能
- 01集中管理 Markdown 计划
- 02自动版本化并保留历史
- 03将计划文件排除在 Git 提交外
- 04配置 Claude Code 与 Codex
- 05离线浏览和编辑计划
适用场景
- 01整理项目中的设计文档与迁移计划
- 02查看 Agent 对计划文件的修改历史
- 03在本地浏览和编辑项目计划
MCP 相关
flanner 通过 MCP 向 Claude Code、Codex 等客户端提供计划文件工具。客户端可由各自启动 MCP 服务,也可连接本地 HTTP 服务。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
45收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| project_id | any | 否 |
详细介绍
Flanner
一款面向 AI 编码 Agent 的计划文件管理器,通过 MCP(Model Context Protocol)接入 Claude Code 和其他助手。
为什么要用
AI Agent 不断编写 Markdown:设计文档、迁移计划、架构说明。文件很快就会堆积起来,散落在仓库各处,悄悄过时,还很容易被意外提交。Flanner 为这些文件提供统一的存放位置,在 Agent 修改文件时自动创建版本,并在你决定之前将它们排除在 Git 之外,同时还提供可浏览的阅读视图和审计记录。
不,我还是不信。那为什么要用?
这些计划文件会从两个方面同时堆积:一方面散落在本地的各个项目中,另一方面散落在项目管理工具的未关闭问题里。Flanner 是两者的汇合点,帮你整理磁盘上的文件,并关联每份计划所属的问题。
Flanner 以本地为先,团队使用时也依然如此。计划会通过加密连接直接在你的设备之间同步——没有服务器保存这些文件,也无需上传。托管服务端(Flanner Mesh)负责分配身份并决定谁可以读取哪些内容;它看不到计划内容,即使想看也无法读取。接下来,我们会支持与团队已在使用的工具建立便捷链接,涵盖产品跟踪器、聊天工具,以及 Notion 这样的第二大脑。
功能
- MCP 集成:向 Claude Code 和 Codex 提供计划文件工具。
- 自动添加标头和版本管理:每个计划都会添加 YAML 前置元数据,每次修订都会成为一个新版本,并保留完整历史记录。
- Git 保护:计划存放在
.plans/中,并自动从提交中排除。 - Agent 集成:
flanner init会配置 CLAUDE.md、AGENTS.md 和防护钩子,让 Agent 通过 flanner 保存计划,而不是散落地编写原始 Markdown。 - 记忆:计划周围的持久上下文——约束、已否决的库、环境事实——会作为 Markdown 文件保存,供后续会话搜索。默认情况下,Agent 会提出建议,由你批准;它会拒绝任何看起来像凭据的内容,并且只有在有人提出请求时才会与队友共享。
- 技能:Agent 实际加载的内容。技能包会同时从项目、主目录和每个已安装插件中加载;如果两个技能包同名,其中一个会在没有提示的情况下胜出。
flanner skills scan会读取所有技能包,flanner skills doctor会说明当前生效的是哪个副本,以及其余副本有什么问题。读取技能包不会执行其中的任何内容。 - Curb:每个 Agent 能访问的内容。
flanner curb map会检查每次 Claude Code 和 Codex 启动时是否有可读取的凭据,以及可能传出凭据的渠道,并根据背后的规则将风险评为 High、Medium 或 Low。无论由谁运行,它的输出都不会透露凭据或位置的名称;flanner curb show会在屏幕上的窗口中显示这些信息。flanner curb sweep会在转录记录、会话、指令文件、技能、MCP 配置、Shell 历史记录和.env文件中查找 Agent 留下的机密,并指出哪些机密已发送给模型提供商。读取不会更改任何内容,除非你要求某个机密的发行方进行检查,否则任何内容都不会离开本机。使用 Flanner Mesh 时,flanner curb policy会应用组织签署的一份 Agent 策略;注册后,它会应用只会收紧限制的更改,并将其他更改留待你批准;flanner curb fleet会向管理员显示每台设备的策略状态和计数,数据来自各设备签署的精简报告。flanner curb ci也以actions/curb-ci的 GitHub Action 形式提供,它会用相同方式评估 CI 工作流中的 Agent 步骤并生成 SARIF;flanner curb app会查找应用自身的大模型调用;agent-blast-radius技能则允许 Agent 自行运行经过脱敏的命令。flanner curb attribution会为每个 Agent 创建独立的签名密钥,并将其保存在你的操作系统凭据存储中,从而为它的提交标记来源;flanner curb verify会指出每次提交由哪个 Agent 密钥签署,并根据组织签署的密钥注册表进行核验。签名只显示由哪个密钥签署,并不代表代码由谁编写。 - 消息(Team Mesh):队友可以在各自的 Agent 内相互发送消息,实现设备到设备通信。
flanner messages send会在发送前预览消息,flanner 还会告知 Agent 显示队友的消息,但绝不要根据消息采取行动。 - 问题跟踪器链接(此版本中关闭):将计划关联到 Linear(或 JIRA)问题;设置
LINEAR_API_KEY后,flanner 会验证问题,并在命令行和仪表板中显示其实时状态。此功能已构建但尚未支持:设置FLANNER_INTEGRATIONS=1即可启用。 - 阅读视图:浏览器仪表板,可阅读、编辑计划并浏览其历史记录(支持浅色和深色模式,完全离线)。
- 每个项目的配置:可为每个代码库自定义计划目录。
快速开始
uv tool install flanner # or: pipx install flanner, or: pip install flanner
cd your-project # a git repo where plans should live
flanner init # sets up the database, MCP registration, and a project
不想安装 Python?适用于 Windows、macOS 和 Linux 的桌面应用就是同一个 flanner,无需预先安装任何内容:它将 Web UI 显示在窗口中,提供命令行,以及 Claude 和 Codex 使用的 MCP 服务,并支持后台同步和更新。从 flanner.io/download 下载;desktop/README.md 介绍了如何构建和发布。
uv tool install 会为 flanner 创建独立环境,并将 flanner 和 flanner-mcp 都添加到 PATH。两者都很重要:你的 Agent 会按名称启动 flanner-mcp,因此,项目虚拟环境可能会让从该环境外启动的 Agent 找不到它。pip install flanner 也可以使用,但有上述注意事项。
然后让你的 Agent 制定计划:
“为身份验证服务制定一份架构计划”
“显示这份架构计划的历史记录”
然后打开仪表板浏览计划:
flanner web --open-browser # http://localhost:8080
flanner init 可以安全地重复运行。它会检测你的 git 根目录、创建 .plans/、更新 .gitignore,并安装 Agent 集成。
三个 Agent、三个不同的文件,init 会一并处理,无需记住第二条命令。它会写入项目级 .mcp.json,供 Claude Code 读取;在用户级注册服务,并将服务注册到 Claude Desktop 的配置中;还会在 CLAUDE.md 和 AGENTS.md 中添加托管区块。Codex 会读取 AGENTS.md,并在 ~/.codex/config.toml 中注册 MCP 服务;如果已安装 Codex,init 会在其中添加 flanner 的条目;只有在无法安全编辑文件时,才会打印供你粘贴的两行内容。flanner status 会为每个 Agent 显示一行,并根据各 Agent 实际查找的位置进行检查;如果之后需要修复其中某个 Agent 的配置,flanner setup 会单独重新注册。
--setup 用于选择要配置的 Agent,并且可以重复使用:flanner init --setup codex 只注册 Codex,不做其他操作。--skip-claude 会在不注册任何 Agent 的情况下运行,但仍会写入仓库自身的文件。
要采用其他人已设置好的仓库?flanner init --sync 还会导入其中已提交的计划文件,让 flanner list 立即显示这些文件。
CLI 命令
flanner init [--project-root PATH] [--plan-dir DIR] # set up a project
flanner status # projects, plan files, db path
flanner list [--project NAME] [--output json] # list projects or a project's plans
flanner sync [--project NAME] [--dry-run] # import existing .plans/ files
flanner config NAME [--plan-dir DIR] [...] # change project settings
flanner web [--port 8080] [--host 127.0.0.1] [--open-browser]
flanner start [--port 8765] / flanner stop # MCP server in the background, over http
flanner peer start / flanner peer stop # serve plans to teammates in the background
flanner mem remember "..." --category fact # durable context for later sessions
flanner mem recall "..." # search what earlier sessions knew
flanner mem list / show ID / supersede ID --with "..." # browse, read, and correct
flanner mem mode [off|explicit|suggest|auto_safe] # how much this project captures
flanner mem share ID / flanner mem withdraw ID # give one to the team, or ask them to stop
flanner skills scan / flanner skills doctor # what your agents load, and what is wrong
flanner skills list [--all] / inspect NAME # browse them, or read every copy of one
flanner skills observe enable / flanner skills report # record which get used; init asks
flanner skills adopt NAME / install HASH / rollback ID # keep a copy, install it, put it back
flanner skills share HASH / transfers / import ID # send one to the team; receiving is not installing
flanner curb map [--agent A] [-- LAUNCH ...] # what each agent launch can reach
flanner curb show # names and locations, in a window
flanner curb inventory # agents, MCP servers, hooks, jobs
flanner curb sweep [--validate] # secrets agents left behind (needs flanner[sweep])
flanner curb forget # delete Curb's reports and digest key
flanner curb fix [--dry-run|--undo] # close what agents reach, after your OS says yes
flanner curb test # prove each block with decoys (costs tokens)
flanner curb decoys [--renew|--remove] # the decoys the tester planted
flanner curb scrub FILE [--dry-run] # replace rotated secrets in a file (no undo)
flanner curb log [--enable|--disable|--verify] # each tool call's metadata, hash-chained and signed
flanner curb observed # what each agent has been seen using
flanner curb policy [--check-in|--enrol|--approve] # your organization's signed agent policy
flanner curb fleet # every device, checked by its own signature (admins)
flanner curb ci [PATH] [--sarif F] [--fail-on L] # agent steps in CI workflows, as SARIF
flanner curb app [PATH] [--sarif F] # LLM calls in an app's Python code
flanner curb attribution [--setup|--rotate] # sign each agent's commits with its own key
flanner curb verify [REV|RANGE] # which agent key signed each commit
flanner register [--force] / flanner unregister # MCP registration with Claude Desktop
flanner claude-info # integration status
大多数 MCP 客户端会通过 stdio 启动自己的服务副本,无需使用 start 或 stop。这些命令适用于只支持 http 的客户端、需要让两个编辑器共用一个服务,或独立使用 flanner 的场景。服务会绑定到 127.0.0.1,没有任何选项可以扩大绑定范围:每个工具都拥有启动者的全部权限,且不会对调用者进行身份验证。
计划文件格式
每个托管计划都带有由工具生成、无需手动编写的 YAML frontmatter:
---
mcp_plan_file: true
project_id: 3d816ecd-489a-4fa0-abe2-15ec93f60d5a
plan_file_id: 59c34f9c-8471-47fc-97f2-8dcfefa15434
plan_name: architecture
version: 2
created_by: claude
---
# Architecture Plan
Your plan content here...
Web 界面

由服务器渲染的仪表板,无需构建步骤,可离线使用:
- 仪表板(
/):项目、统计数据和近期活动 - 项目详情(
/projects/{id}):项目计划,支持分页 - 计划查看器(
/plans/{id}):渲染后的 Markdown、版本选择器和 frontmatter - 编辑器(
/plans/{id}/edit)和版本历史(/plans/{id}/history)
Web UI 绑定到 127.0.0.1,不进行身份验证。请勿将其暴露给 localhost 以外的地址。
数据存储位置
- 目录(SQLite):
~/.flanner/data.db,可通过FLANNER_HOME或FLANNER_DB_PATH更改 - 计划文件:仓库中的
.plans/,已加入 git 忽略,文件名依次为name_v1.md、name_v2.md等
问题跟踪器链接(Linear、JIRA)
将计划文件链接到问题,让计划和对应工单一起流转。功能已构建,
但尚未支持:相关命令处于隐藏状态,除非设置了
FLANNER_INTEGRATIONS=1,否则不会运行。
flanner linear auth # verify LINEAR_API_KEY, print MCP snippet
flanner linear config PROJECT --workspace acme # linear.app/acme
flanner linear link PLAN --issue ENG-123 [--notes ...] # link a plan to an issue
flanner linear links [--project PROJECT] # list all links
flanner linear show PLAN [--project PROJECT] # links for one plan
flanner linear unlink PLAN [--issue ENG-123 | --all]
flanner linear refresh PLAN # re-pull title/state (needs API key)
在设备间同步计划
flanner peer serve # answer authorised peers
flanner peer pull <device-id> [--project NAME] # pull what a peer holds
flanner peer status [<device-id>] # how this device is reached
工作区是一个团队,而一个团队拥有多个代码库,因此拉取的计划需要有存放位置。你已有的计划会存放在其所在的位置;否则,由 --project 或你运行命令时所在的项目决定。如果同一工作区中的两个本地项目都符合条件、无法确定选哪个,系统会报告问题,而不会猜测;下一次指定项目的拉取操作会写入上次无法写入的内容。
peer serve 不会打开监听端口。它会主动发起连接,并通过该连接响应,因此不需要端口转发、VPN 或管理员权限。设备通过公钥而非地址相互发现。
能够被访问并不意味着获得授权。调用方需要提供签名请求,以及同时标明其设备和工作区的授权凭证;收到的每个制品都会根据其作者的密钥进行验证,而不是根据转交该制品的对等端进行验证。因此,与之同步的对等端并不代表可信任。
peer status 可以回答慢速同步时产生的问题:连接是直连还是经中继?两者都能正常工作。中继速度较慢,通常意味着防火墙阻止了连接打洞。
连接会尽可能直连,只有必要时才使用中继。传入 http 地址而不是设备 ID,即可连接到网络中已有的对等端;另一端需要运行 flanner peer serve --http。
平台。 要连接没有地址的对等端,需要使用 iroh 传输层。该传输层提供适用于 Apple Silicon 架构的 macOS、x86-64 和 arm64 架构的 Linux,以及 x86-64 架构的 Windows 的构建版本。它仅为这些平台声明,因此 flanner 在所有平台上都可以安装;在其他平台上,iroh 不会安装,flanner peer status 也会说明这一点。flanner 的其他功能不受影响,共享网络上的对等端仍可通过地址同步。消息是个例外:消息始终通过 iroh 传输,因此两台设备都需要安装它。
Alpine 和其他 musl 发行版是个例外:Linux 构建版本与它们不兼容,因此安装会失败,而不是跳过该依赖。请使用基于 glibc 的镜像,或使用 --no-deps 安装并自行添加其余依赖。
架构
分层规则由 tests/test_architecture.py 强制执行:
- 基础层(
exceptions、utils、frontmatter、git_integration、jira_utils、linear_utils)不会从包的其他部分导入内容;linear_apiGraphQL 客户端只额外导入exceptions - 数据层(
database、storage)仅依赖基础层 - 组合根(MCP 的
server、web、cli)负责串联所有组件,彼此之间不会相互导入(cli除外,它会启动另外两个组件)
在 Windows AMD64、Python 3.13.1 和本地 SSD 上的 SQLite 环境中测得。使用 python benchmarks/bench.py 复现。
| 操作 | 中位数 | p95 | 规模 |
|---|---|---|---|
create_project | 35.9 ms | — | 一个项目 |
create_plan_file | 62.7 ms | 203.0 ms | n=100,每个正文约 2.4 KB |
list_plan_files | 2.6 ms | 7.0 ms | 100 个计划,n=20 |
冷启动使用相同方式测量:
| 命令 | 中位数(n=7) | 之前 |
|---|---|---|
flanner --version | 397 ms | 1470 ms |
flanner --help | 342 ms | 1470 ms |
每条命令都会导入 SQLAlchemy,包括那些从不打开存储的命令;在 1.1 s 的导入耗时中,它占了 630 ms。现在通过轻量封装延迟到首次使用时才导入,因此不接触数据库的命令无需为此付出代价。flanner list 会打开存储,因此它的耗时是实际工作,而非额外开销。
现在两者都低于 500 ms 的门槛。这些数据来自可编辑安装,它会增加约 80 ms 的导入查找器开销;普通的 pip install 不会有这部分开销。
flanner list 不再列在此表中。它会打开存储,因此耗时来自实际工作,而非启动;将它与两个什么都不打开的命令并列,会引发不应有的比较。
这些数据来自 python benchmarks/bench.py,它测量的是已安装的控制台脚本,而不是 python -m flanner.cli——两者并不相同,而人们实际输入的那个才值得报告。CI 会将每次运行与 benchmarks/baseline.json 比较,超过 3 倍就会失败;这能捕捉数量级的回退,却发现不了更细微的问题;共享运行器在相同代码下的计时会有两倍的波动。
出现问题时
flanner --verbose doctor # where the time went, per step
flanner doctor --report # a scrubbed summary to paste into an issue
--verbose 会在命令执行后打印耗时明细,因此“为什么这么慢”无需分析器也能找到答案。
doctor --report 会打印版本、平台、存储大小、目录计数以及网格传输是否已安装。不会包含路径、计划名称或计划内容——本地日志中记录项目名称没问题,但将其粘贴到公开问题中则不行。即使存储无法打开,它也能运行;这正是你最需要它的时候。
MCP 服务会将日志保存在 ~/.flanner/mcp.log:每次工具调用占一行,记录结果和任何错误。这个界面没有人监看,因此如果 Agent 遇到错误后悄悄绕过,原本不会留下任何痕迹。计划正文绝不会写入该文件;flanner peer serve 也会将它处理的请求记录到同一文件中。
你的计划、记忆和技能绝不会离开你的设备。 除非你主动启用,否则 flanner 不会发送其他任何内容。请参阅flanner 会发送什么。
flanner 会发送什么
默认情况下什么都不会发送。两项功能可分别通过各自的命令开启。
版本检查在运行 flanner init 时会单独询问。崩溃报告也会如此,但要等到有接收地址后才会询问:此构建版本没有报告接收地址,因此 init 不会询问是否发送崩溃报告,也不会发送任何内容。
| 发送到哪里 | 包含哪些内容 | 如何关闭 | |
|---|---|---|---|
| 版本检查 | pypi.org,每天一次 | 请求获取 flanner 的公开版本列表。不包含任何关于你或你工作的信息。 | flanner updates off |
| 崩溃报告 | 通过 Sentry(EU)发送给 flanner 的开发者 | 错误类型;错误在 flanner 中发生的位置(模块、函数、行号、相对于软件包的路径);flanner 版本、操作系统、Python 版本和 flanner 的安装方式;发生崩溃的界面及命令名称。 | flanner crash-reports off |
崩溃报告绝不会包含错误消息、局部变量、源代码行、命令参数、完整文件路径、你的用户名或机器名,也不会包含任何可识别人数或统计人数的信息。flanner crash-reports show 会准确显示等待发送的内容,或上次发送的内容。报告由独立的后台进程发送,绝不会由发生崩溃的命令发送。无论你之前如何选择,设置 DO_NOT_TRACK=1 或 FLANNER_CRASH_REPORTS=0 都会关闭崩溃报告。
计划、记忆和技能的内容只会通过 Flanner Mesh,直接传输到你自己团队的设备。
退出代码
脚本需要区分“修正命令”与“这台机器出故障了”,因此二者使用不同代码:
| 代码 | 含义 | 重试有用吗? |
|---|---|---|
0 | 已成功 | — |
1 | 你请求了无法执行的操作:项目不存在、无权访问、工作区 ID 不属于你 | 只有更改命令后才有用 |
2 | 底层机器发生故障:磁盘、权限、无法打开的存储 | 没用 |
工作原理
Agent 会调用 get_plan_config 来了解计划的存放位置,然后调用 create_plan_file_tool 或 update_plan_file_tool 来编写计划。Flanner 会将文件放入项目的计划目录、添加标头并递增版本号。文件保存在 .plans/(已加入 git 忽略列表),因此不会意外进入提交。
不会清理任何内容,也不会删除任何内容。 每个版本、评论和审查决定都会保留。存储只追加、不修改,没有清理命令;Settings 页面会显示其占用的字节数,让这一取舍清晰可见,而不是想当然。删除也遵循同样的设计:flanner retire <plan> 会要求所有对等设备停止显示和提供某个计划,--restore 可以撤销此操作,但这只是一项由其他设备遵守的声明,而非真正的删除。运行此命令时处于离线状态的队友,会保留内容直到下次同步;已经持有这些字节的任何人也会继续持有它们。对于分散在你无法控制的机器上的只追加存储,这是能够诚实作出的最有力承诺,因此我们在此作出这一承诺。
让 Agent 按规矩行事。 MCP 工具规定了如何操作;flanner init 还会安装两层机制,确保 Agent 实际使用这些工具。它会在 CLAUDE.md 和 AGENTS.md 中写入受管理的区块(Claude Code 和 Codex 每个会话都会读取其中的指导),并安装 flanner-plan 技能,让 Agent 知道要通过 flanner 来处理计划文档。此外,guard-write PreToolUse hook 会拒绝对计划目录的任何原始写入,并引导 Agent 使用 create_plan_file_tool,因此即使它忽略指导,计划也无法以非托管 Markdown 文件的形式写入。该 hook 遇到故障时会放行,并且绝不会阻止其他位置的写入。
路线图
已在 0.9.0 版本发布:点对点同步、共享工作区,以及队友之间的评审。计划会直接在设备之间传输;不会上传任何内容。请参阅 Flanner Mesh,了解其工作方式和费用。
此后已发布:通过服务器发送事件在 Web UI 中实时更新;为无法直接连接的节点提供中继回退方案;以及在 0.12.0 版本中推出的 Flanner Memory 和 Flanner Skills。
接下来计划:
- 对计划正文进行全文搜索。命令面板目前会为名称建立索引;计划中的文本暂时还无法搜索。
- 链接到产品跟踪工具、聊天工具,以及 Notion 等第二大脑
- 运行技能对比,而不仅仅是存储对比结果。
flanner skills eval会记录由测试框架或人员生成的结果;目前还无法自行运行针对模型和测试框架的测试套件。 - 等有了值得信赖的接口后,为 Claude Code 以外的 Agent 提供观测能力。在此之前,Skills 会将用量报告为未知,而不是零。
我们没有托管计划内容的打算。目录会留在你的机器上。这是设计决策,并非等待资金支持的里程碑。
贡献
设置、CI 门禁、如何运行单元测试和浏览器测试、基准测试以及发布流程,详见 CONTRIBUTING.md。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。