diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index b62d8eb7..8cf2445d 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "flutter-mcp-toolkit", "source": "./plugin", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop.", - "version": "4.0.0-dev.8", + "version": "4.0.0", "keywords": [ "flutter", "dart", diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..9483e2e2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +.git/ +.github/ +.dart_tool/ +**/.dart_tool/ +build/ +**/build/ +coverage/ +dist/ +node_modules/ +.DS_Store +.flutter_mcp/ +**/.flutter_mcp/ +test/ +**/test/ +docs/ +**/docs/ +*.log diff --git a/.github/workflows/pub_publish.yml b/.github/workflows/pub_publish.yml index b67b01da..7b48e2c6 100644 --- a/.github/workflows/pub_publish.yml +++ b/.github/workflows/pub_publish.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + actions: write contents: read id-token: write @@ -40,3 +41,9 @@ jobs: - name: Publish packages if: github.event_name == 'push' run: bash tool/release/publish_pub_packages.sh --execute --skip-existing + + - name: Trigger MCP Registry publication + if: github.event_name == 'push' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh workflow run publish_mcp_registry.yml --ref "${GITHUB_REF_NAME}" diff --git a/.github/workflows/publish_mcp_registry.yml b/.github/workflows/publish_mcp_registry.yml new file mode 100644 index 00000000..d56c54f1 --- /dev/null +++ b/.github/workflows/publish_mcp_registry.yml @@ -0,0 +1,94 @@ +name: Publish MCP Registry server + +on: + workflow_dispatch: + +permissions: + contents: read + packages: write + id-token: write + +concurrency: + group: mcp-registry-${{ github.ref_name }} + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + environment: mcp-registry-publish + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Require release tag + shell: bash + run: | + set -euo pipefail + if [[ "$GITHUB_REF" != refs/tags/v* ]]; then + echo "::error::This workflow must be run from a v* release tag (got $GITHUB_REF)." + exit 1 + fi + + - name: Resolve release version + id: version + shell: bash + run: | + set -euo pipefail + version="${GITHUB_REF_NAME#v}" + file_version="$(tr -d '[:space:]' < VERSION)" + if [[ "$version" != "$file_version" ]]; then + echo "::error::Tag ${GITHUB_REF_NAME} does not match VERSION (${file_version})." + exit 1 + fi + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Synchronize release metadata + env: + RELEASE_VERSION: ${{ steps.version.outputs.version }} + run: bash tool/release/sync_version.sh --version "$RELEASE_VERSION" + + - name: Verify MCP Registry contracts + run: bash tool/contracts/check_mcp_registry.sh + + - name: Stage workspace lockfile for the image build context + run: cp pubspec.lock mcp_server_dart/pubspec.lock + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and publish OCI image + uses: docker/build-push-action@v6 + with: + context: mcp_server_dart + file: Dockerfile.registry + push: true + tags: ghcr.io/arenukvern/flutter-mcp-toolkit:${{ steps.version.outputs.version }} + + - name: Install pinned mcp-publisher + env: + MCP_PUBLISHER_VERSION: v1.8.1 + MCP_PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc + shell: bash + run: | + set -euo pipefail + curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/download/${MCP_PUBLISHER_VERSION}/mcp-publisher_linux_amd64.tar.gz" \ + -o mcp-publisher.tar.gz + echo "${MCP_PUBLISHER_SHA256} mcp-publisher.tar.gz" | sha256sum --check --strict - + tar xz mcp-publisher -f mcp-publisher.tar.gz + chmod +x mcp-publisher + + - name: Validate server manifest with the Registry + run: ./mcp-publisher validate mcp_server_dart/server.json + + - name: Authenticate to MCP Registry with GitHub OIDC + run: ./mcp-publisher login github-oidc + + - name: Publish server metadata to MCP Registry + working-directory: mcp_server_dart + run: ../mcp-publisher publish diff --git a/.github/workflows/release_pr_sync_versions.yml b/.github/workflows/release_pr_sync_versions.yml index defba6e0..56faa3f3 100644 --- a/.github/workflows/release_pr_sync_versions.yml +++ b/.github/workflows/release_pr_sync_versions.yml @@ -71,6 +71,7 @@ jobs: packages/core/README.md \ packages/server_capability_kernel/README.md \ packages/server_capability_core/README.md \ + mcp_server_dart/server.json \ packages/core/lib/src/runtime_version.dart \ packages/server_capability_core/lib/src/fmt_capability.dart git commit -m "chore: sync release version touchpoints" diff --git a/.gitignore b/.gitignore index 4e39da73..11ae37ab 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ mcp_server_dart/flutter_inspector_mcp # ../flutter_harness # ../flutter_mcp_video .steward/benchmark-summaries/*.json +mcp_server_dart/mcp-publisher diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6e0dd2be..e6f87756 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.0.0-dev.8" + ".": "4.0.0" } diff --git a/README.md b/README.md index 1444cba3..0037c657 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ _Inspect and drive a running Flutter app from your AI assistant._ - 📖 **Docs:** [docs.page/arenukvern/mcp_flutter](https://docs.page/arenukvern/mcp_flutter/) - 🤝 **Contribute:** [guide](docs/contributing/contribution_guide.mdx) · [contributors](docs/contributing/contributors.mdx) · [code of conduct](CODE_OF_CONDUCT.md) · [security](SECURITY.md) -`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/). +`flutter-mcp-toolkit` is a Dart MCP server + Flutter package for AI agents (Codex, Zed, Cursor, Intent, Claude Code, Cline, and more). Agents can inspect a running Flutter app, take semantic snapshots, tap widgets, type into forms, hot-reload, and read logs. Apps can also register their own MCP tools and resources at runtime via MCP Toolkit — all without leaving the conversation. The result is a closed feedback loop between agent and app; see [OpenAI Agentic Harness](https://openai.com/index/harness-engineering/) for an example of this pattern. ![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) @@ -33,7 +33,7 @@ The picture's story: the toolkit gives an AI assistant a shared window and contr ![View Screenshots](docs/view_screenshots.gif) -> ![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. +> ![NOTICE]: Version 4 is now stable. Earlier `4.0.0-dev.*` builds were prerelease testing builds of the new architecture. ## Get started in 4 steps @@ -56,23 +56,47 @@ flutter run --debug That's it. Your AI agent can now inspect and drive the running app — and your app can expose **custom MCP tools at runtime** (see [Dynamic Tools Registration](#dynamic-tools-registration) below). - ## 📰 News --**2026-07-11** - v4 new Live Demos records: [v4 semantic snapshot etc.. with Grok Build CLI](https://youtu.be/P0ObCyt0k3M), [v4 with IntentCall power - WebMCP projection](https://www.youtube.com/watch?v=mX4xxVeImq0) + +- **2026-07-11** - v4 new Live Demos records: [v4 semantic snapshot etc.. with Grok Build CLI](https://youtu.be/P0ObCyt0k3M), [v4 with IntentCall power - WebMCP projection](https://www.youtube.com/watch?v=mX4xxVeImq0) - **2026-05-26** — v3.1.0: Platform-view capture routing, macOS/iOS Simulator host screenshots, web CDP tab capture (SCK → CDP → flutter_layer), and cross-platform showcase platform views. + ## Install from marketplaces -| Platform | Command / link | -|----------|----------------| -| **Any agent (recommended)** | `flutter-mcp-toolkit init ` — see [AI agent setup](docs/ai_agents/overview.mdx) | -| **Claude Code (git catalog)** | `/plugin marketplace add Arenukvern/mcp_flutter` then install `flutter-mcp-toolkit` | -| **Codex (git catalog)** | `codex plugin marketplace add Arenukvern/mcp_flutter` | -| **Cursor (local plugin)** | `flutter-mcp-toolkit init cursor` | -| **Skills only** | `npx skills add Arenukvern/mcp_flutter -a -y` (add MCP via `init` or manual JSON) | -| **MCP registries** | [Smithery](https://smithery.ai/server/@Arenukvern/mcp_flutter), [MseeP](https://mseep.ai/app/03aa0f2d-4ef7-40ae-93de-c7b87e0ac32d) | +| Platform | Command / link | +| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Any agent (recommended)** | `flutter-mcp-toolkit init ` — see [AI agent setup](docs/ai_agents/overview.mdx) | +| **Claude Code (git catalog)** | `/plugin marketplace add Arenukvern/mcp_flutter` then install `flutter-mcp-toolkit` | +| **Codex (git catalog)** | `codex plugin marketplace add Arenukvern/mcp_flutter` | +| **Cursor (local plugin)** | `flutter-mcp-toolkit init cursor` | +| **Skills only** | `npx skills add Arenukvern/mcp_flutter -a -y` (add MCP via `init` or manual JSON) | +| **MCP registries** | [Official MCP Registry](https://registry.modelcontextprotocol.io) — server `io.github.Arenukvern/flutter-mcp-toolkit` (OCI image: `ghcr.io/arenukvern/flutter-mcp-toolkit`), [Smithery](https://smithery.ai/server/@Arenukvern/mcp_flutter), [MseeP](https://mseep.ai/app/03aa0f2d-4ef7-40ae-93de-c7b87e0ac32d) | + +### Docker / MCP Registry install + +The official registry serves an OCI image from GHCR. Point any MCP client at it: + +```json +{ + "mcpServers": { + "flutter-mcp-toolkit": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "--network=host", + "ghcr.io/arenukvern/flutter-mcp-toolkit:4.0.0" + ] + } + } +} +``` + +See [Docker guide](mcp_server_dart/DOCKER.md) for flags, version pinning, and networking notes. Maintainers submitting to official stores: [marketplace submission runbook](docs/contributing/marketplace_submission_runbook.mdx). Full matrix: [marketplace distribution](docs/ai_agents/marketplace_distribution.mdx). @@ -92,12 +116,12 @@ Maintainers submitting to official stores: [marketplace submission runbook](docs ## Published packages -| Package | Pub.dev | Role | -|---|---|---| -| `mcp_toolkit` | [![pub package](https://img.shields.io/pub/v/mcp_toolkit.svg?include_prereleases)](https://pub.dev/packages/mcp_toolkit) [![pub points](https://img.shields.io/pub/points/mcp_toolkit.svg)](https://pub.dev/packages/mcp_toolkit/score) | Flutter app package for runtime MCP tools/resources and toolkit bootstrap. | -| `flutter_mcp_toolkit_core` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_core.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_core) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_core.svg)](https://pub.dev/packages/flutter_mcp_toolkit_core/score) | Pure-Dart shared command/result/capability types. | -| `flutter_mcp_toolkit_capability_kernel` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_capability_kernel.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_capability_kernel) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_capability_kernel.svg)](https://pub.dev/packages/flutter_mcp_toolkit_capability_kernel/score) | Capability kernel contracts for composable MCP units. | -| `flutter_mcp_toolkit_capability_core` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_capability_core.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_capability_core) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_capability_core.svg)](https://pub.dev/packages/flutter_mcp_toolkit_capability_core/score) | Server-side `fmt_*` capability implementation. | +| Package | Pub.dev | Role | +| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `mcp_toolkit` | [![pub package](https://img.shields.io/pub/v/mcp_toolkit.svg?include_prereleases)](https://pub.dev/packages/mcp_toolkit) [![pub points](https://img.shields.io/pub/points/mcp_toolkit.svg)](https://pub.dev/packages/mcp_toolkit/score) | Flutter app package for runtime MCP tools/resources and toolkit bootstrap. | +| `flutter_mcp_toolkit_core` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_core.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_core) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_core.svg)](https://pub.dev/packages/flutter_mcp_toolkit_core/score) | Pure-Dart shared command/result/capability types. | +| `flutter_mcp_toolkit_capability_kernel` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_capability_kernel.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_capability_kernel) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_capability_kernel.svg)](https://pub.dev/packages/flutter_mcp_toolkit_capability_kernel/score) | Capability kernel contracts for composable MCP units. | +| `flutter_mcp_toolkit_capability_core` | [![pub package](https://img.shields.io/pub/v/flutter_mcp_toolkit_capability_core.svg?include_prereleases)](https://pub.dev/packages/flutter_mcp_toolkit_capability_core) [![pub points](https://img.shields.io/pub/points/flutter_mcp_toolkit_capability_core.svg)](https://pub.dev/packages/flutter_mcp_toolkit_capability_core/score) | Server-side `fmt_*` capability implementation. | The server binary lives in `mcp_server_dart` and is shipped through GitHub Release artifacts as `flutter-mcp-toolkit`, `fmtk`, and @@ -105,14 +129,14 @@ Release artifacts as `flutter-mcp-toolkit`, `fmtk`, and ## Development support -| Need | Start here | -|---|---| -| Contribute code or docs | [CONTRIBUTING.md](CONTRIBUTING.md) · [Contribution guide](docs/contributing/contribution_guide.mdx) | -| Add or credit contributors | [Contributors guide](docs/contributing/contributors.mdx) · [`.all-contributorsrc`](.all-contributorsrc) | -| Report vulnerabilities | [SECURITY.md](SECURITY.md) | -| Validate local changes | `steward probe --json --profile quick` · `make check-contracts` | -| Maintain releases | [Release train notes](CONTRIBUTING.md#maintainers) · [`flutter-mcp-toolkit-repo-maintainer`](plugin/skills/flutter-mcp-toolkit-repo-maintainer/SKILL.md) | -| Install or update agent skills | [AI agent setup](docs/ai_agents/overview.mdx) · [Marketplace distribution](docs/ai_agents/marketplace_distribution.mdx) | +| Need | Start here | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Contribute code or docs | [CONTRIBUTING.md](CONTRIBUTING.md) · [Contribution guide](docs/contributing/contribution_guide.mdx) | +| Add or credit contributors | [Contributors guide](docs/contributing/contributors.mdx) · [`.all-contributorsrc`](.all-contributorsrc) | +| Report vulnerabilities | [SECURITY.md](SECURITY.md) | +| Validate local changes | `steward probe --json --profile quick` · `make check-contracts` | +| Maintain releases | [Release train notes](CONTRIBUTING.md#maintainers) · [`flutter-mcp-toolkit-repo-maintainer`](plugin/skills/flutter-mcp-toolkit-repo-maintainer/SKILL.md) | +| Install or update agent skills | [AI agent setup](docs/ai_agents/overview.mdx) · [Marketplace distribution](docs/ai_agents/marketplace_distribution.mdx) | ## What it does @@ -134,7 +158,6 @@ works in this [short YouTube video](https://www.youtube.com/watch?v=Qog3x2VcO98) The same `arguments.connection` targeting is supported by the CLI's `exec`, `batch`, daemon `command/execute`, daemon `watch/start`, and snapshot step args. - > [!NOTE] > There is official [MCP Server for Flutter from Flutter team](https://github.com/dart-lang/ai/tree/main/pkgs/dart_mcp_server) which exposes Dart tooling. > The **main goal of this project** is to bring power of MCP server tools by creating them in Flutter app, using **dynamic MCP tools registration** and close feedback loop for AI Agent. See how it works in [short YouTube video](https://www.youtube.com/watch?v=Qog3x2VcO98). See [Quick Start](https://docs.page/arenukvern/mcp_flutter) for more details. See [original motivation](https://github.com/Arenukvern/mcp_flutter/blob/main/CHANGELOG.md#210) behind the idea. diff --git a/VERSION b/VERSION index 9a838b4b..fcdb2e10 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.0-dev.8 +4.0.0 diff --git a/docs.json b/docs.json index cdc6ccae..fb244f8f 100644 --- a/docs.json +++ b/docs.json @@ -49,7 +49,7 @@ "noindex": false }, "variables": { - "version": "4.0.0-dev.5", + "version": "4.0.0", "repo": "https://github.com/Arenukvern/mcp_flutter", "docs": "https://docs.page/arenukvern/mcp_flutter" }, diff --git a/docs/start_here/video_walkthroughs.mdx b/docs/start_here/video_walkthroughs.mdx index cd8e39d7..8590816e 100644 --- a/docs/start_here/video_walkthroughs.mdx +++ b/docs/start_here/video_walkthroughs.mdx @@ -4,7 +4,8 @@ Use these videos to shorten onboarding. ## 1. Dynamic Tools Registration -- Video: [https://www.youtube.com/watch?v=Qog3x2VcO98](https://www.youtube.com/watch?v=Qog3x2VcO98) +- Grok Build (2026, June): [https://youtu.be/P0ObCyt0k3M?si=_rRYfkvrXGWGwMyJ](https://youtu.be/P0ObCyt0k3M?si=_rRYfkvrXGWGwMyJ). +- Cursor Video: [https://www.youtube.com/watch?v=Qog3x2VcO98](https://www.youtube.com/watch?v=Qog3x2VcO98). - Best for: understanding why dynamic tools are a key differentiator. - Pair with: [Dynamic tool registry docs](/core/dynamic_tools_registry). @@ -14,6 +15,12 @@ Use these videos to shorten onboarding. - Best for: first MCP connection from a desktop AI editor. - Pair with: [AI agent overview](/ai_agents/overview) (use `flutter-mcp-toolkit init cursor` for Cursor MCP wiring). +## 3. Future: intentcall + +- IntentCall + Grok Build (2026, June): [https://youtu.be/mX4xxVeImq0?si=Wv1TpoBq3JyX35g6](https://youtu.be/mX4xxVeImq0?si=Wv1TpoBq3JyX35g6) +- Best for: projection for WebMCP (planned in https://github.com/Arenukvern/mcp_flutter/pull/103) +- Pair with: [AI agent overview](/ai_agents/overview) (use `flutter-mcp-toolkit init cursor` for Cursor MCP wiring). + ## Suggested Watch Order 1. Dynamic tools video. diff --git a/makefile b/makefile index b0978fe8..7b674ecc 100644 --- a/makefile +++ b/makefile @@ -24,7 +24,8 @@ check-contracts: bash tool/contracts/check_tool_prefix.sh && \ bash tool/contracts/check_repo_split_paths.sh && \ bash tool/contracts/check_intentcall_hosted_consumer.sh && \ - steward validate skills/ + bash tool/contracts/check_mcp_registry.sh && \ + steward validate skills/ .PHONY: release-artifacts release-artifacts: diff --git a/mcp_server_dart/DOCKER.md b/mcp_server_dart/DOCKER.md index 4b555247..8e146dc8 100644 --- a/mcp_server_dart/DOCKER.md +++ b/mcp_server_dart/DOCKER.md @@ -1,15 +1,48 @@ # Docker Deployment Guide -IMPORTANT NOTE: Not tested - please critically review how dockerfile works before using it. - This guide covers building and running the MCP Server using Docker. +## Install from GHCR (MCP Registry image) + +The official MCP Registry image is published to GHCR on every release: + +```bash +docker pull ghcr.io/arenukvern/flutter-mcp-toolkit:4.0.0 +``` + +Use it in an `mcpServers` config: + +```json +{ + "mcpServers": { + "flutter-mcp-toolkit": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "--network=host", + "ghcr.io/arenukvern/flutter-mcp-toolkit:4.0.0" + ] + } + } +} +``` + +> `--network=host` is required on macOS/Linux so the container can reach the +> Dart VM service of your locally running Flutter debug app. Pin the version +> tag to the release you validated against for reproducible setups. + ## Overview -Two Dockerfiles are provided: +Three Dockerfiles are provided: - **`Dockerfile`** - Production-ready, multi-stage build with compiled binary - **`Dockerfile.dev`** - Development version with Dart VM for debugging +- **`Dockerfile.registry`** - Dedicated GHCR/MCP Registry image with Registry ownership metadata + +The first two files preserve the existing local Docker contract. The Registry +workflow uses `Dockerfile.registry` and does not change local Docker builds. ## Production Deployment @@ -235,14 +268,10 @@ docker stats ## Registry Publishing -```bash -# Tag for registry -docker tag mcp_server:latest myregistry.com/mcp_server:0.1.0 - -# Push to registry -docker push myregistry.com/mcp_server:0.1.0 +The official image is built from `Dockerfile.registry` and published to GHCR by +[`.github/workflows/publish_mcp_registry.yml`](../.github/workflows/publish_mcp_registry.yml) +when `pub_publish.yml` completes. Manual local build: -# Pull and run -docker pull myregistry.com/mcp_server:0.1.0 -docker run -i myregistry.com/mcp_server:0.1.0 +```bash +docker build -f Dockerfile.registry -t flutter-mcp-toolkit:registry . ``` diff --git a/mcp_server_dart/Dockerfile b/mcp_server_dart/Dockerfile index 571c0ede..53bc9ff8 100644 --- a/mcp_server_dart/Dockerfile +++ b/mcp_server_dart/Dockerfile @@ -13,7 +13,7 @@ COPY lib/ ./lib/ COPY analysis_options.yaml ./ # Compile to native executable for better performance and smaller image -RUN dart compile exe bin/main.dart -o /app/mcp_server +RUN dart compile exe bin/flutter_mcp_toolkit_server.dart -o /app/mcp_server # Runtime stage - minimal image FROM debian:bookworm-slim diff --git a/mcp_server_dart/Dockerfile.dev b/mcp_server_dart/Dockerfile.dev index c90fe526..8a3887dc 100644 --- a/mcp_server_dart/Dockerfile.dev +++ b/mcp_server_dart/Dockerfile.dev @@ -35,4 +35,4 @@ USER mcpuser ENTRYPOINT ["/usr/bin/tini", "--"] # Run via dart VM (not compiled) for easier debugging -CMD ["dart", "run", "bin/main.dart", "--resources", "--images", "--log-level=debug"] +CMD ["dart", "run", "bin/flutter_mcp_toolkit_server.dart", "--resources", "--images", "--log-level=debug"] diff --git a/mcp_server_dart/Dockerfile.registry b/mcp_server_dart/Dockerfile.registry new file mode 100644 index 00000000..2e1b4d19 --- /dev/null +++ b/mcp_server_dart/Dockerfile.registry @@ -0,0 +1,44 @@ +# MCP Registry image build. This is intentionally separate from the legacy +# Dockerfiles so existing `docker build .` users keep their current contract. +# Build from mcp_server_dart: +# docker build -f Dockerfile.registry -t flutter-mcp-toolkit:registry . + +FROM dart:3.12.0-sdk AS build + +WORKDIR /app + +COPY pubspec.yaml ./pubspec.yaml +COPY pubspec.lock ./pubspec.lock +# The registry image resolves published sibling packages from the committed +# workspace lockfile, which keeps this image reproducible in CI. The lockfile +# is staged into the build context by publish_mcp_registry.yml. +RUN sed -i '/^resolution: workspace$/d' pubspec.yaml && dart pub get --enforce-lockfile + +COPY bin/ ./bin/ +COPY lib/ ./lib/ +COPY analysis_options.yaml ./ + +RUN dart compile exe bin/flutter_mcp_toolkit_server.dart -o /app/mcp_server + +FROM debian:bookworm-slim + +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates tini && \ + rm -rf /var/lib/apt/lists/* && \ + apt-get clean + +RUN useradd -r -u 1001 -g root mcpuser + +WORKDIR /app +COPY --from=build --chown=mcpuser:root /app/mcp_server /app/mcp_server +USER mcpuser + +ENTRYPOINT ["/usr/bin/tini", "--", "/app/mcp_server"] + +# Required by the MCP Registry. Additional OCI labels describe the server's +# semantic snapshots, built-in tools, and runtime client-tool registry. +LABEL io.modelcontextprotocol.server.name="io.github.Arenukvern/flutter-mcp-toolkit" \ + org.opencontainers.image.title="Flutter MCP Toolkit" \ + org.opencontainers.image.description="Flutter MCP server with semantic snapshots, ready-to-use interaction tools, and runtime-registered client tools and resources." + +CMD ["--resources", "--images", "--log-level=error", "--environment=production"] diff --git a/mcp_server_dart/analysis_options.yaml b/mcp_server_dart/analysis_options.yaml index 5995bc6d..deea216a 100644 --- a/mcp_server_dart/analysis_options.yaml +++ b/mcp_server_dart/analysis_options.yaml @@ -10,6 +10,13 @@ analyzer: exclude: - test/fixtures/migrate/** + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** errors: cascade_invocations: ignore lines_longer_than_80_chars: ignore diff --git a/mcp_server_dart/lib/src/skill_assets.g.dart b/mcp_server_dart/lib/src/skill_assets.g.dart index 964b2886..f6d88ae1 100644 --- a/mcp_server_dart/lib/src/skill_assets.g.dart +++ b/mcp_server_dart/lib/src/skill_assets.g.dart @@ -2375,7 +2375,7 @@ Full Chrome runtime dogfood stays **local** until headless WebMCP is cost-effect static const String cursorPluginManifest = r'''{ "name": "flutter-mcp-toolkit", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop.", - "version": "4.0.0-dev.8", + "version": "4.0.0", "author": { "name": "Arenukvern", "url": "https://github.com/Arenukvern/mcp_flutter" @@ -2399,7 +2399,7 @@ Full Chrome runtime dogfood stays **local** until headless WebMCP is cost-effect '''; static const String codexPluginManifest = r'''{ "name": "flutter-mcp-toolkit", - "version": "4.0.0-dev.8", + "version": "4.0.0", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop.", "author": { "name": "Arenukvern", diff --git a/mcp_server_dart/pubspec.yaml b/mcp_server_dart/pubspec.yaml index 427e073c..b86017f1 100644 --- a/mcp_server_dart/pubspec.yaml +++ b/mcp_server_dart/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_mcp_toolkit_server -version: 4.0.0-dev.8 +version: 4.0.0 description: >- An MCP server for Flutter Inspector, exposing Flutter debugging and inspection tools to AI models via Dart VM service. publish_to: none environment: - sdk: '>=3.12.0 <4.0.0' + sdk: ">=3.12.0 <4.0.0" resolution: workspace executables: fmtk: flutter_mcp_toolkit @@ -18,9 +18,9 @@ dependencies: dart_mcp: ^0.5.0 dtd: ^4.0.0 equatable: ^2.0.8 - flutter_mcp_toolkit_capability_core: ^4.0.0-dev.8 - flutter_mcp_toolkit_capability_kernel: ^4.0.0-dev.8 - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_capability_core: ^4.0.0 + flutter_mcp_toolkit_capability_kernel: ^4.0.0 + flutter_mcp_toolkit_core: ^4.0.0 from_json_to_json: ^0.5.0 intentcall_core: ^0.6.0 intentcall_mcp: ^0.6.0 @@ -41,5 +41,4 @@ dependencies: dev_dependencies: lints: ^6.1.0 test: ^1.31.0 - xsoulspace_inference_core: ^0.1.0-beta.1 xsoulspace_lints: ^0.1.2 diff --git a/mcp_server_dart/server.json b/mcp_server_dart/server.json new file mode 100644 index 00000000..8af89b9f --- /dev/null +++ b/mcp_server_dart/server.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.Arenukvern/flutter-mcp-toolkit", + "title": "Flutter MCP Toolkit", + "description": "Inspect and drive Flutter debug apps/games: semantic snapshots, search, and custom client tools", + "repository": { + "url": "https://github.com/Arenukvern/mcp_flutter", + "source": "github", + "subfolder": "mcp_server_dart" + }, + "websiteUrl": "https://docs.page/arenukvern/mcp_flutter", + "version": "4.0.0", + "packages": [ + { + "registryType": "oci", + "registryBaseUrl": "https://ghcr.io", + "identifier": "ghcr.io/arenukvern/flutter-mcp-toolkit:4.0.0", + "transport": { + "type": "stdio" + } + } + ] +} diff --git a/mcp_toolkit/CHANGELOG.md b/mcp_toolkit/CHANGELOG.md index b1b1e7d6..aa3bd930 100644 --- a/mcp_toolkit/CHANGELOG.md +++ b/mcp_toolkit/CHANGELOG.md @@ -1,3 +1,4 @@ + # 4.0.0-dev.8 - Align package version and hosted sibling dependency constraints with the Flutter MCP Toolkit prerelease train. diff --git a/mcp_toolkit/analysis_options.yaml b/mcp_toolkit/analysis_options.yaml index 36b48019..098d5530 100644 --- a/mcp_toolkit/analysis_options.yaml +++ b/mcp_toolkit/analysis_options.yaml @@ -11,3 +11,10 @@ analyzer: unnecessary_library_directive: ignore exclude: - "**/*.g.dart" + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** diff --git a/mcp_toolkit/pubspec.yaml b/mcp_toolkit/pubspec.yaml index a1baf1ab..17e952c9 100644 --- a/mcp_toolkit/pubspec.yaml +++ b/mcp_toolkit/pubspec.yaml @@ -1,10 +1,10 @@ name: mcp_toolkit description: Flutter MCP Toolkit to add Flutter-specific methods to the MCP server repository: https://github.com/Arenukvern/mcp_flutter/tree/main/mcp_toolkit -version: 4.0.0-dev.8 +version: 4.0.0 environment: - sdk: '>=3.12.0 <4.0.0' - flutter: '>=3.44.0' + sdk: ">=3.12.0 <4.0.0" + flutter: ">=3.44.0" resolution: workspace dependencies: collection: ^1.19.1 @@ -12,7 +12,7 @@ dependencies: equatable: ^2.0.8 flutter: sdk: flutter - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_core: ^4.0.0 from_json_to_json: ^0.5.0 intentcall_core: ^0.6.0 intentcall_platform: ^0.6.0 diff --git a/packages/core/README.md b/packages/core/README.md index b810fe20..a93fbed5 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -11,7 +11,7 @@ No Flutter SDK, `dart_mcp`, or transport dependencies. ```yaml dependencies: - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_core: ^4.0.0 ``` ## Usage diff --git a/packages/core/analysis_options.yaml b/packages/core/analysis_options.yaml index f0e95fa7..ef570e90 100644 --- a/packages/core/analysis_options.yaml +++ b/packages/core/analysis_options.yaml @@ -3,6 +3,14 @@ include: package:lints/recommended.yaml analyzer: errors: invalid_annotation_target: ignore + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** language: strict-casts: true strict-inference: true diff --git a/packages/core/lib/src/runtime_version.dart b/packages/core/lib/src/runtime_version.dart index 8f09a28d..96aa5e3c 100644 --- a/packages/core/lib/src/runtime_version.dart +++ b/packages/core/lib/src/runtime_version.dart @@ -3,7 +3,7 @@ // Licensed under the MIT License. /// Single source of truth for runtime and protocol version metadata. -const kFlutterMcpVersion = '4.0.0-dev.8'; // x-release-please-version +const kFlutterMcpVersion = '4.0.0'; // x-release-please-version const kFlutterMcpMajorVersion = 4; // x-release-please-major const kCommandCatalogSchemaVersion = 'command-catalog/v1'; diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index 10464afa..46402441 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -3,7 +3,7 @@ description: >- Pure-Dart shared types for Flutter MCP Toolkit — command envelopes, result types, error codes, connection overrides, and capability models. No Flutter or transport dependencies. -version: 4.0.0-dev.8 +version: 4.0.0 license: MIT repository: https://github.com/Arenukvern/mcp_flutter/tree/main/packages/core issue_tracker: https://github.com/Arenukvern/mcp_flutter/issues @@ -15,7 +15,7 @@ topics: - debugging - agentic-harness environment: - sdk: '>=3.12.0 <4.0.0' + sdk: ">=3.12.0 <4.0.0" resolution: workspace dependencies: intentcall_schema: ^0.6.0 diff --git a/packages/server_capability_core/README.md b/packages/server_capability_core/README.md index e0a2aeeb..992ec39d 100644 --- a/packages/server_capability_core/README.md +++ b/packages/server_capability_core/README.md @@ -11,9 +11,9 @@ Server-side Dart only — no Flutter SDK dependency. ```yaml dependencies: - flutter_mcp_toolkit_capability_core: ^4.0.0-dev.8 - flutter_mcp_toolkit_capability_kernel: ^4.0.0-dev.8 - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_capability_core: ^4.0.0 + flutter_mcp_toolkit_capability_kernel: ^4.0.0 + flutter_mcp_toolkit_core: ^4.0.0 ``` ## Usage @@ -70,8 +70,8 @@ server tools. Operator migration uses hand-written `fmt_migrate_agent_entries`. | Requirement | Status | |-------------|--------| | `LICENSE`, `README.md`, `CHANGELOG.md` | Included | -| Hosted sibling deps in `pubspec.yaml` | kernel + core `^4.0.0-dev.8` | -| Publish **after** kernel and core `4.0.0-dev.8` on pub.dev | Required | +| Hosted sibling deps in `pubspec.yaml` | kernel + core `^4.0.0` | +| Publish **after** kernel and core `4.0.0` on pub.dev | Required | | `dart pub publish --dry-run` | Run before release | ## License diff --git a/packages/server_capability_core/analysis_options.yaml b/packages/server_capability_core/analysis_options.yaml index 4a67be0a..37102c75 100644 --- a/packages/server_capability_core/analysis_options.yaml +++ b/packages/server_capability_core/analysis_options.yaml @@ -1,3 +1,12 @@ +analyzer: + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** include: package:lints/recommended.yaml linter: diff --git a/packages/server_capability_core/lib/src/fmt_capability.dart b/packages/server_capability_core/lib/src/fmt_capability.dart index 9f9cfbca..5ab89122 100644 --- a/packages/server_capability_core/lib/src/fmt_capability.dart +++ b/packages/server_capability_core/lib/src/fmt_capability.dart @@ -26,7 +26,7 @@ final class FmtCapability implements Capability { 'Flutter MCP Toolkit — interaction, inspection, hot reload, diagnostics.'; @override - String get version => '4.0.0-dev.8'; // x-release-please-version + String get version => '4.0.0'; // x-release-please-version @override Future register(final CapabilityContext context) async { diff --git a/packages/server_capability_core/pubspec.yaml b/packages/server_capability_core/pubspec.yaml index 7ac2c96a..4f8bbd5d 100644 --- a/packages/server_capability_core/pubspec.yaml +++ b/packages/server_capability_core/pubspec.yaml @@ -3,7 +3,7 @@ description: >- Core Flutter MCP capability (`fmt`) — VM inspection, interaction, navigation, diagnostics, and hot-reload coordination. Server-side Dart; no Flutter SDK dependency. -version: 4.0.0-dev.8 +version: 4.0.0 license: MIT repository: >- https://github.com/Arenukvern/mcp_flutter/tree/main/packages/server_capability_core @@ -17,13 +17,13 @@ topics: - debugging - agentic-harness environment: - sdk: '>=3.12.0 <4.0.0' + sdk: ">=3.12.0 <4.0.0" resolution: workspace dependencies: collection: ^1.19.1 dart_mcp: ^0.5.0 - flutter_mcp_toolkit_capability_kernel: ^4.0.0-dev.8 - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_capability_kernel: ^4.0.0 + flutter_mcp_toolkit_core: ^4.0.0 from_json_to_json: ^0.5.0 intentcall_codegen: ^0.6.0 intentcall_core: ^0.6.0 diff --git a/packages/server_capability_kernel/README.md b/packages/server_capability_kernel/README.md index 77091ad0..00d43246 100644 --- a/packages/server_capability_kernel/README.md +++ b/packages/server_capability_kernel/README.md @@ -11,8 +11,8 @@ Pure Dart — no Flutter SDK or transport. ```yaml dependencies: - flutter_mcp_toolkit_capability_kernel: ^4.0.0-dev.8 - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_capability_kernel: ^4.0.0 + flutter_mcp_toolkit_core: ^4.0.0 ``` ## Usage @@ -32,8 +32,8 @@ Use `pubspec_overrides.yaml` in this directory (not published) to resolve `flutt | Requirement | Status | |-------------|--------| | `LICENSE`, `README.md`, `CHANGELOG.md` | Included | -| Hosted deps only in `pubspec.yaml` | `flutter_mcp_toolkit_core: ^4.0.0-dev.8` | -| Publish **after** `flutter_mcp_toolkit_core` `4.0.0-dev.8` is on pub.dev | Required for consumers | +| Hosted deps only in `pubspec.yaml` | `flutter_mcp_toolkit_core: ^4.0.0` | +| Publish **after** `flutter_mcp_toolkit_core` `4.0.0` is on pub.dev | Required for consumers | | `dart pub publish --dry-run` | Run before release | ## License diff --git a/packages/server_capability_kernel/analysis_options.yaml b/packages/server_capability_kernel/analysis_options.yaml index 4a67be0a..37102c75 100644 --- a/packages/server_capability_kernel/analysis_options.yaml +++ b/packages/server_capability_kernel/analysis_options.yaml @@ -1,3 +1,12 @@ +analyzer: + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** include: package:lints/recommended.yaml linter: diff --git a/packages/server_capability_kernel/pubspec.yaml b/packages/server_capability_kernel/pubspec.yaml index e12e81cd..aa4035ec 100644 --- a/packages/server_capability_kernel/pubspec.yaml +++ b/packages/server_capability_kernel/pubspec.yaml @@ -3,7 +3,7 @@ description: >- Capability kernel contracts for Flutter MCP Toolkit — composable MCP units, host services, tool/resource registration, and prefixed tool naming. Pure Dart; no Flutter or transport. -version: 4.0.0-dev.8 +version: 4.0.0 license: MIT repository: >- https://github.com/Arenukvern/mcp_flutter/tree/main/packages/server_capability_kernel @@ -11,10 +11,10 @@ issue_tracker: https://github.com/Arenukvern/mcp_flutter/issues documentation: >- https://github.com/Arenukvern/mcp_flutter/tree/main/packages/server_capability_kernel#readme environment: - sdk: '>=3.12.0 <4.0.0' + sdk: ">=3.12.0 <4.0.0" resolution: workspace dependencies: - flutter_mcp_toolkit_core: ^4.0.0-dev.8 + flutter_mcp_toolkit_core: ^4.0.0 intentcall_core: ^0.6.0 intentcall_schema: ^0.6.0 meta: ^1.18.0 diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 032154ba..e1a28d52 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "flutter-mcp-toolkit", - "version": "4.0.0-dev.8", + "version": "4.0.0", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop. Bundles skills, subagent, and MCP server registration.", "author": { "name": "Arenukvern", diff --git a/plugin/.codex-plugin/plugin.json b/plugin/.codex-plugin/plugin.json index 6c8880af..4c641080 100644 --- a/plugin/.codex-plugin/plugin.json +++ b/plugin/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "flutter-mcp-toolkit", - "version": "4.0.0-dev.8", + "version": "4.0.0", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop.", "author": { "name": "Arenukvern", diff --git a/plugin/.cursor-plugin/plugin.json b/plugin/.cursor-plugin/plugin.json index 922cc90c..eea0f1eb 100644 --- a/plugin/.cursor-plugin/plugin.json +++ b/plugin/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "flutter-mcp-toolkit", "description": "Flutter MCP toolkit: inspect and drive debug apps (semantic snapshot, tap, hot-reload) and register custom MCP tools and resources at runtime from your Flutter app or game via mcp_toolkit — closed agent feedback loop.", - "version": "4.0.0-dev.8", + "version": "4.0.0", "author": { "name": "Arenukvern", "url": "https://github.com/Arenukvern/mcp_flutter" diff --git a/plugin/EXPECTED_SERVER_VERSION b/plugin/EXPECTED_SERVER_VERSION index 9a838b4b..fcdb2e10 100644 --- a/plugin/EXPECTED_SERVER_VERSION +++ b/plugin/EXPECTED_SERVER_VERSION @@ -1 +1 @@ -4.0.0-dev.8 +4.0.0 diff --git a/pubspec.lock b/pubspec.lock index f6ca278b..e5153c4e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -460,10 +460,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.20" material_color_utilities: dependency: transitive description: @@ -476,10 +476,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" mime: dependency: transitive description: @@ -689,26 +689,26 @@ packages: dependency: transitive description: name: test - sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f url: "https://pub.dev" source: hosted - version: "1.31.0" + version: "1.31.1" test_api: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.12" test_core: dependency: transitive description: name: test_core - sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 url: "https://pub.dev" source: hosted - version: "0.6.17" + version: "0.6.18" typed_data: dependency: transitive description: @@ -737,10 +737,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: f36f9f3be64c6198714492bb455c11056e33e2f85d9a0b676a48301e44fdcf47 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.2" vm_service: dependency: transitive description: @@ -789,14 +789,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - xsoulspace_inference_core: - dependency: transitive - description: - name: xsoulspace_inference_core - sha256: "3507a8ed478716a74ab871a8640448c1f40f2bdbe331537110c97ae51e15a97f" - url: "https://pub.dev" - source: hosted - version: "0.1.0-beta.1" xsoulspace_lints: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a5acd3da..053e021a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,8 +4,6 @@ environment: sdk: ">=3.12.0 <4.0.0" workspace: - - packages/core - - packages/server_capability_kernel - - packages/server_capability_core + - packages/* - mcp_toolkit - mcp_server_dart diff --git a/release-please-config.json b/release-please-config.json index ea1a11a6..6b2a5f70 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -3,9 +3,8 @@ "packages": { ".": { "release-type": "simple", - "versioning": "prerelease", - "prerelease": true, - "prerelease-type": "dev", + "versioning": "default", + "prerelease": false, "package-name": "flutter-mcp-toolkit", "changelog-path": "CHANGELOG.md", "version-file": "VERSION", @@ -51,7 +50,12 @@ "packages/server_capability_core/pubspec.yaml", "packages/core/README.md", "packages/server_capability_kernel/README.md", - "packages/server_capability_core/README.md" + "packages/server_capability_core/README.md", + { + "type": "json", + "path": "mcp_server_dart/server.json", + "jsonpath": "$.version" + } ] } } diff --git a/tool/contracts/check_mcp_registry.sh b/tool/contracts/check_mcp_registry.sh new file mode 100644 index 00000000..4a75ff2d --- /dev/null +++ b/tool/contracts/check_mcp_registry.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# Verifies the MCP Registry manifest, OCI ownership label, and release wiring. +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SERVER_JSON="$ROOT_DIR/mcp_server_dart/server.json" +DOCKERFILE="$ROOT_DIR/mcp_server_dart/Dockerfile.registry" +RELEASE_WORKFLOW="$ROOT_DIR/.github/workflows/publish_mcp_registry.yml" +PUB_WORKFLOW="$ROOT_DIR/.github/workflows/pub_publish.yml" + +fail() { + echo "check_mcp_registry: $*" >&2 + exit 1 +} + +[[ -f "$SERVER_JSON" ]] || fail "missing mcp_server_dart/server.json" +[[ -f "$DOCKERFILE" ]] || fail "missing mcp_server_dart/Dockerfile.registry" +[[ -f "$RELEASE_WORKFLOW" ]] || fail "missing publish_mcp_registry.yml" +[[ -f "$PUB_WORKFLOW" ]] || fail "missing pub_publish.yml" + +export SERVER_JSON ROOT_DIR +ruby <<'RUBY' +require 'json' + +server = JSON.parse(File.read(ENV.fetch('SERVER_JSON'))) +version = File.read(File.join(ENV.fetch('ROOT_DIR'), 'VERSION')).strip +name = 'io.github.Arenukvern/flutter-mcp-toolkit' +description = server.fetch('description') +package = server.fetch('packages').find { |candidate| candidate['registryType'] == 'oci' } + +abort 'server name is not the repository-owned MCP namespace' unless server['name'] == name +abort 'description must be between 1 and 100 characters' unless description.length.between?(1, 100) +abort "server version #{server['version']} != VERSION #{version}" unless server['version'] == version +abort 'OCI package is missing' unless package +expected_identifier = "ghcr.io/arenukvern/flutter-mcp-toolkit:#{version}" +abort "OCI identifier #{package['identifier']} != #{expected_identifier}" unless package['identifier'] == expected_identifier +abort 'OCI package transport must be stdio' unless package.dig('transport', 'type') == 'stdio' +RUBY + +grep -Fq 'io.modelcontextprotocol.server.name="io.github.Arenukvern/flutter-mcp-toolkit"' "$DOCKERFILE" || + fail "Dockerfile is missing the exact MCP ownership label" +grep -Fq 'bin/flutter_mcp_toolkit_server.dart' "$DOCKERFILE" || + fail "Dockerfile does not compile the published server entrypoint" +grep -Fq 'docker/build-push-action' "$RELEASE_WORKFLOW" || + fail "publish workflow does not build and push the OCI image" +grep -Fq 'file: Dockerfile.registry' "$RELEASE_WORKFLOW" || + fail "publish workflow is not using the dedicated Registry Dockerfile" +grep -Fq 'github-oidc' "$RELEASE_WORKFLOW" || + fail "publish workflow does not use GitHub OIDC for MCP Registry authentication" +grep -Fq 'gh workflow run publish_mcp_registry.yml' "$PUB_WORKFLOW" || + fail "pub.dev publication does not trigger the dependent MCP Registry publication" + +echo "check_mcp_registry: manifest, OCI metadata, and release wiring are consistent for $(tr -d '[:space:]' < "$ROOT_DIR/VERSION")" diff --git a/tool/release/sync_version.sh b/tool/release/sync_version.sh index 45897155..b30d2cce 100755 --- a/tool/release/sync_version.sh +++ b/tool/release/sync_version.sh @@ -184,6 +184,18 @@ files.each do |path, keys| cursor[keys.last] = version File.write(path, JSON.pretty_generate(json) + "\n") end + +server_path = 'mcp_server_dart/server.json' +if File.exist?(server_path) + server = JSON.parse(File.read(server_path)) + server['version'] = version + server.fetch('packages').each do |package| + next unless package['registryType'] == 'oci' + + package['identifier'] = "ghcr.io/arenukvern/flutter-mcp-toolkit:#{version}" + end + File.write(server_path, JSON.pretty_generate(server) + "\n") +end RUBY echo "sync_version: synchronized release train to $version"