Skip to main content
Glama

search

Find Disney parks attractions, restaurants, and shows by ID or name using fuzzy matching for Walt Disney World or Disneyland.

Instructions

Search for Disney entities by ID or name. Uses fuzzy matching for name queries like 'Space Mountain' or 'Be Our Guest'. For conceptual queries like 'thrill rides' or 'romantic dinner', use discover instead.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoEntity ID for exact lookup (e.g., '80010190')
nameNoEntity name to search for (e.g., 'Space Mountain', 'Haunted Mansion')
destinationNoLimit search to a destination: 'wdw' or 'dlr'
entityTypeNoFilter by entity type

Implementation Reference

  • The main handler function for the 'search' tool. Handles exact lookup by ID or fuzzy matching by name for Disney entities (attractions, dining, shows). Falls back to API fetches if not in local DB, performs fuzzy search, returns best match with alternatives and confidence scores.
    export const handler: ToolHandler = async (args) => { return withTimeout( "search", async () => { const id = args.id as string | undefined; const name = args.name as string | undefined; const destination = args.destination as DestinationId | undefined; const entityType = args.entityType as EntityType | undefined; // Require either id or name if (!id && !name) { return formatErrorResponse( new ValidationError("Either 'id' or 'name' is required", "id|name", null) ); } try { // Direct ID lookup if (id) { const entity = await getEntityById(id); if (!entity) { // Try fetching from API if not in local DB const client = getDisneyFinderClient(); const fetched = await client.getEntityById(id); if (!fetched) { return { content: [ { type: "text" as const, text: JSON.stringify( { id, found: false, message: "No entity found with this ID", }, null, 2 ), }, ], }; } return formatEntityResult(fetched); } return formatEntityResult(entity); } // Fuzzy name search if (name) { // First try fuzzy search in database let candidates = await searchEntitiesByName<DisneyEntity>(name, { destinationId: destination, entityType, limit: EXTENDED_SEARCH_LIMIT, }); // If no results in DB, fetch from API first if (candidates.length === 0) { const client = getDisneyFinderClient(); const destinations = destination ? [destination] : (["wdw", "dlr"] as DestinationId[]); for (const dest of destinations) { if (!entityType || entityType === "ATTRACTION") { await client.getAttractions(dest); } if (!entityType || entityType === "RESTAURANT") { await client.getDining(dest); } if (!entityType || entityType === "SHOW") { await client.getShows(dest); } } // Try search again candidates = await searchEntitiesByName<DisneyEntity>(name, { destinationId: destination, entityType, limit: EXTENDED_SEARCH_LIMIT, }); } // If still no results, try loading from DB and fuzzy matching if (candidates.length === 0) { const destinations = destination ? [destination] : (["wdw", "dlr"] as DestinationId[]); candidates = []; for (const dest of destinations) { if (!entityType || entityType === "ATTRACTION") { candidates.push(...(await getAttractions(dest))); } if (!entityType || entityType === "RESTAURANT") { candidates.push(...(await getDining(dest))); } if (!entityType || entityType === "SHOW") { candidates.push(...(await getShows(dest))); } } } // Perform fuzzy matching const matches = fuzzySearch(name, candidates, { threshold: DEFAULT_FUZZY_SEARCH_THRESHOLD, limit: DEFAULT_DISCOVER_LIMIT, }); if (matches.length === 0) { return { content: [ { type: "text" as const, text: JSON.stringify( { query: name, found: false, message: "No matching entities found. Try discover for conceptual searches.", }, null, 2 ), }, ], }; } // Return best match with alternatives // WHY: Safe to assert - we checked matches.length > 0 above // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const bestMatch = matches[0]!; const alternatives = matches.slice(1); return { content: [ { type: "text" as const, text: JSON.stringify( { query: name, found: true, confidence: Math.round(bestMatch.score * 100) / 100, bestMatch: formatEntity(bestMatch.entity), alternatives: alternatives.map((m) => ({ name: m.entity.name, id: m.entity.id, type: m.entity.entityType, score: Math.round(m.score * 100) / 100, })), }, null, 2 ), }, ], }; } return formatErrorResponse(new Error("Unexpected state")); } catch (error) { return formatErrorResponse(error); } }, TIMEOUTS.SEARCH ); };
  • ToolDefinition for 'search' including name, description, and inputSchema defining parameters: id (optional string), name (optional string), destination (optional enum wdw/dlr), entityType (optional enum ATTRACTION/RESTAURANT/SHOW). Requires either id or name.
    export const definition: ToolDefinition = { name: "search", description: "Search for Disney entities by ID or name. " + "Uses fuzzy matching for name queries like 'Space Mountain' or 'Be Our Guest'. " + "For conceptual queries like 'thrill rides' or 'romantic dinner', use discover instead.", inputSchema: { type: "object" as const, properties: { id: { type: "string", description: "Entity ID for exact lookup (e.g., '80010190')", }, name: { type: "string", description: "Entity name to search for (e.g., 'Space Mountain', 'Haunted Mansion')", }, destination: { type: "string", description: "Limit search to a destination: 'wdw' or 'dlr'", enum: ["wdw", "dlr"], }, entityType: { type: "string", description: "Filter by entity type", enum: ["ATTRACTION", "RESTAURANT", "SHOW"], }, }, required: [], }, };
  • Registration of all tools in the tools array, including the 'search' tool entry with its definition and handler.
    const tools: ToolEntry[] = [ { definition: destinations.definition, handler: destinations.handler }, { definition: attractions.definition, handler: attractions.handler }, { definition: dining.definition, handler: dining.handler }, { definition: search.definition, handler: search.handler }, { definition: discover.definition, handler: discover.handler }, { definition: status.definition, handler: status.handler }, { definition: sync.definition, handler: sync.handler }, ];
  • registerTools function that populates a Map with all tools by name, including 'search', for MCP tool lookup.
    export function registerTools(toolMap: Map<string, ToolEntry>): void { for (const tool of tools) { toolMap.set(tool.definition.name, tool); } }
  • Helper function to format entity data for output, normalizing field names.
    function formatEntity(entity: DisneyEntity): Record<string, unknown> { // Return full entity data with normalized field names const { entityType, destinationId, parkName, ...rest } = entity; return { ...rest, type: entityType, destination: destinationId, park: parkName, }; }

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/cameronsjo/mouse-mcp'

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