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