Skip to main content
Glama
PeterShin23

SeatGeek MCP Server

find_event_recommendations

Discover personalized event recommendations by searching for performers, events, or locations. Use geo-location, coordinates, or postal codes to find nearby events, with optional date filters and pagination.

Instructions

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
end_utcNoEnd date filter in ISO8601 UTC format (YYYY-MM-DD). Use with start_utc to define date ranges.
formatNoOutput format. Use "structured" for readable format (default) or "json" for raw API response. Only use "json" if explicitly requested.structured
geoipNoUse IP geolocation to provide recommendations for events near the user.
latNoLatitude coordinate for location-based recommendations. Use with lon and optionally range.
lonNoLongitude coordinate for location-based recommendations. Use with lat and optionally range.
pageNoPage number for pagination. Default is 1.
per_pageNoNumber of results to return per page (1-50). Default is 10.
postal_codeNoPostal code for location-based recommendations. Use with country code for better accuracy.
qNoSearch query to find either an event or performer to base recommendations on. If provided, the system will first look up the event ID or performer ID/slug automatically.
rangeNoSearch radius for location-based recommendations (e.g., "50mi", "25km"). Use with lat/lon or postal_code.
start_utcNoStart date filter in ISO8601 UTC format (YYYY-MM-DD). Use for date ranges like "next month" or "this weekend".

Implementation Reference

  • The main handler function that executes the tool logic: parses input parameters, optionally looks up performer or event IDs based on query 'q', builds the API query, fetches recommendations from the endpoint, processes and condenses event data, and returns formatted JSON output or error details.
    handler: async (args: any, extra: any) => {
      try {
        const params = EventRecommendationsQuerySchema.parse(args);
        let performerId: number | null = null;
        let eventId: number | null = null;
        
        // If we have a q parameter, try to look up performer and event IDs
        if (params.q) {
          try {
            // First try to find performers with the query
            const performers = await searchPerformers(params.q, params.per_page, 1);
            
            // If we found performers, aggregate unique performer slugs and make Promise.all query
            if (performers.length > 0) {
              // Get unique performer slugs
              const uniqueSlugs = [...new Set(performers.map((p: any) => p.slug).filter(Boolean))] as string[];
              
              if (uniqueSlugs.length > 0) {
                // Create promises for each unique performer slug
                const promises = uniqueSlugs.map(slug => {
                  return searchEvents(slug, params.per_page, { "performers.slug": slug });
                });
                
                // Execute all promises
                const results = await Promise.all(promises);
                
                // Merge events from all results
                const allEvents: any[] = [];
                for (const result of results) {
                  if (Array.isArray(result)) {
                    allEvents.push(...result);
                  }
                }
                
                // Remove duplicates based on event id
                const eventIds = new Set();
                const uniqueEvents = allEvents.filter(event => {
                  if (eventIds.has(event.id)) {
                    return false;
                  }
                  eventIds.add(event.id);
                  return true;
                });
                
                // Use the first event's ID for recommendations if available
                if (uniqueEvents.length > 0 && uniqueEvents[0].id) {
                  eventId = uniqueEvents[0].id;
                }
              } else {
                // If no valid slugs found, search events directly with the q parameter
                const events = await searchEvents(params.q, params.per_page, {});
                if (events.length > 0 && events[0].id) {
                  eventId = events[0].id;
                }
              }
            } else {
              // If no performer found, search events directly with the q parameter
              const events = await searchEvents(params.q, params.per_page, {});
              if (events.length > 0 && events[0].id) {
                eventId = events[0].id;
              }
            }
          } 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 (convert null to undefined for TypeScript)
        const query = buildQuery(
          params, 
          performerId !== null ? performerId : undefined, 
          eventId !== null ? eventId : undefined
        );
        const data = await fetchJson(RECOMMENDATIONS_ENDPOINT, query);
        
        if (params.format === 'json') {
          return {
            content: [
              {
                type: 'text' as const,
                text: JSON.stringify(data, null, 2)
              }
            ]
          };
        }
        
        // Extract events from recommendations
        const recommendationsRaw = Array.isArray(data) ? data : (data.recommendations || []);
        const results: CondensedEvent[] = [];
        
        for (const item of recommendationsRaw) {
          try {
            // Each recommendation has an event object
            if (item.event) {
              // Condense the event data
              const condensedEvent = condenseEventData(item.event);
              results.push(condensedEvent);
            }
          } catch (error) {
            // Skip invalid events
            console.warn('Skipping invalid event recommendation:', error);
          }
        }
              
        return {
          content: [
            {
              type: 'text' as const,
              text: JSON.stringify(results, null, 2)
            }
          ]
        };
      } catch (error) {
        console.error('Error in find_event_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 event recommendations',
                details: errorDetails,
                suggestion: 'Please check your parameters and try again. Common issues include invalid performer IDs, event IDs, or location parameters.'
              }, null, 2)
            }
          ]
        };
      }
    },
  • Zod-based input schema defining parameters for event recommendations, including search query, location filters, date ranges, pagination, and output format with detailed descriptions for the MCP tool.
    const inputSchema = {
      q: z.string().optional().describe('Search query to find either an event or performer to base recommendations on. If provided, the system will first look up the event ID or performer ID/slug automatically.'),
      geoip: z.boolean().optional().describe('Use IP geolocation to provide recommendations for events near the user.'),
      lat: z.number().optional().describe('Latitude coordinate for location-based recommendations. Use with lon and optionally range.'),
      lon: z.number().optional().describe('Longitude coordinate for location-based recommendations. Use with lat and optionally range.'),
      postal_code: z.string().optional().describe('Postal code for location-based recommendations. Use with country code for better accuracy.'),
      range: z.string().optional().describe('Search radius for location-based recommendations (e.g., "50mi", "25km"). Use with lat/lon or postal_code.'),
      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:24-24 (registration)
    Registers the 'find_event_recommendations' tool with the MCP server using its name, description, input schema, and handler function.
    mcpServer.tool(findEventRecommendationsTool.name, findEventRecommendationsTool.description, findEventRecommendationsTool.inputSchema, findEventRecommendationsTool.handler);
  • Helper function that constructs and filters the query parameters for the recommendations API endpoint, incorporating location, date filters, pagination, and optional performer/event IDs.
    function buildQuery(params: EventRecommendationsQuery, performerId?: number, eventId?: number): Record<string, any> {
      const query: Record<string, any> = {
        "geoip": params.geoip,
        "lat": params.lat,
        "lon": params.lon,
        "postal_code": params.postal_code,
        "range": params.range,
        per_page: Math.min(params.per_page, 50),
        page: params.page,
      };
      
      // Add performer and event IDs if provided
      if (performerId) {
        query["performers.id"] = performerId;
      }
      
      if (eventId) {
        query["events.id"] = eventId;
      };
      
      // 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;
      }
      
      // 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) {
          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