Skip to content

chore(tooling): wire the project's own MCP server - #6

Merged
anilcancakir merged 2 commits into
mainfrom
chore/mcp-server-wiring
Aug 26, 2026
Merged

chore(tooling): wire the project's own MCP server#6
anilcancakir merged 2 commits into
mainfrom
chore/mcp-server-wiring

Conversation

@anilcancakir

@anilcancakir anilcancakir commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

What

Mirrors uptizm#102, per the mirroring rule in AGENTS.md.

This repo already ships bin/fsa (tracked, 100755) and a verification loop written entirely in ./bin/fsa dusk:* form. It had no .mcp.json at all, so a fork inherited the CLI surface and none of the tool surface.

.mcp.json now runs ./bin/fsa mcp:serve: the same dusk, telescope and artisan verbs offered to an agent as tools in the session that edits the code. The binary is byte-identical to uptizm's (git ls-files -s bin/fsa gives the same blob 8a853d0 in both repos), so nothing new is installed and no dependency is added.

Docs

docs/verification-loop.md gains a note at the top of its dusk section: the two routes are interchangeable because both resolve the same running app through the same per-project state under ~/.artisan/sessions/ (see artisan/lib/src/state/state_file.dart), and the file stays in CLI form because that form pastes into a terminal and reads back in a log.

AGENTS.md names it in the "Other agent infrastructure" paragraph, next to the skills and the component-visual-reviewer, because that paragraph is what a fork reads to learn what it inherited. bin/sync-instructions regenerated .github/copilot-instructions.md from it.

Verification

./bin/check flutter
  ok    flutter-analyze
  ok    design-tokens
  ok    flutter-test
check: all green | flutter

bin/sync-instructions was run, so the .github/ mirror is current and the instruction-mirror check will pass.

Mirrors uptizm#102. This repo had bin/fsa, .artisan/plugins.json and a
verification loop written entirely in `./bin/fsa dusk:*` form, but no
.mcp.json at all, so a fork inherited the CLI and none of the tools.

`.mcp.json` runs `./bin/fsa mcp:serve`: the same dusk, telescope and artisan
verbs, offered to an agent as tools in the session that edits the code. The
binary is already tracked and executable, and it is byte-identical to
uptizm's, so nothing new is installed.

docs/verification-loop.md gains the note that the two routes are
interchangeable, since both resolve the same running app through the same
per-project state under ~/.artisan/sessions/, and that the file stays in CLI
form because that form pastes into a terminal. AGENTS.md names it under
agent infrastructure, alongside the skills and the reviewer, because that
paragraph is what a fork reads to learn what it inherited.
@kodizm

kodizm Bot commented Aug 26, 2026

Copy link
Copy Markdown

Note

Kodizm (AI-generated). May contain mistakes; verify before acting.

Config-and-docs only, and the wiring is correct on POSIX - mcp:serve is a real verb, the entry byte-matches what mcp:install generates, and the mirror check passes; the one substantive gap is that this commits the shape upstream deliberately refuses to write on Windows.

Major

.mcp.json:4 — The entry hardcodes the POSIX-only fast path. bin/fsa is a sh script ("POSIX sh; tested on macOS + Linux"), and fluttersdk_artisan's own mcp:install guards against exactly this: final useFsa = _hasFsa() && !_isWindows();, documented as "Windows always skips the bin/fsa shape because the shim is a POSIX shell script." This repo ships a windows/ runner target and is explicitly the thing production apps fork, so a Windows fork opens Claude Code and gets a fluttersdk server that cannot spawn its command, with nothing in AGENTS.md or docs/verification-loop.md telling them to regenerate it. One line in the new docs paragraph pointing Windows forks at dart run :dispatcher mcp:install would close it. (correctness)

Minor

.mcp.json:4 — First-run on a fresh clone fails. pubspec.lock (.gitignore:65) and .artisan/ (.gitignore:46) are both deliberately untracked, and bin/fsa needs both: with no lock, LOCK_HASH comes back empty, needs_build trips, and dart build cli fails before dependencies are resolved. Previously nothing auto-launched fsa; now an MCP client tries at session start and surfaces a failed server until the first flutter pub get. Worth a sentence in the docs note. Related: the description says the repo "ships ... a generated .artisan/plugins.json" - that path is gitignored, so a fork does not inherit it.

Tests

Nothing here is testable code; no repo test asserts the .mcp.json shape, and none is warranted. bin/sync-instructions --check is the CI gate covering the AGENTS.md -> .github/ mirror and it passes.

Checks I ran

  • ./bin/fsa list - mcp:serve and mcp:install are both registered; bin/dispatcher.dart:35 passes collectMcpTools for mcp:serve, so the verb resolves.
  • ./bin/sync-instructions --check - "mirrors are up to date", exit 0.
  • python3 -c "json.load(open('.mcp.json'))" - parses; keys and trailing newline match mcp_install_command.dart branch 1 byte for byte, so a later mcp:install is a no-op diff.
  • git ls-files -s bin/fsa - 100755 8a853d0, tracked and executable as claimed.
  • Docs claim spot-checked: ~/.artisan/sessions/<hash> is confirmed at state_file.dart:114, so the "both routes resolve the same state" note is accurate.
  • Did not run flutter analyze / flutter test; the diff contains no Dart, and the author's ./bin/check flutter output is in the description.

The committed entry is the POSIX shape and nothing said so. `bin/fsa` is a
`sh` script, and `fluttersdk_artisan`'s own `mcp:install` refuses that shape
on Windows for exactly that reason (`useFsa = _hasFsa() && !_isWindows()`),
falling back to a `dart run` command. This repo ships a windows/ runner
target and is the thing production apps fork, so a Windows fork opened a
server that could not spawn its command with nothing telling them why.

The fix is to re-run `mcp:install`, not to hand-edit the file: the tool
already knows which of its three shapes a machine has, it is idempotent, and
it preserves other server entries. Verified that `dart run :dispatcher
mcp:install` resolves here.

Keeping the fast shape committed is a measured choice, not an oversight:
`./bin/fsa list` is 0.63s against 5.21s for `dart run :dispatcher list`, and
a dusk walk pays that per command rather than once per session.

Also drops a false clause I had written into the same paragraph: a fresh
clone cannot run `mcp:install` either, since `dart run` needs resolved
dependencies too. `flutter pub get` is what a clone needs, and it is already
the documented first step.
@kodizm

kodizm Bot commented Aug 26, 2026

Copy link
Copy Markdown

Note

Kodizm (AI-generated). May contain mistakes; verify before acting.

The one new commit is docs-only and it closes both findings from the previous review - nothing further to flag.

Since 7aea43e: 2799f29 adds a Windows paragraph to the dusk section of docs/verification-loop.md, a sentence to the AGENTS.md "Other agent infrastructure" paragraph, and the regenerated .github/copilot-instructions.md mirror. No code, no config change; .mcp.json is untouched.

Both earlier findings are answered rather than argued: the Major (POSIX-only entry with no Windows escape hatch) now points Windows forks at dart run :dispatcher mcp:install, and the Minor (first-run on a fresh clone) is covered by the pubspec.lock/flutter pub get sentence.

I checked the new prose against the implementation rather than taking it on trust, and every claim in it holds:

  • "skips that shape on Windows by design" - mcp_install_command.dart:131, final useFsa = _hasFsa() && !_isWindows();.
  • "three shapes" - fsa fastcli, --invocation, and the :dispatcher fallback, at mcp_install_command.dart:132-148.
  • "idempotent and preserves any other server entry" - the command's own docs at mcp_install_command.dart:60 and :85 say the same, and it merges into the existing mcpServers map rather than replacing it.
  • dart run :dispatcher is a valid invocation here: the :name form resolves to bin/dispatcher.dart in the current package and needs no executables: entry in pubspec.yaml (there is none).

The only unverified claim is the 0.63s vs 5.21s timing, which is presented as "measured here" and is not load-bearing for anything.

Tests

Unchanged from the previous review: docs and generated mirrors, nothing testable. bin/sync-instructions --check is the CI gate that covers this commit and it passes.

Checks I ran

  • ./bin/sync-instructions --check - "mirrors are up to date", exit 0, so the regenerated .github/copilot-instructions.md matches AGENTS.md.
  • Read mcp_install_command.dart:110-175 to confirm the Windows fallback, the three payload shapes, and the preserve/idempotent behaviour the docs describe.
  • grep -n "^executables" pubspec.yaml - no match, confirming :dispatcher resolves by the bin/ convention.
  • Did not run flutter analyze / flutter test; this commit contains no Dart.

@anilcancakir
anilcancakir merged commit 62a0c7a into main Aug 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant