Skip to content

@vybestack/llxprt-code-mcp value-imports core at runtime but declares it only as a devDependency #3305

Description

@acoliver

Problem

@vybestack/llxprt-code-mcp is a published package (version 0.11.0, no private flag, main: dist/mcp/index.js). Its package.json lists @vybestack/llxprt-code-core in devDependencies only:

"dependencies": {
  "@vybestack/llxprt-code-storage": "file:../storage",
  "@modelcontextprotocol/sdk": "^1.25.2",
  "@vybestack/llxprt-code-settings": "file:../settings",
  "@vybestack/llxprt-code-tools": "file:../tools",
  "google-auth-library": "^9.11.0",
  "shell-quote": "^1.8.4",
  "zod": "^3.25.76"
},
"devDependencies": {
  "@vybestack/llxprt-code-core": "file:../core",
  ...
}

But 19 production source files perform value imports from core, not type-only imports. A sample with line numbers:

File Imported value
src/auth/oauth-utils.ts:8-9 getErrorMessage, DebugLogger
src/auth/oauth-provider.ts:12,17,19 openBrowserSecurely, getErrorMessage, DebugLogger
src/auth/file-token-store.ts:12,18 getErrorMessage, debugLogger
src/auth/token-storage/keychain-token-storage.ts:20,22 coreEvents, debugLogger
src/auth/google-auth-provider.ts:17 debugLogger
src/auth/sa-impersonation-provider.ts:17 debugLogger
src/auth/oauth-provider-utils.ts:7 DebugLogger
src/auth/auth-types.ts:7 export { AuthProviderType } (value re-export)
src/client/mcp-client-manager.ts:27 getErrorMessage

Full list of affected production files: auth/oauth-provider-dependencies.ts, auth/oauth-utils.ts, auth/oauth-provider.ts, auth/google-auth-provider.ts, auth/file-token-store.ts, auth/token-storage/keychain-token-storage.ts, auth/sa-impersonation-provider.ts, auth/oauth-provider-utils.ts, auth/auth-types.ts, client/mcp-client-manager.ts, client/mcp-tool.ts, client/mcp-oauth-helpers.ts, client/mcp-client-manager-helpers.ts, client/mcp-client.ts, client/mcp-schema-validator.ts, client/mcp-transport.ts, client/mcp-discovery.ts, client/mcp-discovery-helpers.ts, client/mcp-connection.ts.

Impact

1. The published package is broken for external consumers. npm i @vybestack/llxprt-code-mcp installs no core, and the shipped dist/mcp/index.js resolves @vybestack/llxprt-code-core/utils/errors.js and friends at runtime. This does not reproduce in-repo because workspace resolution and the tsconfig path wildcards ("@vybestack/llxprt-code-core/*" → ../core/src/*) satisfy the import regardless of declaration.

2. It hides a real coremcp runtime cycle. core declares mcp as a normal dependency and value-imports it:

  • core/src/config/config.ts:108import { McpClientManager }
  • core/src/code_assist/oauth-credential-storage.ts:8,13import { KeychainTokenStorage }
  • core/src/config/lspIntegration.ts:22import { DiscoveredMCPTool }
  • core/src/index.ts:511,523 — re-exports

Because one direction is declared as a devDependency, the cycle does not appear in the dependency graph. Any audit that reads package.json files concludes the workspace is acyclic when it is not.

Suggested resolution

Decide which is true and make the declaration match:

  • If mcp legitimately needs core at runtime, move core to dependencies (or peerDependencies) and accept/declare the cycle explicitly.
  • If the cycle is unwanted, move the small set of shared utilities (getErrorMessage, DebugLogger/debugLogger, coreEvents, openBrowserSecurely, AuthProviderType, MCPServerConfig) into a lower-level package that both depend on. Several are already leaf-ish concerns.
  • Convert genuinely type-only imports to import type so they do not contribute to the runtime graph.

Acceptance criteria

  • packages/mcp/package.json declares every package it imports at runtime.
  • A packaging check verifies that no production source file imports a package absent from dependencies/peerDependencies, for every published workspace package rather than just mcp.
  • The coremcp relationship is either removed or documented as a deliberate, declared cycle.
  • Installing the published @vybestack/llxprt-code-mcp tarball standalone and importing its entrypoint succeeds.

Notes

Found while auditing package boundaries for multi-client support. Unrelated to the profile epic (#2635); filing separately so it is not absorbed into that work.

Metadata

Metadata

Assignees

Labels

Code Quality / ModularizationIssues to do with the quality of llxprt code and its maintainability.mcpIssues related to the Model Context Protocol (MCP) servers and clientsstartup/install/bundleanything to do with our scripts to run llxprt, the bundle, the packaging

Type

Projects

Status
In Progress

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions