upload_video
Upload an ad video from a public URL to obtain a video ID for use in ad creatives.
Instructions
Upload an ad video from a public URL. Returns video ID for use in ad creatives.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_url | Yes | Public URL of the video to upload | |
| title | No | Video title | |
| description | No | Video description |
Implementation Reference
- src/tools/videos.ts:29-49 (handler)The 'upload_video' tool handler function. Uses AdsClient.post to POST file_url (with optional title/description) to `${client.accountPath}/advideos` (i.e., /act_{ACCOUNT_ID}/advideos). Returns the API response data with rate limit info, or an error message.
// ─── upload_video ────────────────────────────────────────── server.tool( "upload_video", "Upload an ad video from a public URL. Returns video ID for use in ad creatives.", { file_url: z.string().describe("Public URL of the video to upload"), title: z.string().optional().describe("Video title"), description: z.string().optional().describe("Video description"), }, async ({ file_url, title, description }) => { try { const params: Record<string, unknown> = { file_url }; if (title) params.title = title; if (description) params.description = description; const { data, rateLimit } = await client.post(`${client.accountPath}/advideos`, params); return { content: [{ type: "text" as const, text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text" as const, text: `Failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); - src/tools/videos.ts:33-37 (schema)Zod input schema for 'upload_video': file_url (required string), title (optional string), description (optional string).
{ file_url: z.string().describe("Public URL of the video to upload"), title: z.string().optional().describe("Video title"), description: z.string().optional().describe("Video description"), }, - src/tools/videos.ts:5-57 (registration)The 'registerVideoTools' function registers all video tools (including upload_video) on the MCP server via server.tool().
export function registerVideoTools(server: McpServer, client: AdsClient): void { // ─── list_videos ─────────────────────────────────────────── server.tool( "list_videos", "List ad videos uploaded to the ad account.", { fields: z.string().optional().describe("Comma-separated fields to return"), limit: z.number().optional().default(25).describe("Number of results (default 25)"), after: z.string().optional().describe("Pagination cursor for next page"), }, async ({ fields, limit, after }) => { try { const params: Record<string, unknown> = {}; if (fields) params.fields = fields; if (limit) params.limit = limit; if (after) params.after = after; const { data, rateLimit } = await client.get(`${client.accountPath}/advideos`, params); return { content: [{ type: "text" as const, text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text" as const, text: `Failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── upload_video ────────────────────────────────────────── server.tool( "upload_video", "Upload an ad video from a public URL. Returns video ID for use in ad creatives.", { file_url: z.string().describe("Public URL of the video to upload"), title: z.string().optional().describe("Video title"), description: z.string().optional().describe("Video description"), }, async ({ file_url, title, description }) => { try { const params: Record<string, unknown> = { file_url }; if (title) params.title = title; if (description) params.description = description; const { data, rateLimit } = await client.post(`${client.accountPath}/advideos`, params); return { content: [{ type: "text" as const, text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text" as const, text: `Failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── get_video ───────────────────────────────────────────── server.tool( "get_video", "Get details of a specific ad video by ID.", { video_id: z.string().describe("Video ID"), fields: z.string().optional().describe("Comma-separated fields to return"), - src/index.ts:15-58 (registration)Import and call to registerVideoTools(server, client) which registers upload_video on the MCP server.
import { registerVideoTools } from "./tools/videos.js"; import { registerCanvasTools } from "./tools/canvas.js"; import { registerAudienceTools } from "./tools/audiences.js"; import { registerTargetingTools } from "./tools/targeting.js"; import { registerInsightTools } from "./tools/insights.js"; import { registerLeadTools } from "./tools/leads.js"; import { registerCatalogTools } from "./tools/catalogs.js"; import { registerFeedTools } from "./tools/feeds.js"; import { registerRuleTools } from "./tools/rules.js"; import { registerExperimentTools } from "./tools/experiments.js"; import { registerConversionTools } from "./tools/conversions.js"; import { registerBudgetTools } from "./tools/budget.js"; import { registerReachFrequencyTools } from "./tools/reach_frequency.js"; import { registerBrandSafetyTools } from "./tools/brand_safety.js"; import { registerAccountTools } from "./tools/account.js"; import { registerBusinessTools } from "./tools/business.js"; import { registerAuthTools } from "./tools/auth.js"; import { registerAdLibraryTools } from "./tools/ad_library.js"; // --- Resources & Prompts --- import { registerResources } from "./resources/account.js"; import { registerPrompts } from "./prompts/index.js"; const require = createRequire(import.meta.url); const { version } = require("../package.json"); const server = new McpServer({ name: "meta-ads-mcp", version, }); const config = loadConfig(); const client = new AdsClient(config); // --- Campaign Management --- registerCampaignTools(server, client); registerAdsetTools(server, client); registerAdTools(server, client); registerCreativeTools(server, client); // --- Assets --- registerImageTools(server, client); registerVideoTools(server, client); registerCanvasTools(server, client); - src/services/ads-client.ts:187-209 (helper)The AdsClient.post() method (called by the handler) which sends a POST request to the Meta Graph API with JSON body containing access_token and params.
async post( path: string, params?: Record<string, unknown> ): Promise<ClientResponse> { return this.request("POST", path, params); } async delete( path: string, params?: Record<string, unknown> ): Promise<ClientResponse> { return this.request("DELETE", path, params); } // --- Upload (URL-based) --- async upload( path: string, fileUrl: string, params?: Record<string, unknown> ): Promise<ClientResponse> { return this.post(path, { ...params, url: fileUrl }); }