You’ve built an MCP server. It connects your AI agent to a system that matters: your CRM, your database, your internal API. It works locally. Now you want to make it available to the ecosystem: discoverable, installable, security-scanned, and trusted. Here’s how you go from working server to published package on mpak.dev.

The full process is four phases: prepare, package, validate, publish. For a simple server (single integration, straightforward dependencies), the whole thing takes under 30 minutes.

Prerequisites

Before you start, you need three things.

A working MCP server. The server must start, respond to the MCP initialize handshake, and expose at least one tool. It should handle the standard MCP lifecycle: initialization, tool listing, tool execution, and shutdown. If your server doesn’t implement these basics, fix that first. mpak can’t distribute a server that doesn’t follow the protocol.

The mpak CLI. Install it with your package manager of choice. The CLI handles packing, validation, and publishing from your terminal. The mpak CLI includes mcpb pack for bundling and mpak publish for submitting to the registry.

A GitHub account. Author verification runs against GitHub. Your GitHub profile links to your published packages, and verified accounts receive higher author verification scores in the MTF evaluation. You authenticate with the mpak CLI through GitHub OAuth.

Phase 1: Prepare the Metadata

A MCPB bundle needs two metadata files beyond your server code: manifest.json and mcpb.json. These files declare your server’s identity, runtime requirements, and security scope.

manifest.json

Create a manifest.json in your server’s root directory:

{
  "name": "your-server-name",
  "version": "0.1.0",
  "description": "One sentence: what system this server connects to and what it does",
  "author": "Your Name <your.email@example.com>",
  "license": "MIT",
  "keywords": ["relevant", "searchable", "terms"],
  "mcp_version": "1.0"
}

Naming conventions. Lowercase, hyphens as separators. Descriptive of the target system: salesforce-mcp, postgres-mcp, slack-mcp. Avoid generic names (my-server, test-mcp). The name is what users search for, so make it findable.

Versioning. Start at 0.1.0 for initial publish. Semantic versioning: patch for bug fixes, minor for new tools or features, major for breaking changes. For servers forked from upstream projects, use the -mcpb.N suffix to track your modifications: 1.2.0-mcpb.1.

Description. One sentence, front-loaded with the key information. “MCP server for Salesforce CRM: contacts, opportunities, accounts, and pipeline analytics” beats “A server that provides MCP connectivity.” The description shows in search results. Make every word count.

mcpb.json

Create a mcpb.json that declares how to run your server:

{
  "mcp_config": {
    "command": "python",
    "args": ["-m", "your_package.server"],
    "env": {
      "API_KEY": {
        "description": "API key for the target service",
        "required": true
      }
    }
  },
  "permissions": {
    "network": ["api.targetservice.com"],
    "filesystem": "none"
  }
}

For Python servers: Use module execution. "command": "python" with "args": ["-m", "package_name.server"]. This handles relative imports correctly. Your server needs if __name__ == "__main__": mcp.run() as the entry point. mpak sets PYTHONPATH=deps/ automatically at runtime.

For TypeScript/Node servers: Point to the compiled entry. "command": "node" with "args": ["${__dirname}/dist/index.js"]. Compile TypeScript before packing; the bundle includes JavaScript output, not TypeScript source.

Environment variables. Declare every environment variable your server reads. Include a description and whether it’s required or optional. Users see this before installation. Security teams see this during evaluation. Missing environment variable declarations are the second most common validation failure.

Permissions. Be specific. Declare the exact network endpoints your server connects to (api.salesforce.com, not *). Declare filesystem access only if your server reads or writes files. "filesystem": "none" is the correct declaration for most servers. The MTF scanner compares your declarations against actual behavior, and overly broad or missing permissions lower your trust score.

Phase 2: Package the Bundle

With metadata files in place, run the MCPB packager:

mcpb pack

The packager does four things:

  1. Reads manifest.json and mcpb.json. Validates that required fields are present and correctly formatted.
  2. Resolves and vendors dependencies. For Python: installs dependencies into a deps/ directory. For Node: runs npm install into a local node_modules/. All dependencies are bundled, with no install-time resolution for the end user.
  3. Bundles the server code. Copies the server implementation, vendored dependencies, and metadata into the distributable bundle structure.
  4. Produces the artifact. Creates the .mcpb file ready for validation and publishing.

If the pack step fails, the output tells you why. Missing manifest fields, unresolvable dependencies, and invalid mcpb.json structure are the common causes. Fix the reported issue and run mcpb pack again.

Phase 3: Validate

Before publishing, validate the bundle against registry requirements:

mpak validate

Validation checks everything the registry will check on submission, catching issues before you publish rather than after.

Manifest completeness. Are all required fields present? Is the version valid semver? Is the name available in the registry?

Runtime start. The validator starts your server and checks that it responds to the MCP initialize handshake. A server that doesn’t start or doesn’t respond to initialization fails validation. This catches misconfigured start commands, missing entry points, and dependency errors.

Tool listing. After initialization, the validator requests the server’s tool list. The server must expose at least one tool with a valid schema. Servers with no tools, or tools with malformed parameter schemas, fail this check.

The stdout rule. This catches the most common publishing failure. Your server’s stdout must be clean JSON-RPC only. Any log messages, startup banners, debug prints, or library output on stdout corrupts the MCP protocol stream. The validator monitors stdout during startup and tool execution. If anything non-JSON-RPC appears, validation fails.

The fix is always the same: route all logging to stderr. Configure your logging framework’s handler to write to sys.stderr (Python) or process.stderr (Node). Remove print statements. Check that no dependency writes to stdout during import or initialization. Some libraries emit banners or warnings on first import; suppress them or redirect them.

Permission consistency. The validator compares your declared permissions against what the server actually does during the test run. If the server makes a network request to an endpoint not listed in the permissions block, the validator flags it.

When validation passes, your bundle is ready to publish.

Phase 4: Publish

mpak publish

On first publish, the CLI authenticates you through GitHub OAuth and links your GitHub identity to your mpak publisher account.

The publish command uploads the bundle to the mpak registry. On receipt, the registry:

  1. Validates the manifest format. A server-side check that mirrors the local validation. If you passed mpak validate, this step passes.
  2. Assigns the package listing. Your server gets a page at mpak.dev/packages/your-server-name with the metadata, description, and installation instructions.
  3. Queues MTF scanning. The automated security pipeline evaluates your server across all five trust dimensions: permission declarations, dependency audit, code analysis, runtime behavior, and author verification.
  4. Publishes the trust score. Scanning typically completes in under five minutes. The results appear on your package page, each dimension scored individually, overall trust level visible to anyone evaluating your server.

There is no manual review gate. Publishing is immediate. The MTF scores are public. Low-trust packages are transparent, not blocked. This design is deliberate: the community benefits from transparency, and developers can improve their scores iteratively rather than waiting for approval.

Common Pitfalls

Developers who publish multiple servers converge on a checklist of things that trip up first-time publishers. Here’s the list.

Stdout pollution. Already covered, but it’s the number one issue. Log to stderr. Print to stderr. If you use Python’s logging module, configure a StreamHandler(sys.stderr). If you use Node, write logs to process.stderr.write() or use a logging library configured for stderr output.

Missing dependencies. Your server works locally because the dependency is installed in your global environment. The bundle’s vendored deps/ doesn’t include it because it’s not in your requirements.txt or package.json. The server fails on another machine. Fix: ensure your dependency manifest includes every direct dependency, then re-pack.

Incorrect start command. python server.py works in your development directory but fails when the bundle installs to a different path. python -m package_name.server works regardless of the working directory because it resolves the package through Python’s module system. Use module execution for Python servers.

Broad permissions. Declaring network: ["*"] because you didn’t want to list specific endpoints. The MTF scanner will give you a low permissions score. Take the time to list each endpoint your server connects to. It’s usually one or two.

Undeclared environment variables. Your server reads DATABASE_URL but you didn’t declare it in mcpb.json. The user installs your server, runs it, and gets a cryptic error because the variable isn’t set. Declare every variable. Include descriptions. Mark required variables as required.

Stale vendored dependencies. You packed the bundle with dependencies from three months ago. A CVE was published last week for one of them. Your MTF dependency score reflects the vulnerability. Fix: re-vendor dependencies before publishing, especially for version updates.

Post-Publish

Publishing is not a one-time event. Your server is now part of the ecosystem. Here’s what ongoing maintenance looks like.

Version updates. When you fix bugs or add tools, bump the version in manifest.json, re-pack, and publish. Each version goes through the full MTF pipeline. Users see the version history and can pin specific versions.

Responding to MTF findings. If your initial trust score is lower than expected, read the dimension breakdown on your package page. Each dimension’s score includes the specific findings that affected it. Address the findings (narrow permissions, patch vulnerable dependencies, add missing declarations), then publish a new version.

Dependency maintenance. Periodically update your vendored dependencies and re-publish. The MTF maintenance dimension tracks whether your server’s dependency tree stays current. A server that was clean at initial publish but accumulates unpatched CVEs over time will see its trust score degrade.

Community feedback. Users will file issues, request features, and report bugs. Responsive maintenance (acknowledged issues, timely patches, clear changelogs) contributes to your trust profile and install count. The mpak ecosystem rewards servers that are actively maintained.

Enterprise and Private Registries

mpak is a public registry. Everything published to mpak.dev is discoverable by everyone. For organizations building internal MCP servers that connect to proprietary systems, two paths exist.

MCPB bundles without publishing. The bundle format works independently of the registry. Pack your server into a MCPB bundle, distribute it through your internal artifact repository (Artifactory, S3, internal Git), and install it with mpak install --from-file. Your team gets the packaging benefits (vendored dependencies, declared configuration, standardized runtime) without publishing to the public registry.

Private mpak instances. Organizations can run their own mpak registry for internal distribution. Same format, same CLI, same MTF scanning, pointed at your private infrastructure instead of mpak.dev. NimbleBrain helps enterprise clients set up private registries as part of Business-as-Code engagements, ensuring internal MCP servers carry the same trust evaluation as public ones.

From Server to Ecosystem

Publishing to mpak is the step that turns your MCP server from a local tool into ecosystem infrastructure. The server becomes discoverable, searchable by name, keywords, and capability. It becomes installable: one command, no dependency debugging. It becomes trusted, with MTF evaluation giving users a structured basis for deployment decisions.

Every MCP server NimbleBrain builds on client engagements ships as a MCPB bundle. It’s part of the delivery standard. When a client hits Escape Velocity, the point where they operate independently, their servers are packaged, documented, and portable. Not scripts that only we can run. Not integrations that only we can maintain. Standard packages that any engineer can install, understand, and extend.

That’s the point of mpak and the MCPB format. Distribution infrastructure that makes MCP servers a first-class artifact, as discoverable, installable, and trustworthy as any npm package or Docker image. The registry is at mpak.dev. The source is on GitHub. The trust framework is at mpaktrust.org. Publish your server and contribute to the ecosystem.

For the bundle format specification, see The MCPB Bundle Format. For the trust framework your server is evaluated against, see MCP Trust Framework In Detail.

Frequently Asked Questions

What are the requirements for publishing to mpak?

A valid MCPB bundle with manifest.json (name, version, description, author) and mcpb.json (runtime configuration). The server must start cleanly, respond to MCP protocol initialization, and declare its tools. A GitHub account for author verification.

How long does the trust evaluation take?

Automatic scanning runs on publish and typically completes in under 5 minutes. The results are immediately visible on the package page. There's no manual review gate, but the MTF scores are public, so low-trust packages are transparent.

Can I publish private MCP servers?

mpak is a public registry. For private servers, organizations can run their own mpak instance or use MCPB bundles directly without publishing. NimbleBrain helps enterprise clients set up private registries for internal MCP servers.

Mat GoldsboroughMat Goldsborough·Founder & CEO, NimbleBrain

Ready to put AI agents
to work?

Or email directly: hello@nimblebrain.ai