search_wwdc_content
Search WWDC video transcripts and code examples to find specific discussions, API mentions, or implementation examples. Filter by year, language, and search scope.
Instructions
Full-text search across all WWDC video transcripts and code examples. Find specific discussions, API mentions, or implementation examples. More powerful than list_wwdc_videos for finding specific content.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search terms. Examples: "async await", "@Observable", "Vision Pro", "performance optimization". | |
| searchIn | No | Search scope. "transcript" = spoken content, "code" = code examples only, "both" = everything. Default: "both" | |
| year | No | Limit to specific year ("2025", "2024", etc.). Leave empty for all years. | |
| language | No | Code language filter ("swift", "objc", "javascript"). Only for code search. | |
| limit | No | Max results (default: 20). Results include context snippets. |
Implementation Reference
- src/tools/wwdc/wwdc-handlers.ts:137-227 (handler)Main handler function for search_wwdc_content. Iterates over WWDC years, pre-filters videos by title/topic/capabilities, loads video data, searches transcript and/or code content using helper functions, sorts by match count, applies limit, and formats results.
export async function handleSearchWWDCContent( query: string, searchIn: 'transcript' | 'code' | 'both' = 'both', year?: string, language?: string, limit: number = 20, ): Promise<string> { try { const metadata = await loadGlobalMetadata(); const queryLower = query.toLowerCase(); const results: Array<{ video: WWDCVideo & { year: string }; matches: Array<{ type: 'transcript' | 'code'; context: string; timestamp?: string }>; }> = []; // Determine years to search const yearsToSearch = year ? [year] : metadata.years; // Search each year for (const y of yearsToSearch) { try { const yearIndex = await loadYearIndex(y); // Pre-filter: only load videos that might contain search content const potentialVideos = yearIndex.videos.filter(v => { // Basic title and topic matching const titleMatch = v.title?.toLowerCase().includes(queryLower) || false; const topicMatch = v.topics?.some(t => t.toLowerCase().includes(queryLower)) || false; return titleMatch || topicMatch || (searchIn === 'code' || searchIn === 'both') && v.hasCode || (searchIn === 'transcript' || searchIn === 'both') && v.hasTranscript; }); if (potentialVideos.length === 0) { continue; } // 加载视频数据 const videoFiles = potentialVideos.map((v: any) => v.dataFile); const videos = await loadVideosData(videoFiles); // Search each video for (const video of videos) { const matches: Array<{ type: 'transcript' | 'code'; context: string; timestamp?: string }> = []; // Search transcript if ((searchIn === 'transcript' || searchIn === 'both') && video.transcript) { const transcriptMatches = searchInTranscript(video.transcript.fullText, queryLower); matches.push(...transcriptMatches.map(m => ({ type: 'transcript' as const, context: m.context, timestamp: m.timestamp, }))); } // Search code if ((searchIn === 'code' || searchIn === 'both') && video.codeExamples) { const codeMatches = searchInCode(video.codeExamples, queryLower, language); matches.push(...codeMatches.map(m => ({ type: 'code' as const, context: m.context, timestamp: m.timestamp, }))); } if (matches.length > 0) { results.push({ video: { ...video, year: y }, matches: matches.slice(0, 3), // Max 3 matches per video }); } } } catch (error) { logger.warn(`Failed to search year ${y}:`, error); } } // Sort by match count results.sort((a, b) => b.matches.length - a.matches.length); // Apply limit const limitedResults = results.slice(0, limit); return formatSearchResults(limitedResults, query, searchIn); } catch (error) { logger.error('Failed to search WWDC content:', error); const errorMessage = error instanceof Error ? error.message : String(error); return `Error: Failed to search WWDC content: ${errorMessage}`; } } - Helper that searches transcript text line-by-line for the query, returning context snippets with surrounding lines.
function searchInTranscript( fullText: string, query: string, ): Array<{ context: string; timestamp?: string }> { const matches: Array<{ context: string; timestamp?: string }> = []; const lines = fullText.split('\n'); for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line.toLowerCase().includes(query)) { // Get context (one line before and after) const context = [ lines[i - 1] || '', line, lines[i + 1] || '', ].filter(l => l.trim()).join(' ... '); matches.push({ context }); } } return matches; } - Helper that searches code examples for the query, with optional language filter, returning context snippets.
function searchInCode( codeExamples: Array<{ code: string; language: string; timestamp?: string; title?: string }>, query: string, language?: string, ): Array<{ context: string; timestamp?: string }> { const matches: Array<{ context: string; timestamp?: string }> = []; for (const example of codeExamples) { // Language filter if (language && example.language.toLowerCase() !== language.toLowerCase()) { continue; } if (example.code.toLowerCase().includes(query)) { // Extract code snippet containing the query const lines = example.code.split('\n'); const matchingLines = lines.filter(line => line.toLowerCase().includes(query)); matches.push({ context: `[${example.language}] ${example.title || ''}: ${matchingLines[0]}`, timestamp: example.timestamp, }); } } return matches; } - Helper that formats the search results into a Markdown string with video titles, match counts, and context snippets.
function formatSearchResults( results: Array<{ video: WWDCVideo & { year: string }; matches: Array<{ type: 'transcript' | 'code'; context: string; timestamp?: string }>; }>, query: string, searchIn: string, ): string { if (results.length === 0) { return `No ${searchIn === 'code' ? 'code' : searchIn === 'transcript' ? 'transcript' : 'content'} found containing "${query}".`; } let content = '# WWDC Content Search Results\n\n'; content += `**Search Query:** "${query}"\n`; content += `**Search Scope:** ${searchIn === 'code' ? 'Code' : searchIn === 'transcript' ? 'Transcript' : 'All Content'}\n`; content += `**Found ${results.length} related videos**\n\n`; results.forEach(result => { content += `## [${result.video.title}](${result.video.url})\n`; content += `*WWDC${result.video.year} | ${result.matches.length} matches*\n\n`; result.matches.forEach(match => { content += `**${match.type === 'code' ? 'Code' : 'Transcript'}**`; if (match.timestamp) { content += ` (${match.timestamp})`; } content += '\n'; content += `> ${match.context}\n\n`; }); }); return content; } - src/schemas/wwdc.schemas.ts:20-26 (schema)Zod schema defining input validation for search_wwdc_content: query (required), searchIn (enum transcript/code/both), year (optional), language (optional), limit (1-100, default 20).
export const searchWWDCContentSchema = z.object({ query: z.string().min(1).describe('Search query'), searchIn: z.enum(['transcript', 'code', 'both']).default('both').describe('Where to search'), year: z.string().optional().describe('Filter by WWDC year'), language: z.string().optional().describe('Filter code by language'), limit: z.number().min(1).max(100).default(20).describe('Maximum number of results'), }); - src/tools/handlers.ts:245-255 (registration)Registration of the search_wwdc_content handler in the toolHandlers map. Validates args via schema, calls handleSearchWWDCContent, and returns text content.
search_wwdc_content: async (args, _server) => { const validatedArgs = searchWWDCContentSchema.parse(args); const result = await handleSearchWWDCContent( validatedArgs.query, validatedArgs.searchIn, validatedArgs.year, validatedArgs.language, validatedArgs.limit, ); return { content: [{ type: 'text', text: result }] }; }, - src/tools/definitions.ts:354-387 (registration)Tool definition for search_wwdc_content including name, description, and inputSchema with JSON Schema properties (query, searchIn, year, language, limit).
name: 'search_wwdc_content', description: 'Full-text search across all WWDC video transcripts and code examples. Find specific discussions, API mentions, or implementation examples. More powerful than list_wwdc_videos for finding specific content.', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search terms. Examples: "async await", "@Observable", "Vision Pro", "performance optimization".', }, searchIn: { type: 'string', enum: ['transcript', 'code', 'both'], description: 'Search scope. "transcript" = spoken content, "code" = code examples only, "both" = everything. Default: "both"', }, year: { type: 'string', description: 'Limit to specific year ("2025", "2024", etc.). Leave empty for all years.', }, language: { type: 'string', description: 'Code language filter ("swift", "objc", "javascript"). Only for code search.', }, limit: { type: 'number', description: 'Max results (default: 20). Results include context snippets.', }, }, required: ['query'], }, annotations: { title: 'Search WWDC Content', readOnlyHint: true, }, },