get_metadata
Retrieve video metadata, comments, chapters, and AI summary from a Loom or direct video URL without downloading or extracting frames. Get structured information faster than full video analysis.
Instructions
Get video metadata, comments, chapters, and AI summary from a video URL.
Returns structured metadata without downloading the video or extracting frames. Faster than analyze_video when you only need metadata.
Supports: Loom (loom.com/share/...) and direct video URLs (.mp4, .webm, .mov).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Video URL (Loom share link or direct mp4/webm URL) |
Implementation Reference
- src/tools/get-metadata.ts:11-75 (handler)The main handler that registers and implements the get_metadata tool. Accepts a video URL, resolves the adapter, then fetches metadata, comments, chapters, and AI summary in parallel via the adapter. Returns all data as JSON.
export function registerGetMetadata(server: FastMCP): void { server.addTool({ name: 'get_metadata', description: `Get video metadata, comments, chapters, and AI summary from a video URL. Returns structured metadata without downloading the video or extracting frames. Faster than analyze_video when you only need metadata. Supports: Loom (loom.com/share/...) and direct video URLs (.mp4, .webm, .mov).`, parameters: GetMetadataSchema, annotations: { title: 'Get Metadata', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, execute: async (args, { reportProgress }) => { const progress = createProgressReporter(reportProgress); const { url } = args; let adapter; try { adapter = getAdapter(url); } catch (error) { if (error instanceof UserError) throw error; throw new UserError(`Failed to detect video platform for URL: ${url}`); } const warnings: string[] = []; await progress(0, 'Fetching video metadata...'); const [metadata, comments, chapters, aiSummary] = await Promise.all([ adapter.getMetadata(url).catch((e: unknown) => { warnings.push(`Failed to fetch metadata: ${e instanceof Error ? e.message : String(e)}`); return { platform: adapter.name as 'loom' | 'direct' | 'unknown', title: 'Unknown', duration: 0, durationFormatted: '0:00', url, }; }), adapter.getComments(url).catch((e: unknown) => { warnings.push(`Failed to fetch comments: ${e instanceof Error ? e.message : String(e)}`); return []; }), adapter.getChapters(url).catch(() => []), adapter.getAiSummary(url).catch(() => null), ]); await progress(100, 'Metadata fetched'); return { content: [ { type: 'text' as const, text: JSON.stringify({ metadata, comments, chapters, aiSummary, warnings }, null, 2), }, ], }; }, }); } - src/tools/get-metadata.ts:7-9 (schema)Zod schema for the input parameter: requires a single 'url' field that must be a valid URL string.
const GetMetadataSchema = z.object({ url: z.string().url().describe('Video URL (Loom share link or direct mp4/webm URL)'), }); - src/server.ts:65-65 (registration)Registration of the get_metadata tool in the MCP server setup.
registerGetMetadata(server); - src/adapters/loom.adapter.ts:122-151 (helper)Loom adapter's getMetadata implementation: fetches video details via Loom GraphQL API.
async getMetadata(url: string): Promise<IVideoMetadata> { const videoId = extractLoomId(url); const data = await loomGraphQL<LoomVideoData>( `query GetVideo($videoId: ID!, $password: String) { getVideo(id: $videoId, password: $password) { ... on RegularUserVideo { __typename id name description playable_duration owner { display_name } createdAt } ... on PrivateVideo { __typename id } } }`, { videoId, password: null }, ); const video = data?.getVideo; return { platform: 'loom', title: video?.name ?? 'Untitled Loom Video', description: video?.description ?? undefined, duration: video?.playable_duration ?? 0, durationFormatted: formatDuration(video?.playable_duration ?? 0), url, }; } - src/adapters/direct.adapter.ts:44-53 (helper)Direct adapter's getMetadata implementation: extracts filename from URL, returns basic metadata (duration unknown for direct URLs).
async getMetadata(url: string): Promise<IVideoMetadata> { const filename = getFilenameFromUrl(url); return { platform: 'direct', title: filename, duration: 0, durationFormatted: '0:00', url, }; }