Skip to main content
Glama

compare_packages

Compare two npm packages side-by-side to analyze differences in features, dependencies, and statistics for informed package selection decisions.

Instructions

Compare two packages side-by-side

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
packageName1Yes
packageName2Yes

Implementation Reference

  • The handler function for the 'compare_packages' tool. It fetches full package information and last-month download stats for two packages from the npm registry, extracts latest versions, constructs a comparison output with details like version, description, downloads, maintainers, and keywords, formats a textual comparison, and returns both structured data and formatted text, handling errors appropriately.
    async ({ packageName1, packageName2 }) => { try { const [pkg1Full, pkg2Full, pkg1Stats, pkg2Stats] = await Promise.all([ fetchFullPackageInfo(packageName1), fetchFullPackageInfo(packageName2), fetch( `https://api.npmjs.org/downloads/point/last-month/${encodeURIComponent( packageName1 )}` ).then((r) => r.json()), fetch( `https://api.npmjs.org/downloads/point/last-month/${encodeURIComponent( packageName2 )}` ).then((r) => r.json()), ]); const pkg1Latest = pkg1Full.versions[pkg1Full["dist-tags"].latest]; const pkg2Latest = pkg2Full.versions[pkg2Full["dist-tags"].latest]; const output = { packages: [ { name: pkg1Latest.name, version: pkg1Latest.version, description: pkg1Latest.description, downloads: pkg1Stats.downloads || 0, maintainers: pkg1Latest.maintainers?.map((m: any) => m.name) || [], keywords: pkg1Latest.keywords, }, { name: pkg2Latest.name, version: pkg2Latest.version, description: pkg2Latest.description, downloads: pkg2Stats.downloads || 0, maintainers: pkg2Latest.maintainers?.map((m: any) => m.name) || [], keywords: pkg2Latest.keywords, }, ], }; const formattedText = `Package Comparison:\n\n${pkg1Latest.name} vs ${ pkg2Latest.name }\n\n${pkg1Latest.name}:\n Version: ${ pkg1Latest.version }\n Description: ${ pkg1Latest.description || "N/A" }\n Downloads (last month): ${( pkg1Stats.downloads || 0 ).toLocaleString()}\n Maintainers: ${ output.packages[0].maintainers.join(", ") || "N/A" }\n Keywords: ${pkg1Latest.keywords?.join(", ") || "None"}\n\n${ pkg2Latest.name }:\n Version: ${pkg2Latest.version}\n Description: ${ pkg2Latest.description || "N/A" }\n Downloads (last month): ${( pkg2Stats.downloads || 0 ).toLocaleString()}\n Maintainers: ${ output.packages[1].maintainers.join(", ") || "N/A" }\n Keywords: ${pkg2Latest.keywords?.join(", ") || "None"}`; return { content: [ { type: "text", text: formattedText, }, ], structuredContent: output, }; } catch (error) { return { content: [ { type: "text", text: `Error comparing packages: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], isError: true, }; } }
  • Input and output schemas defining the parameters (packageName1, packageName2 as strings) and the structured output (array of package objects with name, version, description, downloads, maintainers, keywords).
    { title: "Compare Packages", description: "Compare two packages side-by-side", inputSchema: { packageName1: z.string(), packageName2: z.string(), }, outputSchema: { packages: z.array( z.object({ name: z.string(), version: z.string(), description: z.string().optional(), downloads: z.number(), maintainers: z.array(z.string()), keywords: z.array(z.string()).optional(), }) ), }, },
  • src/index.ts:727-833 (registration)
    Registration of the 'compare_packages' tool using server.registerTool, including the tool name, schema, and handler function.
    server.registerTool( "compare_packages", { title: "Compare Packages", description: "Compare two packages side-by-side", inputSchema: { packageName1: z.string(), packageName2: z.string(), }, outputSchema: { packages: z.array( z.object({ name: z.string(), version: z.string(), description: z.string().optional(), downloads: z.number(), maintainers: z.array(z.string()), keywords: z.array(z.string()).optional(), }) ), }, }, async ({ packageName1, packageName2 }) => { try { const [pkg1Full, pkg2Full, pkg1Stats, pkg2Stats] = await Promise.all([ fetchFullPackageInfo(packageName1), fetchFullPackageInfo(packageName2), fetch( `https://api.npmjs.org/downloads/point/last-month/${encodeURIComponent( packageName1 )}` ).then((r) => r.json()), fetch( `https://api.npmjs.org/downloads/point/last-month/${encodeURIComponent( packageName2 )}` ).then((r) => r.json()), ]); const pkg1Latest = pkg1Full.versions[pkg1Full["dist-tags"].latest]; const pkg2Latest = pkg2Full.versions[pkg2Full["dist-tags"].latest]; const output = { packages: [ { name: pkg1Latest.name, version: pkg1Latest.version, description: pkg1Latest.description, downloads: pkg1Stats.downloads || 0, maintainers: pkg1Latest.maintainers?.map((m: any) => m.name) || [], keywords: pkg1Latest.keywords, }, { name: pkg2Latest.name, version: pkg2Latest.version, description: pkg2Latest.description, downloads: pkg2Stats.downloads || 0, maintainers: pkg2Latest.maintainers?.map((m: any) => m.name) || [], keywords: pkg2Latest.keywords, }, ], }; const formattedText = `Package Comparison:\n\n${pkg1Latest.name} vs ${ pkg2Latest.name }\n\n${pkg1Latest.name}:\n Version: ${ pkg1Latest.version }\n Description: ${ pkg1Latest.description || "N/A" }\n Downloads (last month): ${( pkg1Stats.downloads || 0 ).toLocaleString()}\n Maintainers: ${ output.packages[0].maintainers.join(", ") || "N/A" }\n Keywords: ${pkg1Latest.keywords?.join(", ") || "None"}\n\n${ pkg2Latest.name }:\n Version: ${pkg2Latest.version}\n Description: ${ pkg2Latest.description || "N/A" }\n Downloads (last month): ${( pkg2Stats.downloads || 0 ).toLocaleString()}\n Maintainers: ${ output.packages[1].maintainers.join(", ") || "N/A" }\n Keywords: ${pkg2Latest.keywords?.join(", ") || "None"}`; return { content: [ { type: "text", text: formattedText, }, ], structuredContent: output, }; } catch (error) { return { content: [ { type: "text", text: `Error comparing packages: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], isError: true, }; } } );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JuanSebastianGB/npm-context-agent-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server