modelcontextprotocol/servers · critical

Could not locate package.json for server version

Error message

Could not locate package.json for server version

What it means

resolvePackageVersion() walks candidate package.json locations relative to the compiled module (moduleDir and its parent) and throws when none can be read or none contains a version field. Because SERVER_VERSION is computed at module load time, this error crashes the server at startup whenever the package layout does not include a package.json next to version.ts/dist.

Source

Thrown at src/memory/version.ts:24

  const require = createRequire(import.meta.url);
  const moduleDir = path.dirname(fileURLToPath(import.meta.url));
  const candidates = [
    path.join(moduleDir, 'package.json'),
    path.join(moduleDir, '..', 'package.json'),
  ];

  for (const candidate of candidates) {
    try {
      const pkg = require(candidate) as { version?: string };
      if (pkg.version) {
        return pkg.version;
      }
    } catch {
      // Try the next candidate when running from dist/ or source.
    }
  }

  throw new Error('Could not locate package.json for server version');
}

export const SERVER_VERSION = resolvePackageVersion();

View on GitHub (pinned to d73f99efbf)

Solutions

  1. Ensure package.json is shipped/copied alongside the built output (e.g. COPY src/memory/package.json next to dist/ in Docker).
  2. If bundling, mark the module external or emit package.json into the bundle output directory.
  3. Build with the package's own build script (npm run build) instead of ad-hoc tsc invocations that change the output layout.
  4. As a workaround, set the version through the environment or patch resolvePackageVersion to fall back to a constant when the file is absent.

Example fix

// before (Dockerfile)
COPY dist/ ./dist/
CMD ["node", "dist/index.js"]
// after
COPY dist/ ./dist/
COPY package.json ./dist/../package.json
CMD ["node", "dist/index.js"]
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";
const dir = path.dirname(fileURLToPath(import.meta.url));
if (!existsSync(path.join(dir, "package.json")) && !existsSync(path.join(dir, "..", "package.json"))) {
  console.warn("package.json not found next to build output; SERVER_VERSION will throw");
}

Try / catch

// The throw happens at import time (SERVER_VERSION), so wrap the dynamic import instead:
let serverVersion = "unknown";
try {
  ({ SERVER_VERSION } = await import("./version.js"));
  serverVersion = SERVER_VERSION;
} catch (e) {
  console.error("Version resolution failed; check package.json is shipped with dist/", e);
}

Prevention

When it happens

Trigger: Running the built dist/index.js in isolation (copied out of node_modules or a container) without package.json beside it; bundling with a packer (esbuild/webpack/ncc) that does not emit package.json into the output; running from a source checkout after build layout changes so neither dist/../package.json nor dist/package.json resolves.

Common situations: Docker images that COPY only dist/ and not package.json; npm pack/tgz installs pruned unexpectedly; monorepo symlinked builds where the candidate paths point at the wrong directory; bundled single-file deployments.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of modelcontextprotocol/servers@d73f99efbf (2026-09-07). Data as JSON: /api/errors/6b9ea2886b3faf69. Report an issue: GitHub.