A server that only runs from a local dist/ path is fine for learning. Shipping means someone else can install it with npx (or pin a version) and point Cursor at it. This page is that distribution path — npm package plus the MCP Registry — not public HTTP hosting (that is Part 8).

Before you start

If Tool, stdio, or registerTool are unfamiliar, read Part 1 and Part 3 first — this post will not re-teach those basics.

Gate: apply the hardening checklist (or keep tools read-only) before you publish anything that others will run on their machines.

Bootstrap:

git clone https://github.com/SRVivek1/geekmonks-mcp-bookmarks.git
cd geekmonks-mcp-bookmarks
git checkout part-6   # or part-4 if you skipped hardening
npm install
npm run build

Companion checkpoint after packaging: tag part-7.

What “published” means here

LayerWhere it livesJob
npm packageregistry.npmjs.orgThe installable bits (bin → your stdio server)
MCP Registryregistry.modelcontextprotocol.ioMetadata so people can find the server (not a second copy of the tarball)

The Registry is in preview and may change; treat the official quickstart as the source of truth when commands drift.

Package layout for a stdio CLI

Minimum shape (already close to the bookmarks lab):

package.json      # name, version, bin, files, mcpName
dist/index.js     # built entry (shebang + serveStdio)
README.md         # install + Cursor snippet
server.json       # MCP Registry metadata (from mcp-publisher init)

package.json fields that matter

{
  "name": "@your-npm-scope/geekmonks-mcp-bookmarks",
  "version": "0.7.0",
  "description": "Local bookmarks MCP server (stdio)",
  "type": "module",
  "bin": {
    "geekmonks-mcp-bookmarks": "./dist/index.js"
  },
  "files": [
    "dist",
    "README.md"
  ],
  "engines": {
    "node": ">=20"
  },
  "mcpName": "io.github.youruser/geekmonks-mcp-bookmarks"
}
FieldWhy
binLets users run the server via npx / global install
filesKeeps the published tarball small (no src/, no tests)
mcpNameMust match the Registry server.json name for ownership checks
enginesHonest Node floor (20+)

Ensure dist/index.js starts with #!/usr/bin/env node and that npm run build is part of your release habit (prepublishOnly is a common hook).

README install snippet (complete this post’s promise)

npx -y @your-npm-scope/geekmonks-mcp-bookmarks

Cursor mcp.json sketch:

{
  "mcpServers": {
    "bookmarks": {
      "command": "npx",
      "args": ["-y", "@your-npm-scope/geekmonks-mcp-bookmarks"]
    }
  }
}

Other hosts (Claude Desktop, etc.) use the same server binary with a different config file path — one callout, not a second tutorial.

Publish to npm

  1. Log in: npm login
  2. Build: npm run build
  3. Dry-run: npm publish --access public --dry-run
  4. Publish: npm publish --access public

You should see: the package page on npm; npx -y @your-npm-scope/geekmonks-mcp-bookmarks starts (and waits on stdio — that is normal).

Register with the MCP Registry

Install the CLI (quickstart):

brew install mcp-publisher   # or download the release binary
mcp-publisher --help

Then:

mcp-publisher init
mcp-publisher login github
# edit server.json so name === package.json mcpName, version aligns
mcp-publisher publish

Typical server.json ideas (exact schema: follow init output / package types):

{
  "name": "io.github.youruser/geekmonks-mcp-bookmarks",
  "description": "Local bookmarks MCP server over stdio",
  "version": "0.7.0",
  "packages": [
    {
      "registryType": "npm",
      "identifier": "@your-npm-scope/geekmonks-mcp-bookmarks",
      "version": "0.7.0",
      "transport": {
        "type": "stdio"
      }
    }
  ]
}

You should see: a Registry entry that points at your npm package; ownership verification passes because mcpName matches.

Distribution vs hosting

GoalUse
Others run locally via npxThis post (npm + Registry)
Clients connect to your HTTPS URLPart 8

Do not conflate “listed in the Registry” with “deployed on the internet.”

Wrap-up

You packaged a stdio MCP server for npm, proved npx, and registered metadata with mcp-publisher. Series hub: MCP Without the Hype. Safety gate: Part 6. Code checkpoint: tag part-7 on geekmonks-mcp-bookmarks.

Optional next Put the same tools on Streamable HTTP behind a live URL. Host an MCP Server for Public Use