Docs

MCP Migration Guide

Migrate an existing bare MCP server to a signed, sandboxed MPP package.

Overview

If you have an existing MCP server — whether built with the TypeScript SDK, Python SDK, or another framework — this guide walks you through wrapping it as an MPP package. The process takes 15–30 minutes for a typical server.

Your existing MCP logic does not change. MPP wraps around the outside.

Step 1: Audit Your Capabilities

Before writing the manifest, list everything your server currently accesses:

# Find all fs module usage
grep -r "fs\." src/ --include="*.ts"

# Find all network calls
grep -r "fetch\|axios\|http\." src/ --include="*.ts"

# Find all process.env reads
grep -r "process\.env" src/ --include="*.ts"

This becomes the basis for your capability declaration. Be accurate — under-declaration causes sandbox violations; over-declaration flags your package to security reviewers.

Step 2: Add the MPP Manifest

Create mpp.manifest.json at your project root:

{
  "name": "@yourorg/your-existing-server",
  "version": "1.0.0",
  "description": "Your existing server description",
  "publisher": "Your Name <you@yourdomain.com>",
  "entrypoint": "dist/index.js",
  "mcp_version": "2024-11-05",
  "capabilities": {
    "filesystem": {
      "read": ["$HOME/.config/your-server"],
      "write": ["/tmp/your-server-cache"]
    },
    "network": {
      "outbound": ["api.yourdomain.com"]
    },
    "env": ["YOUR_API_KEY", "LOG_LEVEL"]
  }
}

Step 3: Generate Your Signing Key

mpp keys generate

This creates an Ed25519 key pair in ~/.mpp/keys/. The public key is registered with the MPP Registry under your account. The private key never leaves your machine.

Step 4: Build and Sign

npm run build      # your existing build step
mpp sign           # signs the manifest with your private key

Step 5: Publish

mpp publish

Step 6: Update Consumers

If agents or platform code currently loads your server directly (e.g., via stdio transport or a local path), update them to use the MPP runtime:

// Before — loading bare MCP server
const transport = new StdioServerTransport();

// After — loading via MPP runtime (auto-verified + sandboxed)
const result = await mppRuntime.invoke({
  package: "@yourorg/your-existing-server@1.0.0",
  method: "yourToolMethod",
  args: { ... },
});

Handling Sandbox Violations

During testing, you may see errors like:

SandboxViolation: Attempted fs.readFileSync('/etc/passwd') — not in capability manifest

This means your audit in Step 1 missed a capability. Add the path to your manifest, bump the patch version, re-sign, and re-publish.

These violations are intentional — the sandbox catches accesses you may not have noticed before.

Common Issues

ENOENT: no such file or directory in sandbox The tool is trying to access a path not declared in capabilities.filesystem.read. Add the path to the manifest.

NetworkError: blocked by sandbox An outbound HTTP call to a hostname not in capabilities.network.outbound. Add the hostname.

EnvAccessBlocked: process.env.SECRET The tool reads an env var not listed in capabilities.env. Add the variable name.

Rollback Strategy

Keep your existing bare MCP server running alongside the MPP-wrapped version during migration. Use feature flags or platform-level configuration to switch consumers one at a time. MPP packages are backwards-compatible with all MCP clients.