The inputSchema `type: "number"` is advisory only — runtime may receive a
string payload that gets interpolated into the osascript template. Coerce
tab_id via Number.parseInt before interpolating at all four sites.
Affected sites:
- findTabById(tabId)
- executeTabOperation(tabId, ...) (close_tab, switch_to_tab, reload_tab,
go_back, go_forward)
- execute_javascript handler
- get_page_content handler
The shared toSafeTabId() helper returns null for missing values (preserving
the active-tab fallthrough) and throws on non-numeric input (surfacing misuse
via the existing request-level try/catch, consistent with the missing-code
path in execute_javascript).
When server.type is "binary", mcpb pack now ensures the entry_point
file has execute bits (|0o111) in the ZIP external_attr, regardless
of the source filesystem permissions. This prevents EACCES failures
when Claude Desktop extracts Windows-built binary MCPBs (which store
644 because Windows has no Unix execute bit).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
platform_overrides.*.env was replacing the entire mcp_config.env object
instead of merging, causing base env vars (including ${user_config.*}
references) to be silently dropped when platform overrides defined any
env vars.
Fixes#217
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add three pre-pack validators to catch common runtime failures early:
- validateEntryPoint: checks file exists, extension matches server type,
binary has executable bit (Unix)
- validateCommandVariables: scans mcp_config for unrecognized ${...}
variables against the runtime allowlist
- validateSensitiveFiles: warns about credentials.json, *.pem, *.key,
.ssh/, etc. that would be bundled
validateManifest() now accepts optional { projectDir } to separate the
manifest directory from the source file directory.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow specifying an external manifest file path with `mcpb pack --manifest <path>`.
The manifest resolves relative to CWD, is validated, injected into the bundle,
and errors immediately if the specified file is not found.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Align with other examples — no example ships a Dockerfile or its own
.gitignore. Rust build artifacts are now covered by the repo-level
.gitignore instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
First example of the binary server type — a compiled Rust MCP server
packaged as an MCPB. Based on the official Rust SDK calculator example
(rmcp 1.2.0, 2 tools: sum/sub, ~80 LOC).
Includes Cargo.toml, Dockerfile for Docker-based builds, .mcpbignore
to exclude source from the bundle, and README with build/pack/test
instructions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- hello-world-node: wrap server startup in async main() with proper
await on server.connect(transport) — fixes crash on initialize in
Claude Desktop UtilityProcess runtime (closes#200)
- hello-world-uv: add required mcp_config block — v0.4 schema requires
it but the example omitted it, causing mcpb pack to fail
- file-manager-python: convert from broken v0.1/python to v0.4/uv —
the old manifest had privacy_policies on v0.1 (schema violation),
used command "python" (ENOENT on macOS), and had no bundled deps.
Now uses UV runtime with proper mcp_config (closes#47, closes#72)
- Graduate UV runtime from experimental across docs and schema comments
- Bump DEFAULT_MANIFEST_VERSION from 0.2 to 0.3
All three examples verified: pack succeeds, server responds to MCP
initialize over stdio, tools/list returns expected tools.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The signMcpbFile function appended a signature block to the ZIP file but
did not update the EOCD comment_length field. Strict ZIP parsers (like
Claude Desktop's) rejected these files because the declared comment
length didn't account for the appended signature data.
Now scans backwards for the EOCD magic bytes, reads the current
comment_length, and adds the signature block length before concatenating.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Break function parameters onto separate lines with trailing comma.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Allow developers to specify which manifest version to use when
initializing a new manifest.json file.
Usage: mcpb init --manifest-version 0.3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add UV as a new server type for Python extensions that use UV runtime
for dependency management instead of bundling dependencies.
Schema changes (v0.4):
- Add "uv" to server.type enum
- Make mcp_config optional (not needed for UV type)
- UV extensions rely on pyproject.toml for dependencies
Documentation:
- Add UV runtime section to MANIFEST.md explaining benefits and usage
- Update README.md to recommend UV runtime for Python
- Add complete hello-world-uv example
Benefits of UV runtime:
- Cross-platform support (Windows/macOS/Linux, Intel/ARM)
- Small bundle size (~100 KB vs 5-10 MB)
- Handles compiled dependencies portably
- No user Python installation required
Example manifest:
{
"manifest_version": "0.4",
"server": {
"type": "uv",
"entry_point": "src/server.py"
}
}
Co-authored-by: Joan <joan@anthropic.com>
- Export McpbManifestAny and Logger types from types.js
- Export McpbSignatureInfo and McpbUserConfigValues from shared/common.ts
- Add exports to both main and browser entry points
- Bump version to 2.0.1
This eliminates the need for manual type inference in consuming code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The localization parameter is commented out in the buildManifest function
signature, so it should also be commented out in the test calls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The buildManifest function signature has the localization parameter
commented out (expecting 13 params), but the function call was still
passing it as the 14th argument, causing a type error.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed all entry points (index.ts, cli.ts, node.ts) to export from schemas/index.js
instead of schemas/0.3.js. This provides access to all versioned schemas (v0_1, v0_2,
v0_3, vAny) and VERSIONED_MANIFEST_SCHEMAS without exposing a specific version.
The build script was still importing from the deleted schemas/latest.js file.
Updated to import McpbSignatureInfoSchema from 0.3.js and removed the
mcpb-manifest-latest entry from versionedManifestSchemas.