Skip to content

feat(mcp): package server as MCPB (.mcpb) for one-click Claude Desktop install#102

Open
dougborg wants to merge 3 commits intomainfrom
feat/mcp-mcpb-bundle
Open

feat(mcp): package server as MCPB (.mcpb) for one-click Claude Desktop install#102
dougborg wants to merge 3 commits intomainfrom
feat/mcp-mcpb-bundle

Conversation

@dougborg
Copy link
Copy Markdown
Owner

@dougborg dougborg commented May 4, 2026

Summary

Packages `frontapp-mcp-server` as an MCP Bundle (.mcpb) — Claude Desktop's one-click install format for local MCP servers. The bundle ships the server source plus a manifest declaring runtime requirements and prompting for `FRONTAPP_API_KEY` via the Claude Desktop UI (no JSON config editing).

Closes #99. Near-direct port of statuspro PR #62 — same monorepo layout, same UV-runtime bundle pattern, same dep-mirror verification.

What's added

  • `frontapp_mcp_server/mcpb/manifest.template.json` — `manifest_version: "0.4"`, `server.type: "uv"`, `VERSION` placeholder substituted at build time, `user_config.api_key` (sensitive string) injected as `FRONTAPP_API_KEY`.
  • `frontapp_mcp_server/mcpb/pyproject.template.toml` — bundle's own pyproject; mirrors the package's production deps, omits `[tool.uv.sources]` workspace ref (which doesn't resolve outside the monorepo).
  • `frontapp_mcp_server/mcpb/.mcpbignore` — Python build excludes (`pycache`, `.venv`, etc.).
  • `scripts/build_mcpb.py` — orchestrator. Reads version from package pyproject, verifies the dep mirror and fails loudly on drift, stages `build/mcpb/`, runs `mcpb validate` + `mcpb pack`. Stdlib-only; honors `MCPB_SKIP_PACK=1` for dry-runs.
  • `pyproject.toml` — `build-mcpb` poe task.
  • `.github/workflows/release-mcp.yml` — `build-mcpb` job runs alongside the PyPI publish on `mcp-v*` tags; uploads the `.mcpb` as a workflow artifact and attaches it to the GitHub release.
  • `frontapp_mcp_server/README.md` — Claude Desktop install section now leads with the `.mcpb` flow, with the manual `uvx` config kept as a labeled fallback.

Bundled bug fix

The bundle surfaced a pre-existing footgun: `frontapp_mcp_server/pyproject.toml` declared `frontapp-openapi-client>=0.51.0` but only 0.1.0 ever existed (workspace ref hides this in-monorepo, but the bundle resolves from PyPI). Fixed the constraint to `>=0.1.0`; the bundle template mirrors it; the build script's dep-mirror check keeps them in sync going forward. Same exact bug + fix as statuspro #62.

Build output

```
Output: dist/frontapp-mcp-server-0.1.0.mcpb

  • name: frontapp-mcp-server
  • version: 0.1.0
  • package size: 77.3 kB
  • unpacked size: 263.1 kB
  • total files: 34
    ```

Test plan

  • `uv run poe agent-check` passes (format + lint + typecheck + facts).
  • `python scripts/build_mcpb.py` produces `dist/frontapp-mcp-server-0.1.0.mcpb` (77.3 kB / 34 files).
  • `mcpb info dist/frontapp-mcp-server-0.1.0.mcpb` reads bundle metadata cleanly.
  • `mcpb validate` passes against MCPB schema 0.4.
  • Bundle dep-mirror verification triggered (manually edited the template, confirmed it fails the build, reverted).
  • End-to-end launch (`uv run --directory build/mcpb frontapp-mcp-server --help`) is gated on `frontapp-openapi-client` being on PyPI; that lands with chore(ci): re-enable release workflow push triggers once PyPI/NPM tokens are configured #10. UV reaches dep resolution and only fails because the package is unpublished — bundle structure is correct.
  • CI `build-mcpb` job builds + uploads on this PR (no tag → no release upload).

🤖 Generated with Claude Code

dougborg and others added 3 commits May 4, 2026 09:52
MCP Bundles (formerly DXT — renamed during Anthropic's 2025 rebrand) are
Claude Desktop's one-click install format for local MCP servers. A .mcpb
is a zip containing the server source plus a manifest.json declaring
metadata, runtime requirements, and user-config (env-var) prompts.

Refs:
- Spec: https://github.com/anthropics/mcpb/blob/main/MANIFEST.md
- Reference: https://github.com/anthropics/mcpb/tree/main/examples/hello-world-uv
- Tracking issue: #99
- Pattern ported from statuspro PR #62 (dougborg/statuspro-openapi-client#62)

This commit lands just the build mechanics; CI wiring + docs follow in
sibling commits.

Adds:

- ``frontapp_mcp_server/mcpb/manifest.template.json`` — manifest_version
  0.4 with ``server.type = "uv"`` (matches the hello-world-uv reference;
  delegates dep resolution to UV at install time, no bundled interpreter
  or virtualenv). Declares ``user_config.api_key`` as a sensitive string,
  which Claude Desktop prompts for at install and injects as
  ``FRONTAPP_API_KEY`` via the ``env`` block. Version is a
  ``__VERSION__`` placeholder substituted at build time.
- ``frontapp_mcp_server/mcpb/pyproject.template.toml`` — bundle's own
  pyproject. Hand-mirrors production deps from the package's pyproject
  but omits the ``[tool.uv.sources]`` workspace ref, which doesn't
  resolve outside the monorepo. The build script verifies the dep lists
  match and fails loudly on drift.
- ``frontapp_mcp_server/mcpb/.mcpbignore`` — pack-time excludes for
  Python build artefacts (``__pycache__/``, ``.venv/``, etc.) on top of
  the CLI's defaults.
- ``scripts/build_mcpb.py`` — orchestrator. Reads the package's
  pyproject for the version, verifies the bundle dep mirror, stages
  ``build/mcpb/`` (manifest + pyproject + ``src/frontapp_mcp/`` source +
  README), runs ``mcpb validate`` then ``mcpb pack`` to produce
  ``dist/frontapp-mcp-server-<version>.mcpb``. Honors
  ``MCPB_SKIP_PACK=1`` for local dry-runs without the CLI installed.
- ``[tool.poe.tasks].build-mcpb`` — convenience entry point.

Also fixes a pre-existing dep-constraint bug surfaced by the bundle:
``frontapp_mcp_server/pyproject.toml`` declared
``frontapp-openapi-client>=0.51.0`` but only 0.1.0 (and below) ever
existed. The workspace ref hides this inside the monorepo, but the
bundle resolves from PyPI and would fail on launch. Constraint is now
truthful (``>=0.1.0``) and the bundle template mirrors it; the build
script's dep-mirror verification keeps them in sync going forward.

Verified end-to-end with ``mcpb`` CLI v2.1.2 — manifest validates
against the schema; the produced .mcpb (77.3 kB, 34 files) inspects
correctly via ``mcpb info``.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a ``build-mcpb`` job to ``.github/workflows/release-mcp.yml`` that
runs alongside the existing PyPI publish job on ``mcp-v*`` tag pushes:

- Sets up Python (no uv — the build script is stdlib-only) and Node 20.
- Installs the ``mcpb`` CLI via npm.
- Runs ``python scripts/build_mcpb.py``; captures the artifact path
  printed on stdout.
- Uploads the .mcpb as a workflow artifact.
- On real tag pushes (``startsWith(github.ref, 'refs/tags/mcp-v')``)
  attaches the .mcpb to the existing GitHub release that
  semantic-release created earlier in the workflow.

Each ``mcp-v*`` tag now produces both a PyPI wheel and a downloadable
``.mcpb`` on the release page, ready for one-click install in Claude
Desktop.

Pattern ported from statuspro PR #62 (dougborg/statuspro-openapi-client#62).
Refs #99.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…top flow

Reorders the Claude Desktop section in
``frontapp_mcp_server/README.md`` to lead with the .mcpb bundle
(download from the latest mcp-v release, drag into Claude Desktop,
prompts for the API key via UI) and demote the manual ``uvx`` JSON
config to a labeled fallback.

The .mcpb path is friendlier for non-technical users — no JSON editing,
no remembering env-var names, and the API key is stored in Claude
Desktop's secrets store rather than a plaintext config file.

Updates the dev-mode caveat note to mention both ``.mcpb`` and ``uvx``
resolve from PyPI (so neither works against an unpublished local clone
until issue #10 lands the publish workflow).

Pattern ported from statuspro PR #62 (dougborg/statuspro-openapi-client#62).
Refs #99.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 4, 2026 15:53
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.

Package MCP server as DXT for one-click Claude Desktop install

1 participant