Skip to main content
Glama
media.ts9.01 kB
import * as fs from "fs"; import { WordPressClient } from "@/client/api.js"; import { MediaQueryParams, UpdateMediaRequest, UploadMediaRequest } from "@/types/wordpress.js"; import { getErrorMessage } from "@/utils/error.js"; /** * Comprehensive media management tools for WordPress sites. * * This class provides complete media library functionality including: * - Listing media items with advanced filtering and search * - Uploading new media files with validation and optimization * - Retrieving detailed media information and metadata * - Updating media properties like title, description, and alt text * - Deleting media items with safety checks * * Supports all WordPress media types including images, videos, audio files, * and documents with proper MIME type validation and security checks. * * @example * ```typescript * const mediaTools = new MediaTools(); * const tools = mediaTools.getTools(); * * // Upload an image * const client = new WordPressClient(config); * const result = await mediaTools.handleUploadMedia(client, { * file_path: "/path/to/image.jpg", * title: "My Image", * alt_text: "Description of the image" * }); * ``` * * @since 1.0.0 * @author MCP WordPress Team */ export class MediaTools { /** * Retrieves the complete list of media management tools available for MCP. * * Returns an array of tool definitions for comprehensive media library management. * Each tool includes parameter validation, security checks, and detailed error handling. * * @returns {Array<MCPTool>} Array of MCPTool definitions for media management * * @example * ```typescript * const mediaTools = new MediaTools(); * const tools = mediaTools.getTools(); * console.log(tools.length); // 5 tools: list, get, upload, update, delete * ``` * * @since 1.0.0 */ public getTools(): Array<{ name: string; description: string; parameters?: Array<{ name: string; type?: string; description?: string; required?: boolean; enum?: string[]; items?: unknown; }>; handler: (client: WordPressClient, params: Record<string, unknown>) => Promise<unknown>; }> { return [ { name: "wp_list_media", description: "Lists media items from a WordPress site, with filters.", parameters: [ { name: "per_page", type: "number", description: "Number of items to return per page (max 100).", }, { name: "search", type: "string", description: "Limit results to those matching a search term.", }, { name: "media_type", type: "string", description: "Limit results to a specific media type.", enum: ["image", "video", "audio", "application"], }, ], handler: this.handleListMedia.bind(this), }, { name: "wp_get_media", description: "Retrieves a single media item by its ID.", parameters: [ { name: "id", type: "number", required: true, description: "The unique identifier for the media item.", }, ], handler: this.handleGetMedia.bind(this), }, { name: "wp_upload_media", description: "Uploads a file to the WordPress media library.", parameters: [ { name: "file_path", type: "string", required: true, description: "The local, absolute path to the file to upload.", }, { name: "title", type: "string", description: "The title for the media item.", }, { name: "alt_text", type: "string", description: "Alternative text for the media item (for accessibility).", }, { name: "caption", type: "string", description: "The caption for the media item.", }, { name: "description", type: "string", description: "The description for the media item.", }, { name: "post", type: "number", description: "The ID of a post to attach this media to.", }, ], handler: this.handleUploadMedia.bind(this), }, { name: "wp_update_media", description: "Updates the metadata of an existing media item.", parameters: [ { name: "id", type: "number", required: true, description: "The ID of the media item to update.", }, { name: "title", type: "string", description: "The new title for the media item.", }, { name: "alt_text", type: "string", description: "The new alternative text.", }, { name: "caption", type: "string", description: "The new caption.", }, { name: "description", type: "string", description: "The new description.", }, ], handler: this.handleUpdateMedia.bind(this), }, { name: "wp_delete_media", description: "Deletes a media item.", parameters: [ { name: "id", type: "number", required: true, description: "The ID of the media item to delete.", }, { name: "force", type: "boolean", description: "If true, permanently delete. If false, move to trash. Defaults to false.", }, ], handler: this.handleDeleteMedia.bind(this), }, ]; } public async handleListMedia(client: WordPressClient, params: Record<string, unknown>): Promise<unknown> { const queryParams = params as MediaQueryParams; try { const media = await client.getMedia(queryParams); if (media.length === 0) { return "No media items found matching the criteria."; } const content = `Found ${media.length} media items:\n\n` + media.map((m) => `- ID ${m.id}: **${m.title.rendered}** (${m.mime_type})\n Link: ${m.source_url}`).join("\n"); return content; } catch (_error) { throw new Error(`Failed to list media: ${getErrorMessage(_error)}`); } } public async handleGetMedia(client: WordPressClient, params: Record<string, unknown>): Promise<unknown> { const { id } = params as { id: number }; try { const media = await client.getMediaItem(id); const content = `**Media Details (ID: ${media.id})**\n\n` + `- **Title:** ${media.title.rendered}\n` + `- **URL:** ${media.source_url}\n` + `- **Type:** ${media.media_type} (${media.mime_type})\n` + `- **Date:** ${new Date(media.date).toLocaleString()}\n` + (media.alt_text ? `- **Alt Text:** ${media.alt_text}\n` : "") + (media.caption.rendered ? `- **Caption:** ${media.caption.rendered}\n` : ""); return content; } catch (_error) { throw new Error(`Failed to get media item: ${getErrorMessage(_error)}`); } } public async handleUploadMedia(client: WordPressClient, params: Record<string, unknown>): Promise<unknown> { const uploadParams = params as unknown as UploadMediaRequest & { file_path: string }; try { try { await fs.promises.access(uploadParams.file_path); } catch (_error) { throw new Error(`File not found at path: ${uploadParams.file_path}`); } const media = await client.uploadMedia(uploadParams); return `✅ Media uploaded successfully!\n- ID: ${media.id}\n- Title: ${media.title.rendered}\n- URL: ${media.source_url}`; } catch (_error) { throw new Error(`Failed to upload media: ${getErrorMessage(_error)}`); } } public async handleUpdateMedia(client: WordPressClient, params: Record<string, unknown>): Promise<unknown> { const updateParams = params as unknown as UpdateMediaRequest & { id: number }; try { const media = await client.updateMedia(updateParams); return `✅ Media ${media.id} updated successfully.`; } catch (_error) { throw new Error(`Failed to update media: ${getErrorMessage(_error)}`); } } public async handleDeleteMedia(client: WordPressClient, params: Record<string, unknown>): Promise<unknown> { const { id, force } = params as { id: number; force?: boolean }; try { await client.deleteMedia(id, force); const action = force ? "permanently deleted" : "moved to trash"; return `✅ Media item ${id} has been ${action}`; } catch (_error) { throw new Error(`Failed to delete media: ${getErrorMessage(_error)}`); } } } export default MediaTools;

Implementation Reference

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/docdyhr/mcp-wordpress'

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