Skip to main content
Glama

search_collection_enhanced

Search and filter DollhouseMCP collection content by type, category, or relevance with paginated results for precise discovery.

Instructions

Enhanced search for collection content with pagination, filtering, and sorting. Use this for advanced searches when users need specific content types or want to browse results in pages.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query for finding content. Examples: 'creative writer', 'explain like I'm five', 'coding assistant'.
elementTypeNoFilter by content type: personas, skills, agents, templates, tools, memories, prompts
categoryNoFilter by category: creative, professional, educational, personal, gaming
pageNoPage number for paginated results (default: 1)
pageSizeNoNumber of results per page (default: 25, max: 100)
sortByNoSort results by relevance, name, or date

Implementation Reference

  • Registration of the 'search_collection_enhanced' tool, including full input schema (with query, elementType, category, page, pageSize, sortBy) and thin handler that delegates to server.searchCollectionEnhanced
    {
      tool: {
        name: "search_collection_enhanced",
        description: "Enhanced search for collection content with pagination, filtering, and sorting. Use this for advanced searches when users need specific content types or want to browse results in pages.",
        inputSchema: {
          type: "object",
          properties: {
            query: {
              type: "string",
              description: "Search query for finding content. Examples: 'creative writer', 'explain like I'm five', 'coding assistant'.",
            },
            elementType: {
              type: "string",
              description: "Filter by content type: personas, skills, agents, templates, tools, memories, prompts",
              enum: ["personas", "skills", "agents", "templates", "tools", "memories", "prompts"]
            },
            category: {
              type: "string",
              description: "Filter by category: creative, professional, educational, personal, gaming",
              enum: ["creative", "professional", "educational", "personal", "gaming"]
            },
            page: {
              type: "number",
              description: "Page number for paginated results (default: 1)",
              minimum: 1
            },
            pageSize: {
              type: "number", 
              description: "Number of results per page (default: 25, max: 100)",
              minimum: 1,
              maximum: 100
            },
            sortBy: {
              type: "string",
              description: "Sort results by relevance, name, or date",
              enum: ["relevance", "name", "date"]
            }
          },
          required: ["query"],
        },
      },
      handler: (args: any) => server.searchCollectionEnhanced(args.query, {
        elementType: args.elementType,
        category: args.category,
        page: args.page,
        pageSize: args.pageSize,
        sortBy: args.sortBy
      })
    },
  • Interface definition for the server.searchCollectionEnhanced method called by the tool handler
    searchCollectionEnhanced(query: string, options?: any): Promise<any>;
  • Core implementation of enhanced collection search logic (searchCollectionWithOptions), supporting filtering, pagination, sorting, index-based search with fallback to GitHub API and cache
    async searchCollectionWithOptions(query: string, options: SearchOptions = {}): Promise<SearchResults> {
      const startTime = Date.now();
      logger.debug(`CollectionSearch.searchCollectionWithOptions called with query: "${query}"`, options);
      
      // Validate search query for security
      try {
        validateSearchQuery(query, 1000);
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        logger.error('Search query validation failed:', { query, error: errorMessage });
        ErrorHandler.logError('CollectionSearch.searchWithOptions.validateQuery', error, { query });
        return this.createEmptySearchResults(query, options);
      }
      
      try {
        // Try index-based search first
        const indexResults = await this.searchFromIndex(query, options);
        const searchTime = Date.now() - startTime;
        
        logger.debug(`Index search completed in ${searchTime}ms with ${indexResults.items.length} results`);
        return { ...indexResults, searchTime };
      } catch (error) {
        logger.debug('Index search failed, falling back to legacy search:', error);
        
        // Fallback to legacy search
        const legacyResults = await this.searchCollection(query);
        const searchTime = Date.now() - startTime;
        
        // Convert legacy results to new format
        return this.convertLegacyResults(legacyResults, query, options, searchTime);
      }
    }
  • Index-based search helper with filtering by elementType/category, relevance scoring, sorting, and pagination logic used by enhanced search
    private async searchFromIndex(query: string, options: SearchOptions): Promise<SearchResults> {
      const index = await this.indexCache.getIndex();
      const allEntries = this.flattenIndexEntries(index);
      
      // Filter by element type if specified
      let filteredEntries = allEntries;
      if (options.elementType) {
        filteredEntries = allEntries.filter(entry => entry.type === options.elementType);
      }
      
      // Filter by category if specified
      if (options.category) {
        filteredEntries = filteredEntries.filter(entry => entry.category === options.category);
      }
      
      // Search matching
      const matchedEntries = this.performIndexSearch(query, filteredEntries);
      
      // Sort results
      const sortedEntries = this.sortSearchResults(matchedEntries, options.sortBy || 'relevance', query);
      
      // Apply pagination
      const page = options.page || 1;
      const pageSize = options.pageSize || 25;
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const paginatedEntries = sortedEntries.slice(startIndex, endIndex);
      
      return {
        items: paginatedEntries,
        total: sortedEntries.length,
        page,
        pageSize,
        hasMore: endIndex < sortedEntries.length,
        query,
        searchTime: 0 // Will be set by caller
      };
    }
  • Legacy/basic searchCollection fallback used by enhanced search when index unavailable; searches GitHub API or cache/seed data
    async searchCollection(query: string): Promise<any[]> {
      logger.debug(`CollectionSearch.searchCollection called with query: "${query}"`);
      
      // Validate search query for security
      try {
        validateSearchQuery(query, 1000);
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        logger.error('Search query validation failed:', { query, error: errorMessage });
        ErrorHandler.logError('CollectionSearch.search.validateQuery', error, { query });
        return [];
      }
      
      try {
        // First, try GitHub API search if authenticated
        const searchUrl = `${this.searchBaseUrl}?q=${encodeURIComponent(query)}+repo:DollhouseMCP/collection+path:library+extension:md`;
        logger.debug(`Attempting GitHub API search with URL: ${searchUrl}`);
        const data = await this.githubClient.fetchFromGitHub(searchUrl, false); // Don't require auth for search
        
        if (data.items && Array.isArray(data.items)) {
          logger.debug(`Found ${data.items.length} items via GitHub API search`);
          
          // Update cache with fresh data from API
          await this.updateCacheFromGitHubItems(data.items);
          
          return data.items;
        }
        
        logger.debug('GitHub API search returned no items, falling back to cache');
        return [];
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        logger.debug(`GitHub API search failed: ${errorMessage}. Falling back to cached search.`);
        ErrorHandler.logError('CollectionSearch.search.githubApi', error, { query });
        
        // Fallback to cached search
        return this.searchFromCache(query);
      }
    }

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/DollhouseMCP/DollhouseMCP'

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