MCPB packaging
The repository can produce a deterministic MCP Bundle (.mcpb) for local desktop MCP
hosts. Packaging copies the existing generic server, versioned configuration, and
accepted graph-package repository into a clean stage; it does not introduce a second
runtime implementation or alter curriculum data.
What the bundle contains
A retained stage has this shape:
kgfegmcp-stage/
├── .mcpbignore
├── README.md
├── fastmcp.json
├── manifest.json
├── pyproject.toml
├── uv.lock
├── config/
│ ├── profiles/
│ └── prompts/
├── data/
│ └── graph_packages/
└── src/
└── kgfegmcp/
The .mcpbignore file controls the packer but is excluded from the independently
verified archive-member set.
The build deliberately does not package:
.venvor another virtual environment;- caches and
__pycache__directories; .pycor.pyobytecode;- local logs or build output;
- Git metadata;
- arbitrary files outside the approved staging contract.
Prerequisites
Install:
uv;- Node.js and npm; and
- the official MCPB CLI.
Confirm the executables:
The repository must also contain the locked backend project metadata, including
backend/uv.lock.
The lock file is part of the distribution contract
Both uv --locked execution and MCPB staging require uv.lock. Do not silently
generate or replace the lock file during a packaging review unless you intend to
change the dependency lock as a separate repository update.
Runtime contract
The template manifest declares MCPB manifest version 0.4 and a UV server runtime.
The packaged MCP configuration starts:
It also sets the bundle root as PATHS_PROJECT_DIR and supplies explicit bundle-local
profile, prompt, data, and graph-package paths.
Keep the Python module launcher
The manifest contains src/kgfegmcp/mcpb_server.py as its declared entry-point
artifact, but the actual MCP command must execute
python -m kgfegmcp.mcpb_server. Direct filesystem execution can cause the internal
kgfegmcp.mcp package to shadow the external MCP SDK package named mcp.
Build flow
%%{init: {"themeVariables": {"fontSize": "18px"}}}%%
flowchart TB
SRC[Repository source + config + graph packages] --> PREFLIGHT[Validate project/manifest contract]
PREFLIGHT --> STAGE[Assemble clean stage]
STAGE --> SAFETY[Reject symlinks, special files, unsafe/unexpected paths]
SAFETY --> OFFICIAL[mcpb validate + mcpb pack]
OFFICIAL --> ARCHIVE[Generated .mcpb archive]
ARCHIVE --> VERIFY[Reopen and independently verify archive]
STAGE --> VERIFY
VERIFY --> BYTE[Require stage-to-archive byte identity]
BYTE --> DONE[Report archive path]
Build the default archive
From the repository root:
For version 0.1.0, the default output is:
The command removes an existing file at the selected output path before packing a new archive.
Retain the exact stage
The default stage is temporary. Retain it for review and independent runtime acceptance:
rm -rf ./dist/kgfegmcp-stage
uv --directory backend run --locked --no-dev \
kgfegmcp-build-mcpb \
--stage-output ./dist/kgfegmcp-stage
The requested stage location must either not exist or be a completely empty directory. The output archive may not be placed inside the stage.
Choose another archive path
uv --directory backend run --locked --no-dev \
kgfegmcp-build-mcpb \
--output ./dist/review-build.mcpb
You can combine --output, --stage-output, and --mcpb-command.
Use a specific MCPB executable
If mcpb is not on PATH, or you need to test a specific installation:
uv --directory backend run --locked --no-dev \
kgfegmcp-build-mcpb \
--mcpb-command /absolute/path/to/mcpb
Manifest/project cross-checks
Before packing, the builder requires the MCPB manifest to agree with the packaged Python project. The reviewed contract fixes, among other things:
- package name and version agreement;
- MCPB manifest version
0.4; - server type
uv; - declared entry-point artifact
src/kgfegmcp/mcpb_server.py; - the exact module-launch MCP arguments;
- the expected bundle-local environment; and
- the project Python/dependency metadata needed by the UV runtime.
Changing the packaging manifest independently of the backend project can therefore make the build fail before an archive is produced.
Filesystem safety checks
The staging step requires regular source files and directory trees. It rejects:
- missing required files or directories;
- symbolic links;
- special filesystem entries;
- a stage located inside a source tree that is being copied;
- a non-empty retained stage; and
- ignored local-development/build artifacts.
Archive verification then rejects:
- absolute paths;
- parent traversal (
..); - backslash-based unsafe names;
- duplicate archive members;
- archive symlinks;
- missing required paths;
- unexpected members; and
- any file whose bytes differ from the retained stage.
This means successful mcpb pack execution is necessary but not sufficient: the
repository performs its own post-pack verification before reporting success.
Smoke-test before packaging
First exercise the ordinary checkout:
A passing repository smoke demonstrates that the accepted graph packages, profiles, prompt configurations, MCP registration, and representative resource reads work before packaging is introduced.
Smoke-test the retained stage
After building with --stage-output:
uv --directory backend run --locked --no-dev \
kgfegmcp-stdio-smoke \
--bundle-root ./dist/kgfegmcp-stage
This changes both the uv runtime root and the application project root to the retained
stage, providing a useful test that the package no longer depends on repository-local
paths.
Inspect the archive manually
List members:
Inspect the packaged manifest:
Inspect the server declaration:
Test ZIP integrity:
Recommended acceptance sequence
# Repository runtime
uv --directory backend run --locked --no-dev kgfegmcp-stdio-smoke
# Clean, retained stage + archive
rm -rf ./dist/kgfegmcp-stage
uv --directory backend run --locked --no-dev \
kgfegmcp-build-mcpb --stage-output ./dist/kgfegmcp-stage
# Packaged runtime
uv --directory backend run --locked --no-dev \
kgfegmcp-stdio-smoke --bundle-root ./dist/kgfegmcp-stage
# Archive-level sanity check
unzip -t ./dist/kgfegmcp-0.1.0.mcpb
A strong release baseline requires all four steps to pass.
Claude Desktop installation
The bundle is intended for a custom-extension installation flow, but installation behavior can vary by Claude Desktop build. A client may recognize a valid bundle while still preventing installation because of client-side prerequisite checks.
Treat bundle installation as a client surface separate from server acceptance. If both repository and retained-stage STDIO smoke tests pass, do not change the server runtime merely to work around an installation UI issue.
The confirmed development connection remains manual STDIO registration through Claude Desktop's MCP configuration. See Connect an MCP client.
Packaging is behavior-preserving
The builder copies the accepted runtime inputs. It does not modify:
- graph packages or package validation state;
- interpretation profiles;
- prompt configurations;
- search or traversal behavior;
- comparison or progression evidence behavior;
- resource policy; or
- the public MCP inventory.
A staged-runtime smoke test exists specifically to verify this distribution boundary.
Next: Troubleshooting