get_package_manager
Detect the package manager in a project directory to ensure correct dependency management commands are used.
Instructions
Detects and returns the current package manager information
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | Yes | Root directory to check for lock files | |
| defaultManager | No | Default package manager to use if detection fails (npm, yarn, pnpm) |
Implementation Reference
- src/tools/package_manager_tool.ts:54-98 (handler)The async handler function that executes the tool logic: logs args, checks for lockfiles, prepares options, calls detectPackageManager, and returns the package manager name and commands.handler: async (args: PackageManagerDetectionArgs) => { // Debug logging log("MCP Tool - get_package_manager called with args:", args); log("MCP Tool - Current working directory:", process.cwd()); // Check for lock files directly in the handler const lockFiles = { pnpm: "pnpm-lock.yaml", yarn: "yarn.lock", npm: "package-lock.json", }; // Log existence of each lock file Object.entries(lockFiles).forEach(([pm, file]) => { const lockPath = resolve(process.cwd(), file); log(`MCP Tool - ${pm} lock file (${file}) exists:`, existsSync(lockPath)); }); // Only include options that are actually provided const options: Record<string, any> = { cwd: args.cwd, // cwd is now required }; if (args.defaultManager) { options.defaultManager = args.defaultManager; } else { // Set npm as default if not specified options.defaultManager = "npm"; } log("MCP Tool - Calling detectPackageManager with options:", options); const pmInfo = detectPackageManager(options); log("MCP Tool - Detection result:", pmInfo); return { name: pmInfo.name, commands: { install: pmInfo.installCmd, add: pmInfo.addCmd, remove: pmInfo.removeCmd, run: pmInfo.runCmd, }, // cwd: options.cwd, }; },
- The inputSchema defining the tool's parameters: cwd (required) and optional defaultManager.inputSchema: { type: "object", properties: { cwd: { type: "string", description: "Root directory to check for lock files", }, defaultManager: { type: "string", description: "Default package manager to use if detection fails (npm, yarn, pnpm)", enum: ["npm", "yarn", "pnpm"], }, }, required: ["cwd"], },
- src/tools/index.ts:52-53 (registration)Registers the packageManagerTool in the central tools Map by name, making it available for the MCP server.// Register package manager tool tools.set(packageManagerTool.name, packageManagerTool);
- src/utils/package_manager.ts:87-117 (helper)Core helper function detectPackageManager that checks for lockfiles in priority order (pnpm, yarn, npm) and returns PackageManagerInfo with name and commands.export function detectPackageManager(options: PackageManagerOptions = {}): PackageManagerInfo { const { cwd = process.cwd(), defaultManager = "npm" } = options; // Determine priorities for checking lock files const packageManagers: PackageManager[] = ["pnpm", "yarn", "npm"]; // Detected package managers const detected: PackageManager[] = []; // Check for each lock file for (const pm of packageManagers) { const lockFile = LOCK_FILES[pm]; const lockFilePath = resolve(cwd, lockFile); console.log(`Checking for ${lockFile} at ${lockFilePath}`); if (existsSync(lockFilePath)) { detected.push(pm); // Found a lock file, no need to check others break; } } // Return the first detected package manager or default const packageManager = detected.length > 0 ? detected[0] : defaultManager; return { name: packageManager, ...PACKAGE_MANAGER_COMMANDS[packageManager], }; }
- src/utils/package_manager.ts:22-33 (schema)Type definition for the output structure returned by the tool.export interface PackageManagerInfo { /** The name of the detected package manager */ name: PackageManager; /** The command to use for installing packages */ installCmd: string; /** The command to use for adding a package */ addCmd: string; /** The command to use for removing a package */ removeCmd: string; /** The command to use for running scripts */ runCmd: string; }