Skip to main content
Glama

search_packages

Search npm registry for packages by keyword to find relevant dependencies and tools for your project.

Instructions

Search npm registry for packages by keyword

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
limitNo

Implementation Reference

  • The handler function for the 'search_packages' tool. It takes a query and optional limit, fetches search results from the npm registry API, validates the response using PackageSearchSchema, formats a text summary of the results, and returns both text content and structured output.
    async ({ query, limit = 20 }) => { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( `https://registry.npmjs.org/-/v1/search?text=${encodedQuery}&size=${limit}` ); if (!response.ok) { throw new Error(`Failed to search packages: ${response.statusText}`); } const rawData = await response.json(); const parseResult = PackageSearchSchema.safeParse(rawData); if (!parseResult.success) { throw new Error( `Invalid search results structure: ${parseResult.error.message}` ); } const data = parseResult.data; const packages = data.objects.map((obj) => obj.package); const formattedResults = packages .map( (pkg) => `Name: ${pkg.name}\nVersion: ${pkg.version}\nDescription: ${ pkg.description || "N/A" }\n${pkg.author ? `Author: ${pkg.author.name || "N/A"}\n` : ""}${ pkg.links?.npm ? `NPM: ${pkg.links.npm}\n` : "" }---` ) .join("\n\n"); const output = { total: data.total, results: packages.map((pkg) => ({ name: pkg.name, version: pkg.version, description: pkg.description, author: pkg.author?.name, npmUrl: pkg.links?.npm, })), }; return { content: [ { type: "text", text: `Found ${data.total} packages (showing ${packages.length}):\n\n${formattedResults}`, }, ], structuredContent: output, }; } catch (error) { return { content: [ { type: "text", text: `Error searching packages: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], isError: true, }; } }
  • Zod schema for validating the npm package search response from the registry API, used in the search_packages handler.
    const PackageSearchSchema = z.object({ objects: z.array( z.object({ package: z.object({ name: z.string(), version: z.string(), description: z.string().optional(), keywords: z.array(z.string()).optional(), author: z .object({ name: z.string().optional(), email: z.string().optional(), }) .optional(), links: z .object({ npm: z.string().optional(), homepage: z.string().optional(), repository: z.string().optional(), }) .optional(), }), }) ), total: z.number(), });
  • src/index.ts:267-357 (registration)
    Registers the 'search_packages' tool with McpServer, defining title, description, input and output schemas, and references the handler function.
    server.registerTool( "search_packages", { title: "Search npm Packages", description: "Search npm registry for packages by keyword", inputSchema: { query: z.string(), limit: z.number().optional(), }, outputSchema: { total: z.number(), results: z.array( z.object({ name: z.string(), version: z.string(), description: z.string().optional(), author: z.string().optional(), npmUrl: z.string().optional(), }) ), }, }, async ({ query, limit = 20 }) => { try { const encodedQuery = encodeURIComponent(query); const response = await fetch( `https://registry.npmjs.org/-/v1/search?text=${encodedQuery}&size=${limit}` ); if (!response.ok) { throw new Error(`Failed to search packages: ${response.statusText}`); } const rawData = await response.json(); const parseResult = PackageSearchSchema.safeParse(rawData); if (!parseResult.success) { throw new Error( `Invalid search results structure: ${parseResult.error.message}` ); } const data = parseResult.data; const packages = data.objects.map((obj) => obj.package); const formattedResults = packages .map( (pkg) => `Name: ${pkg.name}\nVersion: ${pkg.version}\nDescription: ${ pkg.description || "N/A" }\n${pkg.author ? `Author: ${pkg.author.name || "N/A"}\n` : ""}${ pkg.links?.npm ? `NPM: ${pkg.links.npm}\n` : "" }---` ) .join("\n\n"); const output = { total: data.total, results: packages.map((pkg) => ({ name: pkg.name, version: pkg.version, description: pkg.description, author: pkg.author?.name, npmUrl: pkg.links?.npm, })), }; return { content: [ { type: "text", text: `Found ${data.total} packages (showing ${packages.length}):\n\n${formattedResults}`, }, ], structuredContent: output, }; } catch (error) { return { content: [ { type: "text", text: `Error searching packages: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], isError: true, }; } } );
  • Input and output schemas defined for the search_packages tool registration, specifying parameters like query and limit, and expected response structure.
    title: "Search npm Packages", description: "Search npm registry for packages by keyword", inputSchema: { query: z.string(), limit: z.number().optional(), }, outputSchema: { total: z.number(), results: z.array( z.object({ name: z.string(), version: z.string(), description: z.string().optional(), author: z.string().optional(), npmUrl: z.string().optional(), }) ), },

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