Skip to main content
Glama

packageSearch

Find NPM and Python packages with their repository URLs to locate code sources and research dependencies from imports or configuration files.

Instructions

Find NPM/Python packages & their repository URLs

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queriesYesResearch queries for packageSearch (1-3 queries per call for optimal resource management). Review schema before use for optimal results

Implementation Reference

  • Core execution logic for packageSearch tool: processes bulk queries, calls searchPackage API, handles errors, enriches results with repo info and deprecation status, generates contextual hints.
    async function searchPackages( queries: PackageSearchQuery[] ): Promise<CallToolResult> { return executeBulkOperation( queries, async (query: PackageSearchQuery, _index: number) => { try { const apiResult = await searchPackage(query); if (isPackageSearchError(apiResult)) { return createErrorResult(apiResult.error, query); } const packages = (apiResult.packages as PackageResult[]).map(pkg => { const repoUrl = getPackageRepo(pkg); const { owner, repo } = parseRepoInfo(repoUrl); if (owner && repo) { return { ...pkg, owner, repo }; } return pkg; }); const result = { packages, totalFound: apiResult.totalFound, }; const hasContent = result.packages.length > 0; let deprecationInfo: DeprecationInfo | null = null; if (hasContent && query.ecosystem === 'npm' && result.packages[0]) { deprecationInfo = await checkNpmDeprecation( getPackageName(result.packages[0]) ); } // Generate context-specific hints for package search const extraHints = hasContent ? generateSuccessHints(result, query.ecosystem, deprecationInfo) : generateEmptyHints(query); // Use unified pattern with extraHints for package-specific guidance return createSuccessResult( query, result, hasContent, TOOL_NAMES.PACKAGE_SEARCH, { extraHints } ); } catch (error) { return handleCatchError(error, query); } }, { toolName: TOOL_NAMES.PACKAGE_SEARCH, keysPriority: ['packages', 'totalFound', 'error'], } ); }
  • Registers the 'packageSearch' tool (TOOL_NAMES.PACKAGE_SEARCH) with MCP server, including input schema, description, annotations, and security-wrapped handler.
    export async function registerPackageSearchTool( server: McpServer, callback?: ToolInvocationCallback ): Promise<RegisteredTool | null> { const npmAvailable = await checkNpmAvailability(10000); if (!npmAvailable) { return null; } return server.registerTool( TOOL_NAMES.PACKAGE_SEARCH, { description: DESCRIPTIONS[TOOL_NAMES.PACKAGE_SEARCH], // Type assertion needed: Zod discriminatedUnion types don't fully align with MCP SDK's expected schema type inputSchema: PackageSearchBulkQuerySchema as Parameters< typeof server.registerTool >[1]['inputSchema'], annotations: { title: 'Package Search', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, }, withSecurityValidation( TOOL_NAMES.PACKAGE_SEARCH, async ( args: { queries: PackageSearchQuery[]; }, _authInfo, _sessionId ): Promise<CallToolResult> => { const queries = args.queries || []; await invokeCallbackSafely( callback, TOOL_NAMES.PACKAGE_SEARCH, queries ); return searchPackages(queries); } ) ); }
  • Zod input schema: discriminated union for npm/python package queries (name, searchLimit, ecosystem-specific options), plus bulk query schema used in registration.
    export const PackageSearchQuerySchema = z.discriminatedUnion('ecosystem', [ NpmPackageQuerySchema, PythonPackageQuerySchema, ]); export type NpmPackageQuery = z.infer<typeof NpmPackageQuerySchema>; export type PythonPackageQuery = z.infer<typeof PythonPackageQuerySchema>; export type PackageSearchQuery = NpmPackageQuery | PythonPackageQuery; export type PackageSearchBulkParams = { queries: PackageSearchQuery[]; }; export const PackageSearchBulkQuerySchema = createBulkQuerySchema( TOOL_NAMES.PACKAGE_SEARCH, PackageSearchQuerySchema );
  • ToolConfig entry that wires registerPackageSearchTool into the ALL_TOOLS array for automatic registration via toolsManager.
    export const PACKAGE_SEARCH: ToolConfig = { name: TOOL_NAMES.PACKAGE_SEARCH, description: getDescription(TOOL_NAMES.PACKAGE_SEARCH), isDefault: true, isLocal: false, type: 'search', fn: registerPackageSearchTool, };
  • Generic registration loop in registerTools() that invokes each tool's fn (including packageSearch via toolConfig), with filtering based on config.
    for (const tool of ALL_TOOLS) { // Step 1: Check if tool should be enabled if (!isToolEnabled(tool, localEnabled, filterConfig)) { continue; } // Step 2: Check if tool exists in metadata try { if (!isToolInMetadata(tool.name)) { await logSessionError( tool.name, TOOL_METADATA_ERRORS.INVALID_FORMAT.code ); continue; } } catch { await logSessionError( tool.name, TOOL_METADATA_ERRORS.INVALID_API_RESPONSE.code ); continue; } // Step 3: Register the tool try { const result = await tool.fn(server, callback); if (result !== null) { successCount++; } } catch { failedTools.push(tool.name); } }

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/bgauryy/octocode-mcp'

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