Release 0.0.4: fix MCP empty tools/list (issue #7) + fsa staleness + missing artisan_command stub#8
Merged
Merged
Conversation
…issue #7 Bug A red)
…nstall coverage (issue #7 Bug B red)
…artisan (latent regression red)
…Fsa+isWindows (issue #7 Bug B)
…-0.0.2 wrapper regression)
…cture diagram + flag examples (issue #7)
…ver + commands (issue #7)
…lock pub add updates pubspec.yaml after pub get writes pubspec.lock, leaving pubspec.yaml mtime newer than pubspec.lock for every freshly installed consumer. The pre-fix staleness check tripped on that, forcing a ~5s AOT rebuild on every invocation (the wrapper's ~50ms cached-bundle target was never met after initial install). Compare pubspec.yaml against the build stamp instead: the stamp is written at the end of every successful compile, so pubspec.yaml newer than the stamp means the user actually edited it after the last build. Discovered during A-Z e2e testing in a fresh consumer.
MakeCommandCommand.getStub() declared 'artisan_command' but the asset
never shipped, so every consumer invocation of `make:command` crashed
with FileSystemException: Stub file not found. Added the stub with the
canonical `final class ... extends ArtisanCommand` shape, honoring the
{{ className }} / {{ namespace }} / {{ commandName }} placeholders the
generator base class substitutes.
Discovered during A-Z e2e testing in a fresh consumer.
…leness + missing artisan_command stub Substrate-side fixes for GitHub issue #7 (empty tools/list when consumers invoke ./bin/fsa mcp:serve), plus two A-Z testing finds: the bin/fsa wrapper rebuilt the AOT bundle on every invocation due to a pubspec.lock mtime quirk, and make:command crashed because the canonical artisan_command stub never shipped in the publish archive. See CHANGELOG [0.0.4] for the full bullet list and migration steps.
…ll + mcp setup pages The install command's own doc page jumped straight to `dart run fluttersdk_artisan install` without telling the reader to add the package first; same with the MCP setup page and the mcp-server skill reference. Added explicit Prerequisites sections so a first-time reader of any of those pages sees the pub-add step before the scaffold/mcp-install invocation.
…cher.dart The 0.0.2 rename moved the consumer wrapper from `bin/artisan.dart` to `bin/dispatcher.dart` but two current-flow descriptions in the getting-started docs still referenced the legacy filename. Updated installation.md scaffold table + quickstart.md step descriptions to the canonical name. Plugin-install legacy-mode references at `doc/commands/plugin-install.md` intentionally keep `bin/artisan.dart` because that section documents the legacy fallback.
There was a problem hiding this comment.
Pull request overview
This PR prepares the 0.0.4 release by fixing the “empty tools/list” MCP symptom (issue #7) by routing MCP server startup through the consumer wrapper and ensuring MCP tools are collected, plus additional reliability fixes discovered during end-to-end validation (fast CLI staleness detection and a missing make:command stub asset).
Changes:
- Fix consumer dispatcher stub and
mcp:installso MCP server invocation loads consumer plugin providers and collects MCP tool descriptors. - Update auto-delegation to target the post-0.0.2 wrapper name (
bin/dispatcher.dart) and adddoctoradvisory for pre-fix.mcp.jsonshapes. - Improve
bin/fsastaleness detection and ship the missingartisan_command.stub, with tests and docs updated accordingly.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test/stubs/stub_loader_test.dart | Adds regression test ensuring dispatcher stub forwards collectMcpTools. |
| test/stubs/bin_fsa_stub_test.dart | Adds regression test for corrected bin/fsa staleness check condition. |
| test/console/run_artisan_test.dart | Updates/extends tests to assert delegation prefixes :dispatcher. |
| test/commands/mcp_uninstall_command_test.dart | Adds tests covering uninstall of new .mcp.json shapes. |
| test/commands/mcp_install_command_test.dart | Updates tests for branched .mcp.json install shape (fsa vs dart fallback). |
| test/commands/make_command_command_test.dart | Adds regression test asserting artisan_command stub asset exists. |
| test/commands/install_command_test.dart | Asserts rendered dispatcher includes collectMcpTools forwarding. |
| test/commands/doctor_command_test.dart | Adds coverage for new advisory warning on pre-fix .mcp.json shape. |
| skills/fluttersdk-artisan/SKILL.md | Updates skill guidance for new MCP invocation and installation flow. |
| skills/fluttersdk-artisan/references/mcp-server.md | Updates canonical .mcp.json shapes and client config guidance. |
| skills/fluttersdk-artisan/references/commands.md | Updates MCP command docs to reflect new invocation shapes. |
| README.md | Updates Quick Start MCP wiring snippet and documents new .mcp.json shape. |
| pubspec.yaml | Bumps version to 0.0.4. |
| lib/src/console/run_artisan.dart | Changes auto-delegation to prepend :dispatcher and simplifies delegate invocation. |
| lib/src/commands/mcp_install_command.dart | Branches .mcp.json entry shape based on fsa availability and platform; injects test seams. |
| lib/src/commands/doctor_command.dart | Adds advisory warning for pre-fix fluttersdk_artisan:mcp entry shape. |
| doc/mcp/tool-reference.md | Updates MCP restart/invocation guidance for new server entry points. |
| doc/mcp/setup.md | Updates per-client setup matrix for new MCP server spawn shapes. |
| doc/mcp/overview.md | Updates overview to describe the post-install MCP invocation path and legacy entrypoint behavior. |
| doc/getting-started/installation.md | Updates command list to describe how to run mcp:serve post-install. |
| doc/commands/mcp-serve.md | Updates examples/synopsis to prefer ./bin/fsa mcp:serve with dart fallback. |
| doc/commands/install.md | Documents collectMcpTools forwarding behavior in the generated dispatcher. |
| CHANGELOG.md | Adds 0.0.4 release notes covering the fixes and migrations. |
| assets/stubs/dispatcher.dart.stub | Updates generated dispatcher to forward collectMcpTools for mcp:serve. |
| assets/stubs/bin_fsa.sh.stub | Fixes staleness check to compare pubspec.yaml against the build stamp file. |
| assets/stubs/artisan_command.stub | Adds the missing command stub used by make:command. |
Comments suppressed due to low confidence (1)
lib/src/commands/mcp_install_command.dart:123
- This code writes
.mcp.jsonviaFile.writeAsString, which is not atomic and can leave a truncated/partial file if the process is interrupted mid-write. The comment calls this atomic; if the repo convention is.tmp+ rename for persistent writes, consider switching to that pattern here too (write to$path.tmp, then rename over the original).
// 3. Write atomically (single write; no partial-read window on success).
await file.writeAsString(
'${const JsonEncoder.withIndent(' ').convert(config)}\n',
);
… :dispatcher Auto-delegation always prepended :dispatcher when defaultConsumerWrapperExists returned true. The exists check accepts EITHER bin/dispatcher.dart (canonical post-0.0.2) OR bin/artisan.dart (legacy), so a legacy-only consumer was detected as delegatable but the dispatched dart run :dispatcher would then fail because bin/dispatcher.dart did not exist. Added defaultConsumerWrapperName + WrapperNameResolver seam that returns 'dispatcher' or 'artisan' (or null) per the file actually on disk; runArtisan forwards the matching token. Existing wrapperExists bool seam stays for back- compat with tests that force the boolean against tempdirs; when both are injected, wrapperExists wins for the bool gate, name defaults to 'dispatcher'. Copilot PR #8 review finding.
The stale-MCP advisory text told the user to run `dart run fluttersdk_artisan:artisan mcp:install`, but the substrate's pubspec exposes only `fluttersdk_artisan` and `mcp` executables (no `artisan`). The advisory was unactionable. Replaced with `./bin/fsa mcp:install` (canonical fast path) and `dart run fluttersdk_artisan mcp:install` (substrate-direct fallback). Test-local mirror constant in doctor_command_test.dart updated byte-for-byte. Copilot PR #8 review finding.
The new stub I added shipped with an em-dash in the {{ className }} doc comment,
violating the repo's no-em-dash rule (CLAUDE.md Must NOT). Replaced with a colon.
Copilot PR #8 review finding.
…s with canonical post-rename forms Five doc surfaces still pointed at invocations that no longer resolve: - README quick start said `dart run artisan mcp:install` (no `artisan` executable post-rename). - doc/mcp/overview.md plugin-registration paragraph cited `bin/artisan.dart` + a non-existent `artisanProviders` factory. - doc/mcp/tool-reference.md plugin-tools intro + .artisan/mcp.json layout cited `bin/artisan.dart` as the registration site. - skills/.../SKILL.md Core Law #1 cited `dart run <consumer-package>:artisan <cmd>` as the consumer entry. - doc/mcp/setup.md V1-transport paragraph cited `dart run artisan start`. Replaced each with `./bin/fsa` (canonical fast path) and the `dart run :dispatcher` fallback. Legacy-mode references in plugin-install docs intentionally kept (they document the legacy fallback branch). Copilot PR #8 review findings (5 of 9).
The group label said 'new entry shape (fluttersdk_artisan:mcp)' but the section now exercises three shapes via key-based removal: the two post-fix shapes (`./bin/fsa mcp:serve`, `dart run :dispatcher mcp:serve`) and the pre-fix `fluttersdk_artisan:mcp`. Renamed to make the intent explicit. Copilot PR #8 review finding.
…cp_uninstall_command_test.dart CI's `dart format --output=none --set-exit-if-changed` flagged 2 files that escaped my local format pass between the Copilot-fix edits and the commit phase. Re-formatted both; `dart format` is now clean and CI's format gate will pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #7.
Summary
Substrate-side fix for the empty `tools/list` symptom from GitHub issue #7 (`./bin/fsa mcp:serve` returned 0 tools even when plugin providers were correctly registered), plus two pre-existing bugs surfaced during A-Z end-to-end testing in a fresh consumer.
What landed
Issue #7 root cause (verified end-to-end)
Issue body correction
The issue's proposed fallback `dart run :artisan mcp:serve` does not resolve (per dart docs, `dart run :name` is a pure `bin/.dart` filename lookup; `executables:` is honored only by `dart pub global activate`). The correct fallback shape is `dart run :dispatcher mcp:serve`.
A-Z testing bonus fixes
`doctor` migration aid
`doctor` now advisory-warns when `.mcp.json` still contains the pre-fix `fluttersdk_artisan:mcp` args shape, pointing the user at `./bin/fsa mcp:install` to upgrade.
Migration
Verification
See CHANGELOG.md [0.0.4] for the full bullet list.
Process
Plan + execute autonomous run: `.ac/plans/mcp-empty-tools-list/` (planning artifacts gitignored). Deep code review + oracle both APPROVED first pass.