Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- gitnexus:start -->
# GitNexus — Code Intelligence

This project is indexed by GitNexus as **mcp_flutter** (4644 symbols, 10513 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
This project is indexed by GitNexus as **mcp_flutter** (4681 symbols, 10358 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.

> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.

Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@

### Added

- `fmtk` short CLI alias for `flutter-mcp-toolkit`, including release artifacts and install script smoke checks.
- Gating CI: `make check-intentcall-integration` + `.github/workflows/intentcall_eval.yml` job `intentcall-integration` (full intentcall matrix, contracts, skills grep, migrate/init/codegen `--check`).
- `make macos-validate-runtime` helper (`tool/evals/run_macos_validate_runtime.sh`) for I5 macOS dogfood.
- intentcall: `xsoulspace_lints` (`library.yaml` / `app.yaml`); `make analyze`; pre-release warnings on all packages ([intentcall/PRE_RELEASE.md](intentcall/PRE_RELEASE.md)); IntentCall consumer guide.
Expand All @@ -91,7 +92,8 @@

- Raised workspace Dart SDK floor to `>=3.12.0 <4.0.0` across packages and updated fixture expectations.
- Added Flutter SDK floor `>=3.44.0 <4.0.0` for Flutter packages (`mcp_toolkit`, `flutter_test_app`) and bumped server Docker toolchain images/checks to `dart:3.12.0-sdk`.
- `ToolRegistration` / `ResourceRegistration` canonical types moved to `intentcall_mcp`; kernel re-exports (extract-friendly).
- **Breaking:** `mcp_server_dart/lib/flutter_mcp_core.dart` no longer promises compatibility for removed private session/state/snapshot internals. Downstream code should import `intentcall_session` for `IntentSessionManager`, `StateStore`, `StateLockManager`, `SafeFileWriter`, and `IntentSnapshotStore`; Flutter MCP keeps only its server-local `FlutterSessionConnector` adapter.
- `ToolRegistration` / `ResourceRegistration` canonical types moved to `intentcall_core`; kernel re-exports (extract-friendly).
- Dogfood harness paths use `--dart-define=INTENTCALL_HARNESS_ROOT` / `INTENTCALL_VISUAL_RECONSTRUCT_ROOT`.
- `MigrateAgentEntriesMigrator` moved to `intentcall_core` (shared by CLI and MCP tool).
- `intentcall_testing`: ecsly-style builder → `invokeWire` → `AgentResult.envelope` test.
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ _Inspect and drive a running Flutter app from your AI assistant._

`flutter-mcp-toolkit` is a Dart MCP server + Flutter package that lets AI Agents (Codex, Zed, Cursor, Intent, Claude Code, Cline, etc..) take (semantic snapshots, tap widgets, type into forms, hot-reload, and read logs from a Flutter app) or create __its own tools and resources at runtime__ using MCP Toolkit — without leaving the conversation and work with Flutter apps in closed feedback loop - see example of it described in [OpenAI Agentic Harness](https://openai.com/index/harness-engineering/).

![Watercolor comic infographic explaining flutter-mcp-toolkit: install fmtk, add it to a Flutter app, connect an AI agent, then inspect, tap, reload, and prove changes in a close feedback loop.](docs/assets/flutter-mcp-toolkit-infographic.png)

The picture's story: the toolkit gives an AI assistant a shared window and control loop into a running Flutter app, so it can inspect state, act like a user, hot reload, read proof, and use custom tools from your app instead of guessing.

![View Screenshots](docs/view_screenshots.gif)

> ![NOTICE]: Version 4 is currently a prerelease train. Use `4.0.0-dev.2` only if you are intentionally testing the new architecture; otherwise stay on the latest stable 3.x release until `4.0.0` is promoted.
> ![NOTICE]: Version 4 is currently a prerelease train. Use `4.0.0-dev.5` only if you are intentionally testing the new architecture; otherwise stay on the latest stable 3.x release until `4.0.0` is promoted.

## Get started in 4 steps

```bash
# 1. Install the binary
curl -fsSL https://raw.githubusercontent.com/Arenukvern/mcp_flutter/main/install.sh | bash
# Installs flutter-mcp-toolkit plus the short fmtk alias for repeated CLI loops.

# 2. Add the toolkit to your Flutter app
cd my-flutter-app
Expand Down Expand Up @@ -77,7 +81,7 @@ Maintainers submitting to official stores: [marketplace submission runbook](docs

## What it does

The toolkit exposes 27 MCP tools (under the `fmt_*` capability prefix) across four categories:
The default toolkit surface exposes 30 MCP tools under the `fmt_*` capability prefix across four categories:

- **Inspection** — semantic snapshot, view details, errors, screenshots, VM info
- **Interaction** — tap, scroll, type, fill forms, hot-reload, navigate, wait_for
Expand Down
102 changes: 102 additions & 0 deletions decisions/0012_fmtk_cli_alias_and_harness_boundary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# ADR 0012 — `fmtk` CLI alias and harness boundary

- **Status:** Accepted
- **Shipped:** Unreleased
- **Authoritative source:** `mcp_server_dart/pubspec.yaml`, `install.sh`, `tool/release/build_release_artifacts.sh`

## Context

`flutter-mcp-toolkit` is explicit and searchable, but it is long for repeated
agent and terminal loops. The MCP tool surface already uses the compact `fmt_`
capability prefix, so agents and developers naturally reach for a shorter CLI
handle when running `doctor`, `exec`, `batch`, and `validate-runtime`.

The short name cannot be too clever:

- `fmt` collides with the standard Unix text formatter (`/usr/bin/fmt` on
macOS).
- `fmcp` is readable, but a PyPI package with that name already exists.
- Renaming the canonical binary would break install docs, plugin manifests, and
searchability.
- Shipping many aliases increases docs and support surface.

At the same time, `scripts/run_exec_sweep.sh` showed a second pressure: repeated
debug/eval batteries want compact commands and good logging, but they should
not turn every step into a new public CLI or MCP verb. Repeatable scenario
documents belong in `flutter_harness`; the toolkit should stay focused on live
Flutter command primitives, CLI/MCP parity, diagnostics, and runtime validation.

## Decision

Ship `fmtk` as a short CLI alias for `flutter-mcp-toolkit`.

`fmtk <args>` runs the same entrypoint as `flutter-mcp-toolkit <args>`. The long
name remains canonical in install, onboarding, plugin config, marketplace, and
PATH troubleshooting docs. The MCP server binary remains
`flutter-mcp-toolkit-server`; package names, MCP registry keys, and MCP tools
continue unchanged. MCP remains the typed `fmt_*` surface. We do not add a
generic MCP `run_tool`.

## Considered Options

- **`fmt` alias:** rejected because it collides with the standard Unix text
formatter (`/usr/bin/fmt` locally).
- **`fmcp` alias:** rejected because `fmcp` already exists on PyPI.
- **Both `fmcp` and `fmtk`:** rejected because multiple short aliases enlarge
docs, support, completions, and install smoke surface without enough AX gain.
- **Rename `flutter-mcp-toolkit`:** rejected because the long name is still the
searchable canonical identity for installs, plugin configs, registry keys,
and onboarding.
- **`fmtk` alias:** accepted because it is compact, reads as Flutter MCP
Toolkit, and no checked pub.dev/PyPI package or unscoped npm package conflict
was found for this Dart CLI alias.

Debug/eval workflows should first use existing surfaces:

- `--log-level debug`
- `--output-dir`
- `--save-images`
- `doctor --json`
- `validate-runtime`
- `batch`
- `exec --name diagnose` / diagnostics bundle

If a debug/eval battery becomes reusable across projects, graduate it to
`flutter_harness` as Harness Script or a harness example instead of adding a
scenario language to `mcp_flutter`.

## Consequences

**Good:**

- Agents and developers get shorter repeated commands: `fmtk doctor --json`,
`fmtk exec --name status --args '{}'`, `fmtk batch ...`.
- The explicit `flutter-mcp-toolkit` name remains stable for install,
searchability, and docs.
- `mcp_flutter` and `flutter_harness` keep a cleaner boundary: primitives here,
reusable scenarios in the harness repo.

**Bad:**

- Release and install artifacts now have one more binary to build, smoke test,
and document.
- Users may ask whether `fmtk` or `flutter-mcp-toolkit` is preferred; docs must
consistently call `fmtk` the short alias.

**Neutral:**

- Existing MCP clients, plugin configs, package names, and `fmt_*` tool names do
not change.

## Notes

- Name-collision check at decision time: `fmt` is a local system command;
`fmcp` exists on PyPI; no checked pub.dev/PyPI package or unscoped npm
package conflict was found for `fmtk` as this Dart CLI alias. Scoped npm
packages and other ecosystem uses, including Factorio Mod Tool Kit, do not
block a local Dart binary alias.
- Sources checked: [PyPI `fmcp`](https://pypi.org/project/fmcp/),
[pub.dev `mcp_toolkit`](https://pub.dev/packages/mcp_toolkit), and
[Flutter MCP server docs](https://docs.flutter.dev/ai/mcp-server).
- Harness-side boundary is recorded in
`flutter_harness/decisions/0003_toolkit_primitives_and_harness_scenarios.md`.
2 changes: 1 addition & 1 deletion decisions/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Architectural decisions (Flutter MCP Toolkit)

ADRs for the MCP server, capability kernel, and `fmt_*` tool surface (0001–0005).
ADRs for the MCP server, capability kernel, `fmt_*` tool surface, and CLI/harness boundaries.

Published copy for [docs.page](https://docs.page): symlink `docs/decisions/` → this folder.
1 change: 1 addition & 0 deletions decisions/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ day-to-day docs live under [Core Reference](/core/project_architecture) and
| [0008](/decisions/0008_web_agent_invoke_js_only) | Web agent invoke — JS-only path | Accepted | Unreleased |
| [0010](/decisions/0010-intentcall-extract) | intentcall Phase 7 — monorepo extract and publish | Accepted | Unreleased |
| [0011](/decisions/0011_dogfood_tracker_evidence_split) | Dogfood tracker vs `.showcase` runtime artifacts | Accepted | Unreleased |
| [0012](/decisions/0012_fmtk_cli_alias_and_harness_boundary) | `fmtk` CLI alias and harness boundary | Accepted | Unreleased |

## Format

Expand Down
4 changes: 2 additions & 2 deletions docs/NORTH_STAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@

## Distribution

- **Ship:** `install.sh` → `flutter-mcp-toolkit` + `flutter-mcp-toolkit-server`.
- **pub.dev:** Flutter MCP Toolkit packages ship on one version train. `VERSION`, `mcp_toolkit`, `mcp_server_dart`, capability/core packages, runtime metadata, and plugin manifests must agree (currently `4.0.0-dev.1` for the breaking prerelease train).
- **Ship:** `install.sh` → `flutter-mcp-toolkit` + short alias `fmtk` + `flutter-mcp-toolkit-server`.
- **pub.dev:** Flutter MCP Toolkit packages ship on one version train. `VERSION`, `mcp_toolkit`, `mcp_server_dart`, capability/core packages, runtime metadata, and plugin manifests must agree (currently `4.0.0-dev.5` for the breaking prerelease train).
2 changes: 1 addition & 1 deletion docs/ai_agents/marketplace_copy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ long_description: |
for AI-assisted Flutter development in debug mode.

Built-in surface:
- 27 fmt_* MCP tools for inspection, UI control, debugging, and lifecycle
- 30 fmt_* MCP tools for inspection, UI control, debugging, and lifecycle
- Bundled agent skills (flutter-mcp-toolkit-*, flutter-mcp,
flutter-mcp-toolkit-custom-tools)

Expand Down
2 changes: 1 addition & 1 deletion docs/ai_agents/marketplace_distribution.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: How flutter-mcp-toolkit reaches Claude Code, Cursor, Codex, Cline,

`flutter-mcp-toolkit` is **not** only bundled skills plus a static MCP server. It ships three layers:

1. **Host MCP** — `flutter-mcp-toolkit-server` with 27 `fmt_*` tools (inspect, control, debug).
1. **Host MCP** — `flutter-mcp-toolkit-server` with 30 `fmt_*` tools (inspect, control, debug).
2. **In-app toolkit** — `mcp_toolkit` in your Flutter app (debug only).
3. **Dynamic registry** — your app registers custom tools/resources at runtime (`AgentCallEntry`, `addMcpTool` / `addEntries`); agents use `fmt_list_client_tools_and_resources`, `fmt_client_tool`, `fmt_client_resource`.

Expand Down
2 changes: 1 addition & 1 deletion docs/ai_agents/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ description: Install flutter-mcp-toolkit skills and MCP wiring for Claude Code,

## Three layers (read this first)

1. **Host MCP** — `flutter-mcp-toolkit-server` with 27 `fmt_*` tools.
1. **Host MCP** — `flutter-mcp-toolkit-server` with 30 `fmt_*` tools.
2. **In-app toolkit** — `mcp_toolkit` in your Flutter app (debug only).
3. **Dynamic registry** — register custom tools/resources at runtime (`AgentCallEntry`, `addEntries` / `addMcpTool`). Agents discover via `fmt_list_client_tools_and_resources` and invoke via `fmt_client_tool` / `fmt_client_resource`. Use skill **`flutter-mcp-toolkit-custom-tools`** and [Dynamic tool registry](/core/dynamic_tools_registry).

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/flutter-mcp-toolkit-infographic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Flutter MCP Toolkit connects a running Flutter debug app to AI assistants through MCP, so your assistant can inspect UI, read runtime errors, hot reload, and run app-defined tools.

![Watercolor comic infographic explaining Flutter MCP Toolkit: install fmtk, add it to a Flutter app, connect an AI agent, then inspect, tap, reload, and prove changes in a close feedback loop.](/assets/flutter-mcp-toolkit-infographic.png)

The toolkit gives an AI assistant a shared window and control loop into a running Flutter app, so it can stop guessing and verify changes with runtime proof.

## Choose Your Path

| Audience | Start Here |
Expand Down
70 changes: 65 additions & 5 deletions docs/intentcall/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
|------|----------|
| Canonical local IntentCall clone | `/Users/anton/mcp/agentkit` |
| GitHub | `github.com/Arenukvern/intentcall` |
| Consumer package policy | Hosted `intentcall_* ^0.1.0` from pub.dev |
| Consumer package policy | Hosted `intentcall_* ^0.3.1` from pub.dev |
| Local-development exception | Temporary sibling path overrides to `/Users/anton/mcp/agentkit/packages/intentcall_*` only |
| Main integration gate | `make check-intentcall-integration` |
| Repo contract gate | `make check-contracts` |
Expand All @@ -18,11 +18,70 @@ Keep IntentCall product architecture out of this repository. If a doc needs to e

Keep `mcp_flutter` docs focused on consumer integration, migration, regression proof, and dogfood behavior.

## Runtime sessions

Runtime session ownership lives in IntentCall, not in this consumer repo.
Downstream debug tools that need a running app session should depend on
`intentcall_session` for session state/lifecycle and on `intentcall_core` /
`intentcall_schema` for registry, invocation, result, artifact, and event
semantics.

The reusable session surface is:

- `SessionState`, `PersistedState`, `StateStore`, `StateLockManager`, and
`SafeFileWriter`
- `IntentSessionManager` backed by an `IntentSessionConnector`
- `IntentSessionExecutor` for invoking an `AgentRegistry` inside a session
- `IntentSnapshotStore` for generic JSON snapshot persistence and diffing
- `AgentResult` / `AgentArtifact` from IntentCall

Do not import `mcp_server_dart/src/cli/session/*` or other private server
internals from downstream repos. The hard public boundary is
`intentcall_session` plus the IntentCall registry/result packages; Flutter MCP
is the adapter proving those pieces against a real Flutter app.

Breaking boundary cut: `mcp_server_dart/lib/flutter_mcp_core.dart` and
server-local session barrels no longer promise compatibility for removed
`SessionManager`, `StateStore`, `StateLockManager`, `SafeFileWriter`, or
snapshot internals. Downstream code must import `intentcall_session` for
`IntentSessionManager`, `StateStore`, `StateLockManager`, `SafeFileWriter`, and
`IntentSnapshotStore`. Flutter MCP exposes `FlutterSessionConnector` only as
its adapter between `ConnectionContext` and IntentCall sessions.

Flutter MCP remains one runtime adapter. It keeps VM service discovery, DTD,
Flutter extension calls, screenshots, widget inspection, MCP projection, and CLI
daemon wiring in `mcp_server_dart`. Its `FlutterSessionConnector` adapts
`ConnectionContext` to `IntentSessionConnector`.

The word "broker" should describe product composition, not a new facade layer.
For example, a visual-debug broker can compose `IntentSessionManager`,
`IntentSessionExecutor`, `AgentRegistry`, `intentcall_mcp`, and its artifact
storage. It should not re-export those packages or duplicate the command
executor under a new name.

Dynamic registry is also IntentCall responsibility. If registry ownership,
catalog snapshots, invocation semantics, durable permissions, or transport
publication rules need to change, update `/Users/anton/mcp/agentkit` and dogfood
the hosted or overridden package here.

Flutter MCP still owns Flutter-specific dynamic discovery: reading app-posted
tools/resources from the VM service, registering Flutter extension calls, and
bridging screenshots/widget inspection. IntentCall owns the reusable registry
events and MCP publication behavior, including query-tolerant resource reads and
resource-template de-duplication.

Flutter MCP also owns command snapshot production. The reusable
`IntentSnapshotStore` persists and diffs JSON payloads; `CommandSnapshotService`
in `mcp_server_dart` builds those payloads by executing the Flutter MCP command
catalog through `DefaultCoreCommandExecutor`.

## Normal consumer state

Committed `mcp_flutter` state should use hosted `intentcall_*` dependencies. Do not commit normal consumer pubspecs with `agentkit/packages`, `intentcall/packages`, or `path: .*intentcall` dependencies.

Use local path overrides only while deliberately developing against the sibling IntentCall checkout, then remove them before committing consumer integration changes.
Use root `dependency_overrides` only while deliberately developing against the
sibling IntentCall checkout, then remove them before publishing consumer
integration changes.

## Consumer proof gates

Expand All @@ -46,7 +105,7 @@ The durable proof should live in checks, CI, Steward scenarios, tests, and dated
| Symptom | Start here |
|---------|------------|
| `MCPCallEntry` compile errors or migration work | [MCPCallEntry to AgentCallEntry migration](../start_here/migration_mcp_call_entry_to_agent_call_entry.md) |
| Hosted dependency or local path override drift | `tool/intentcall/check_no_path_deps.sh`, then this guide |
| Hosted dependency or local path override drift | `tool/intentcall/check_no_path_deps.sh`; use `--strict-root` before release/cutover |
| Platform hooks, WebMCP, deep links, app dynamic tools | [flutter_test_app/INTENTCALL_PLATFORM.md](../../flutter_test_app/INTENTCALL_PLATFORM.md) |
| Schema, `fmt_*`, CLI `exec`, or app-dynamic parity debugging | `plugin/skills/flutter-mcp-boundary-audit/` |
| Unsure whether to fix `mcp_flutter` or IntentCall upstream | Fix consumer wiring here; fix architecture/package behavior in `/Users/anton/mcp/agentkit` |
Expand All @@ -58,7 +117,8 @@ For future hosted dependency bumps:
1. Confirm the intended `intentcall_*` versions exist on pub.dev.
2. Update consumer constraints in `mcp_toolkit`, `mcp_server_dart`, capability packages, and `flutter_test_app` as needed.
3. Remove temporary local path overrides.
4. Run the consumer proof gates above.
5. Investigate package behavior regressions in `/Users/anton/mcp/agentkit`, not in this consumer repo.
4. Run `tool/intentcall/check_no_path_deps.sh --strict-root`.
5. Run the consumer proof gates above.
6. Investigate package behavior regressions in `/Users/anton/mcp/agentkit`, not in this consumer repo.

Historical in-repo IntentCall rollout plans, specs, trackers, closure reports, hosted cutover notes, and checklist docs were removed after durable extraction. Git history is the forensic archive.
Loading
Loading