wpnav_upload_media_from_url
Download images from URLs and upload them to WordPress media library using server-side processing, avoiding binary data transfer through MCP connections.
Instructions
Upload media from URL (server-side download). Downloads an image from a URL and uploads it to WordPress media library without sending binary data over MCP.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Image URL to download and upload | |
| title | Yes | Media title | |
| alt_text | No | Alt text for accessibility (optional) | |
| caption | No | Media caption (optional) |
Implementation Reference
- src/tools/content/index.ts:823-865 (handler)Handler function that validates inputs, prepares sideload data, POSTs to custom WP endpoint /wpnav/v1/media/sideload for server-side download and upload of media from URL, returns result or error.handler: async (args, context) => { try { validateRequired(args, ['url', 'title']); // Use the WP Navigator server-side sideload endpoint. // This avoids DNS resolution issues when the MCP client can't resolve external domains. // WordPress server downloads the URL instead of the local MCP client. const sideloadData: Record<string, string> = { url: args.url, title: args.title, }; if (args.alt_text) sideloadData.alt_text = args.alt_text; if (args.caption) sideloadData.caption = args.caption; const result = await context.wpRequest('/wpnav/v1/media/sideload', { method: 'POST', body: JSON.stringify(sideloadData), }); return { content: [{ type: 'text', text: context.clampText(JSON.stringify(result, null, 2)), }], }; } catch (error: any) { const errorMessage = error.message || 'Unknown error'; return { content: [{ type: 'text', text: JSON.stringify({ error: 'operation_failed', code: 'UPLOAD_FAILED', message: errorMessage, context: { resource_type: 'media', url: args.url, title: args.title, suggestion: 'Check URL is accessible and returns valid image' }, }, null, 2), }], isError: true, }; } }, category: ToolCategory.CONTENT, });
- src/tools/content/index.ts:812-821 (schema)Input schema defining required 'url' and 'title', optional 'alt_text' and 'caption' for the wpnav_upload_media_from_url tool.inputSchema: { type: 'object', properties: { url: { type: 'string', format: 'uri', description: 'Image URL to download and upload' }, title: { type: 'string', description: 'Media title' }, alt_text: { type: 'string', description: 'Alt text for accessibility (optional)' }, caption: { type: 'string', description: 'Media caption (optional)' }, }, required: ['url', 'title'], },
- src/tools/content/index.ts:808-865 (registration)Full tool registration including definition, schema, handler, and category for wpnav_upload_media_from_url in the content tools module.toolRegistry.register({ definition: { name: 'wpnav_upload_media_from_url', description: 'Upload media from URL (server-side download). Downloads an image from a URL and uploads it to WordPress media library without sending binary data over MCP.', inputSchema: { type: 'object', properties: { url: { type: 'string', format: 'uri', description: 'Image URL to download and upload' }, title: { type: 'string', description: 'Media title' }, alt_text: { type: 'string', description: 'Alt text for accessibility (optional)' }, caption: { type: 'string', description: 'Media caption (optional)' }, }, required: ['url', 'title'], }, }, handler: async (args, context) => { try { validateRequired(args, ['url', 'title']); // Use the WP Navigator server-side sideload endpoint. // This avoids DNS resolution issues when the MCP client can't resolve external domains. // WordPress server downloads the URL instead of the local MCP client. const sideloadData: Record<string, string> = { url: args.url, title: args.title, }; if (args.alt_text) sideloadData.alt_text = args.alt_text; if (args.caption) sideloadData.caption = args.caption; const result = await context.wpRequest('/wpnav/v1/media/sideload', { method: 'POST', body: JSON.stringify(sideloadData), }); return { content: [{ type: 'text', text: context.clampText(JSON.stringify(result, null, 2)), }], }; } catch (error: any) { const errorMessage = error.message || 'Unknown error'; return { content: [{ type: 'text', text: JSON.stringify({ error: 'operation_failed', code: 'UPLOAD_FAILED', message: errorMessage, context: { resource_type: 'media', url: args.url, title: args.title, suggestion: 'Check URL is accessible and returns valid image' }, }, null, 2), }], isError: true, }; } }, category: ToolCategory.CONTENT, });