Introduction
An MCP server that nobody can find is an MCP server that nobody uses. Publishing your server to registries, following discovery conventions, and maintaining version compatibility are essential for ecosystem participation. This lesson covers npm publishing with the MCP scope, server discovery mechanisms, configuration schemas, and the versioning strategies that keep the ecosystem healthy.
Key Concepts
- npm Publishing: MCP servers are distributed as npm packages, typically under the
@modelcontextprotocolscope for official servers. Community servers use their own scope or unscoped packages. The package must include a properbinfield pointing to the server entry point. - Server Discovery: Users find MCP servers through the official MCP servers repository on GitHub, npm search, community registries, and documentation. Your server's discoverability depends on clear naming, accurate descriptions, and proper npm metadata.
- Configuration Schemas: Well-designed servers accept configuration through environment variables and a documented schema. Users need to know what configuration is required (API keys, database URLs) and what is optional (timeout values, cache sizes).
- Version Compatibility: MCP servers should follow semantic versioning. The MCP protocol version your server supports must be documented. Breaking changes to tool signatures require a major version bump.
- README Conventions: MCP server READMEs follow a consistent structure: description, installation, configuration, available tools (with input/output schemas), and usage examples with Claude Desktop configuration.
Real World Context
You have built an MCP server that wraps your company's internal APIs. Other teams want to use it with Claude Desktop and Cursor. You publish it to your organization's private npm registry with proper configuration documentation. Within a week, three teams have integrated it into their AI workflows. Without publishing and discovery, each team would have built their own integration — exactly the N-times-M problem MCP was designed to solve.
Deep Dive
Publishing to npm
Your package.json must include the right fields for MCP server distribution:
json{ "name": "@myorg/mcp-server-analytics", "version": "1.2.0", "description": "MCP server for analytics queries and dashboards", "bin": { "mcp-server-analytics": "./dist/index.js" }, "files": ["dist"], "keywords": ["mcp", "mcp-server", "analytics", "model-context-protocol"], "engines": { "node": ">=18.0.0" }, "dependencies": { "@modelcontextprotocol/sdk": "^2.0.0", "zod": "^3.23.0" } }
The bin field is critical — it defines the executable name that users reference in their MCP host configuration. The files field ensures only compiled output is published, not source code. Keywords including "mcp" and "mcp-server" make your package discoverable via npm search.
Server Entry Point Conventions
The entry point file must include a shebang line for direct execution:
typescript#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new McpServer({ name: "analytics-server", version: "1.2.0" }); // ... register tools, resources, prompts ... const transport = new StdioServerTransport(); await server.connect(transport);
The shebang (#!/usr/bin/env node) tells the operating system to run the file with Node.js. This is necessary for the npx invocation pattern used by Claude Desktop.
Configuration Documentation
Document required and optional configuration clearly:
textConfiguration ───────────────────────────────────────────────────────── Environment Variable Required Description ───────────────────────────────────────────────────────── ANALYTICS_API_KEY Yes API key for analytics service ANALYTICS_BASE_URL No API base URL (default: https://api.analytics.io) ANALYTICS_TIMEOUT_MS No Request timeout in ms (default: 30000) ANALYTICS_CACHE_TTL No Cache TTL in seconds (default: 300)
Users configure these in their MCP host config:
json{ "mcpServers": { "analytics": { "command": "npx", "args": ["-y", "@myorg/mcp-server-analytics"], "env": { "ANALYTICS_API_KEY": "your-key-here" } } } }
Version Compatibility Matrix
Document which MCP protocol versions your server supports:
textServer Version MCP Protocol Node.js SDK Version ──────────────── ────────────── ───────── ─────────── 1.0.x 2024-11-05 >= 18 SDK 1.x 1.1.x 2024-11-05 >= 18 SDK 1.x 2.0.x 2025-11-25 >= 20 SDK 2.x
This helps users know whether your server is compatible with their host's MCP protocol version.
Common Pitfalls
- Missing bin field — Without a
binfield inpackage.json,npxcannot find your server's entry point. Users get "command not found" errors that are difficult to debug. - Publishing source instead of compiled output — Use the
filesfield to include only thedistdirectory. Publishing TypeScript source requires users to havets-nodeor a build step, which adds friction. - Undocumented required configuration — If your server needs an API key but does not document it, users get cryptic runtime errors. Validate required configuration at startup and emit clear error messages.
Best Practices
- Validate configuration at startup — Check for required environment variables before connecting the transport. If a required variable is missing, print a clear error message to stderr and exit with a non-zero code.
- Follow the naming convention — Name your package
mcp-server-{domain}(e.g.,mcp-server-analytics,mcp-server-slack). This makes it immediately clear that your package is an MCP server for a specific domain. - Include Claude Desktop configuration examples — Users want to copy-paste working configuration. Include exact
claude_desktop_config.jsonsnippets in your README.
Summary
- Publish MCP servers as npm packages with a
binfield pointing to the server entry point. - Include a shebang line (
#!/usr/bin/env node) in the entry point for direct execution. - Document all configuration (environment variables) with clear required/optional indicators.
- Follow the
mcp-server-{domain}naming convention for discoverability. - Maintain a version compatibility matrix documenting supported MCP protocol versions and Node.js requirements.
Code Examples
{
"name": "@myorg/mcp-server-analytics",
"version": "1.2.0",
"description": "MCP server for analytics queries",
"bin": {
"mcp-server-analytics": "./dist/index.js"
},
"files": ["dist"],
"keywords": ["mcp", "mcp-server", "analytics"],
"engines": { "node": ">=18.0.0" },
"dependencies": {
"@modelcontextprotocol/sdk": "^2.0.0",
"zod": "^3.23.0"
}
}