Skip to main content
Glama
PeterShin23

SeatGeek MCP Server

find_performer_recommendations

Discover personalized performer recommendations by inputting event, performer, or location details. Find nearby or similar performers based on search queries, venue information, or date ranges for ticketed entertainment events.

Instructions

Get personalized performer recommendations based on performers, events, or location. This tool first searches for performers and/or events based on the queries, then uses the IDs to find similar performers. Use location parameters (geoip, lat/lon, postal_code) for nearby performers.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
end_utcNoEnd date filter in ISO8601 UTC format (YYYY-MM-DD). Use with start_utc to define date ranges.
event_qNoSearch query to find events to base recommendations on. If provided, the system will first look up the event ID automatically.
formatNoOutput format. Use "structured" for readable format (default) or "json" for raw API response. Only use "json" if explicitly requested.structured
pageNoPage number for pagination. Default is 1.
per_pageNoNumber of results to return per page (1-50). Default is 10.
performer_qNoSearch query to find performers to base recommendations on. If provided, the system will first look up the performer ID automatically.
start_utcNoStart date filter in ISO8601 UTC format (YYYY-MM-DD). Use for date ranges like "next month" or "this weekend".
venue_cityNoCity name where the venue is located. Use full city name, e.g., "New York" or "Los Angeles".
venue_countryNoCountry code where the venue is located, e.g., "US" for United States or "CA" for Canada.
venue_stateNoState abbreviation where the venue is located, e.g., "CA" for California or "NY" for New York.

Implementation Reference

  • Primary tool definition and handler implementation for 'find_performer_recommendations'. Handles input parsing, concurrent searches for performers/events, API calls to recommendations endpoint, and result processing/formatting.
    export const findPerformerRecommendationsTool = {
      name: 'find_performer_recommendations',
      description: 'Get personalized performer recommendations based on performers, events, or location. This tool first searches for performers and/or events based on the queries, then uses the IDs to find similar performers. Use location parameters (geoip, lat/lon, postal_code) for nearby performers.',
      inputSchema: inputSchema,
      handler: async (args: any, extra: any) => {
        try {
          const params = PerformerRecommendationsQuerySchema.parse(args);
          const performerIds: number[] = [];
          const eventIds: number[] = [];
          
          // If we have event_q or performer_q parameters, try to look up IDs concurrently
          if (params.event_q || params.performer_q) {
            try {
              // Create promises for concurrent execution
              const promises = [];
              
              // Add performer lookup promise if performer_q is provided
              if (params.performer_q) {
                const performerPromise = searchPerformers(params.performer_q, params.per_page, 1).then(performers => {
                  if (performers.length > 0) {
                    // Get unique performer IDs
                    const uniqueIds = [...new Set(performers.map((p: any) => p.id).filter(Boolean))] as number[];
                    performerIds.push(...uniqueIds);
                  }
                });
                promises.push(performerPromise);
              }
              
              // Add event lookup promise if event_q is provided
              if (params.event_q) {
                // Prepare additional parameters for the event search
                const additionalParams: Record<string, any> = {};
                
                // Add venue location parameters
                if (params.venue_city) {
                  additionalParams["venue.city"] = params.venue_city;
                }
                if (params.venue_state) {
                  additionalParams["venue.state"] = params.venue_state;
                }
                if (params.venue_country) {
                  additionalParams["venue.country"] = params.venue_country;
                }
                
                // Add date filters
                if (params.start_utc) {
                  additionalParams["datetime_utc.gte"] = params.start_utc;
                }
                if (params.end_utc) {
                  additionalParams["datetime_utc.lte"] = params.end_utc;
                }
                
                const eventPromise = searchEvents(params.event_q, params.per_page, additionalParams).then(events => {
                  if (events.length > 0) {
                    // Get unique event IDs
                    const uniqueIds = [...new Set(events.map((e: any) => e.id).filter(Boolean))] as number[];
                    eventIds.push(...uniqueIds);
                  }
                });
                promises.push(eventPromise);
              }
              
              // Execute both promises concurrently
              await Promise.all(promises);
            } catch (error) {
              // If lookup fails, continue with original query
              console.warn('Failed to lookup performer or event, continuing with original query:', error);
            }
          }
          
          // Build query with found IDs
          const query = buildQuery(params, performerIds, eventIds);
          
          // For performer recommendations, we need to use the correct endpoint
          // The recommendations endpoint for performers is still RECOMMENDATIONS_ENDPOINT
          // but with different query parameters
          const data = await fetchJson(`${RECOMMENDATIONS_ENDPOINT}/performers`, query);
          
          if (params.format === 'json') {
            return {
              content: [
                {
                  type: 'text' as const,
                  text: JSON.stringify(data, null, 2)
                }
              ]
            };
          }
          
          // Extract performers from recommendations
          const recommendationsRaw = Array.isArray(data) ? data : (data.recommendations || []);
          const results: Performer[] = [];
          
          for (const item of recommendationsRaw) {
            try {
              // Each recommendation has a performer object
              if (item.performer) {
                const performer = PerformerSchema.parse(item.performer);
                results.push(performer);
              }
            } catch (error) {
              // Skip invalid performers
              console.warn('Skipping invalid performer recommendation:', error);
            }
          }
                
          // Limit results to per_page
          const limitedResults = results.slice(0, params.per_page);
          
          return {
            content: [
              {
                type: 'text' as const,
                text: JSON.stringify(limitedResults, null, 2)
              }
            ]
          };
        } catch (error) {
          console.error('Error in find_performer_recommendations handler:', error);
          
          // Provide more detailed error information
          const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
          const errorDetails = {
            error: 'API_REQUEST_FAILED',
            message: errorMessage,
            timestamp: new Date().toISOString(),
            endpoint: RECOMMENDATIONS_ENDPOINT,
            args: args
          };
          
          return {
            content: [
              {
                type: 'text' as const,
                text: JSON.stringify({
                  error: 'Failed to fetch performer recommendations',
                  details: errorDetails,
                  suggestion: 'Please check your parameters and try again. Common issues include invalid performer IDs, event IDs, or location parameters.'
                }, null, 2)
              }
            ]
          };
        }
      },
    };
  • Input schema definition using Zod for validation and descriptions of tool parameters.
    const inputSchema = {
      event_q: z.string().optional().describe('Search query to find events to base recommendations on. If provided, the system will first look up the event ID automatically.'),
      performer_q: z.string().optional().describe('Search query to find performers to base recommendations on. If provided, the system will first look up the performer ID automatically.'),
      venue_city: z.string().optional().describe('City name where the venue is located. Use full city name, e.g., "New York" or "Los Angeles".'),
      venue_state: z.string().optional().describe('State abbreviation where the venue is located, e.g., "CA" for California or "NY" for New York.'),
      venue_country: z.string().optional().describe('Country code where the venue is located, e.g., "US" for United States or "CA" for Canada.'),
      start_utc: z.string().optional().describe('Start date filter in ISO8601 UTC format (YYYY-MM-DD). Use for date ranges like "next month" or "this weekend".'),
      end_utc: z.string().optional().describe('End date filter in ISO8601 UTC format (YYYY-MM-DD). Use with start_utc to define date ranges.'),
      per_page: z.number().min(1).max(50).default(10).describe('Number of results to return per page (1-50). Default is 10.'),
      page: z.number().min(1).default(1).describe('Page number for pagination. Default is 1.'),
      format: z.enum(['structured', 'json']).default('structured').describe('Output format. Use "structured" for readable format (default) or "json" for raw API response. Only use "json" if explicitly requested.'),
    };
  • src/server.ts:25-25 (registration)
    Registration of the find_performer_recommendations tool with the MCP server.
    mcpServer.tool(findPerformerRecommendationsTool.name, findPerformerRecommendationsTool.description, findPerformerRecommendationsTool.inputSchema, findPerformerRecommendationsTool.handler);
  • src/index.ts:3-3 (registration)
    Export of the tool for use in other modules like server.ts.
    export { findPerformerRecommendationsTool } from './tools/findPerformerRecommendations';
  • Helper function to construct the query object for the recommendations API call.
    function buildQuery(params: PerformerRecommendationsQuery, performerIds: number[] = [], eventIds: number[] = []): Record<string, any> {
      const query: Record<string, any> = {
        per_page: Math.min(params.per_page, 50),
        page: params.page,
      };
      
      // Add venue location - API expects flat format
      if (params.venue_city) {
        query["venue.city"] = params.venue_city;
      }
      if (params.venue_state) {
        query["venue.state"] = params.venue_state;
      }
      if (params.venue_country) {
        query["venue.country"] = params.venue_country;
      }
      
      // Add date filters if provided
      if (params.start_utc) {
        query["datetime_utc.gte"] = params.start_utc;
      }
      if (params.end_utc) {
        query["datetime_utc.lte"] = params.end_utc;
      }
      
      // Add performer and event IDs if provided
      if (performerIds.length > 0) {
        query["performer_ids"] = performerIds.join(',');
      }
      
      if (eventIds.length > 0) {
        query["event_ids"] = eventIds.join(',');
      }
      
      // Drop null/undefined values to avoid noisy query strings
      const filteredQuery: Record<string, any> = {};
      for (const [key, value] of Object.entries(query)) {
        if (value !== null && value !== undefined && value !== '') {
          filteredQuery[key] = value;
        }
      }
      
      return filteredQuery;
    }
Install Server

Other Tools

Related Tools

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/PeterShin23/seatgeek-mcp'

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