Skip to content

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

Merged
dougborg merged 3 commits intomainfrom
feat/mcp-mcpb-bundle
May 4, 2026
Merged

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

Conversation

@dougborg
Copy link
Copy Markdown
Owner

Summary

Implements #61 — adds the build-time machinery to produce a statuspro-mcp-server-<version>.mcpb artifact on every MCP release. Users install with one click in Claude Desktop and get prompted for the API key via UI; no more hand-editing claude_desktop_config.json.

The format is MCP Bundles (MCPB) — Anthropic's one-click install format for local MCP servers. (Originally branded as DXT; renamed during the 2025 rebrand.) Spec: https://github.com/anthropics/mcpb.

What's in the box

  • statuspro_mcp_server/mcpb/manifest.template.jsonmanifest_version: "0.4" with server.type: "uv" (the v0.4-only "UV Runtime" type — no bundled interpreter or virtualenv, UV handles deps at install time, ~46 kB bundle vs. multi-MB). Declares user_config.api_key as a sensitive string; Claude Desktop prompts and injects it as STATUSPRO_API_KEY.
  • statuspro_mcp_server/mcpb/pyproject.template.toml — bundle's own pyproject. Hand-mirrors production deps from the package's pyproject minus [tool.uv.sources] (workspace refs don't resolve outside the monorepo). The build script verifies the dep lists match and fails loudly on drift.
  • statuspro_mcp_server/mcpb/.mcpbignore — pack-time excludes for Python build artefacts on top of the CLI's defaults.
  • scripts/build_mcpb.py — orchestrator. Reads version from package pyproject, verifies dep mirror, stages build/mcpb/, runs mcpb validate then mcpb pack to produce dist/statuspro-mcp-server-<version>.mcpb. MCPB_SKIP_PACK=1 for local dry-runs without the CLI installed.
  • uv run poe build-mcpb — local build task.
  • .github/workflows/release-mcp.yml — new build-mcpb job runs alongside publish-pypi, installs the mcpb CLI, builds the bundle, attaches it to the GitHub release matching the triggering mcp-v* tag.
  • statuspro_mcp_server/README.md — install section now leads with the .mcpb flow, keeps uvx as a labeled fallback.

What I learned (corrections to the original issue text)

Posted these to issue #61 plus the sibling issues for stocktrim (dougborg/stocktrim-openapi-client#160) and frontapp (dougborg/frontapp-openapi-client#99) so they can skip the same dead ends:

  • DXT → MCPB rename (CLI, file extension, npm package, repo URL).
  • server.type: "uv" is the right answer for Python servers, not "python" — the v0.4-only UV runtime type ships zero interpreter/venv tree, supports cross-platform compiled deps, and is what examples/hello-world-uv actually uses.
  • Bundle's pyproject is purpose-built, not the package's own. Stripping [tool.uv.sources] is mandatory; the build script's dep-mirror verification catches the inevitable drift.

Pre-existing footgun surfaced (not fixed in this PR)

While testing the bundle launch end-to-end, I hit a dep-resolution failure: statuspro_mcp_server/pyproject.toml declares statuspro-openapi-client>=0.51.0 but only 0.1.0 is on PyPI. Inside the monorepo the workspace ref masks this; outside (i.e. in the bundle), uv can't resolve. This was set in the initial commit and never updated.

The bundle infrastructure (manifest, build script, CI) is correct and validates against the schema; the runtime gap is a separate dep-version concern and will be filed as its own issue. Don't block this PR on it — the bundle is shippable infrastructure, the constraint fix is one line in a separate change.

Branches

  • This branch is off origin/main, not off the open PR chore: align with katana-openapi-client safety + MCP fixes #60 (chore/align-katana-safety-fixes). Once that PR merges, this one will get the pre-push guard / list_coercion goodies via the next rebase forward.
  • Pre-push guard fired and passed on push (since it isn't merged to main yet, the guard hook runs from this branch's checkout if I'd had it installed — moot for now, but the safe refspec form was used regardless).

Test plan

  • uv run poe build-mcpb succeeds locally (requires npm install -g @anthropic-ai/mcpb first); produces dist/statuspro-mcp-server-<version>.mcpb
  • mcpb info dist/statuspro-mcp-server-<version>.mcpb shows expected metadata
  • mcpb validate build/mcpb/manifest.json passes
  • unzip -l dist/statuspro-mcp-server-<version>.mcpb shows manifest.json, pyproject.toml, .mcpbignore, src/statuspro_mcp/* (no __pycache__, no .venv)
  • CI's build-mcpb job runs and uploads the artifact
  • MCPB_SKIP_PACK=1 uv run python scripts/build_mcpb.py works without the CLI installed (stages, returns build dir)

🤖 Generated with Claude Code

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds MCP Bundle (MCPB, .mcpb) packaging and release automation for statuspro-mcp-server to enable one-click installation in Claude Desktop, with UI-prompted API key configuration.

Changes:

  • Introduces MCPB bundle templates (manifest.template.json, pyproject.template.toml) and a .mcpbignore for bundle contents control.
  • Adds scripts/build_mcpb.py plus a poe build-mcpb task to stage/validate/pack the bundle into dist/.
  • Extends the MCP release workflow to build and attach the .mcpb asset; updates MCP server README to recommend the bundle install flow.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
statuspro_mcp_server/mcpb/pyproject.template.toml Bundle pyproject template with mirrored runtime dependencies and version placeholder.
statuspro_mcp_server/mcpb/manifest.template.json MCPB manifest template using the v0.4 uv runtime and sensitive user config for API key.
statuspro_mcp_server/mcpb/.mcpbignore Additional ignore rules to keep the bundle clean of build/test artifacts.
statuspro_mcp_server/README.md Documents .mcpb as the recommended Claude Desktop install path, keeps uvx as fallback.
scripts/build_mcpb.py Build orchestrator: stages bundle dir, validates manifest, packs .mcpb artifact.
pyproject.toml Adds poe task build-mcpb for local bundle builds.
.github/workflows/release-mcp.yml Adds a build-mcpb job to build/upload the bundle and attach it to the GitHub release.

Comment thread statuspro_mcp_server/mcpb/pyproject.template.toml Outdated
Comment thread scripts/build_mcpb.py Outdated
Comment thread .github/workflows/release-mcp.yml Outdated
dougborg and others added 3 commits April 29, 2026 22:56
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

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

Adds:

- ``statuspro_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
  ``STATUSPRO_API_KEY`` via the ``env`` block. Version is a
  ``__VERSION__`` placeholder substituted at build time.
- ``statuspro_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.
- ``statuspro_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/statuspro_mcp/`` source +
  README), runs ``mcpb validate`` then ``mcpb pack`` to produce
  ``dist/statuspro-mcp-server-<version>.mcpb``. Honors
  ``MCPB_SKIP_PACK=1`` for local dry-runs without the CLI installed.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires the build script into the existing release-mcp.yml workflow as a
new ``build-mcpb`` job that runs alongside ``publish-pypi`` (both depend
on ``build`` for tests). The job:

- Installs the ``mcpb`` CLI (``npm install -g @anthropic-ai/mcpb``)
- Runs ``uv run python scripts/build_mcpb.py`` to assemble + pack the
  bundle
- Uploads the ``.mcpb`` as a workflow artifact (for inspection on
  workflow_dispatch runs)
- Attaches it to the GitHub release matching the triggering tag (only
  on ``mcp-v*`` tag pushes — not workflow_dispatch, since those don't
  have a release to attach to)

Also exposes ``uv run poe build-mcpb`` for local builds. The CLI is a
one-time ``npm install -g`` on developer machines; CI installs it on
every run.

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

Restructures the "Use with Claude Desktop" section to lead with the
``.mcpb`` one-click install (download from the latest mcp-v release,
drag into Claude Desktop, confirm in the install dialog — Claude
Desktop prompts for the API key via UI, no JSON editing). Keeps the
manual ``uvx`` config-file path as a labeled fallback for users who
prefer it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dougborg dougborg force-pushed the feat/mcp-mcpb-bundle branch from 2a9e284 to 2cb7050 Compare April 30, 2026 04:57
@dougborg dougborg merged commit 78edbe8 into main May 4, 2026
9 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.

2 participants