Skip to main content
Glama
media-service.ts4.25 kB
// WordPress Media Service import { AxiosInstance } from 'axios'; import FormData from 'form-data'; import * as fs from 'fs'; import * as path from 'path'; import { logger } from '../../utils/logger.js'; import { ErrorHandler, ErrorCategory, MCPError } from '../../utils/error-handler.js'; export interface MediaQueryParams { per_page?: number; page?: number; search?: string; media_type?: 'image' | 'video' | 'audio' | 'application'; mime_type?: string; parent?: number; } export interface MediaUploadOptions { title?: string; alt_text?: string; caption?: string; description?: string; post?: number; } export class MediaService { constructor(private client: AxiosInstance, private baseUrl: string) {} async getMedia(params: MediaQueryParams = {}): Promise<any> { return ErrorHandler.wrapAsync(async () => { const defaultParams = { per_page: 10, ...params }; logger.debug('Listing media', defaultParams); const response = await this.client.get('/media', { params: defaultParams }); logger.debug(`Found ${response.data.length} media items`); return { media: response.data, total: response.headers['x-wp-total'], totalPages: response.headers['x-wp-totalpages'] }; }, 'MediaService.getMedia'); } async getMediaItem(id: number): Promise<any> { return ErrorHandler.wrapAsync(async () => { logger.debug(`Fetching media item ${id}`); const response = await this.client.get(`/media/${id}`); return response.data; }, 'MediaService.getMediaItem'); } async uploadMedia(filePath: string, options: MediaUploadOptions = {}): Promise<any> { return ErrorHandler.wrapAsync(async () => { // Validate file exists if (!fs.existsSync(filePath)) { throw new MCPError( `File not found: ${filePath}`, ErrorCategory.FILE_OPERATION, 'FILE_NOT_FOUND' ); } const fileName = path.basename(filePath); const fileStream = fs.createReadStream(filePath); const fileStats = fs.statSync(filePath); logger.info(`Uploading media file: ${fileName}`, { size: fileStats.size, path: filePath }); // Create form data const formData = new FormData(); formData.append('file', fileStream, fileName); if (options.title) formData.append('title', options.title); if (options.alt_text) formData.append('alt_text', options.alt_text); if (options.caption) formData.append('caption', options.caption); if (options.description) formData.append('description', options.description); if (options.post) formData.append('post', options.post.toString()); // Upload to WordPress const response = await this.client.post('/media', formData, { headers: { ...formData.getHeaders(), }, maxBodyLength: Infinity, maxContentLength: Infinity, }); logger.info('Media uploaded successfully', { id: response.data.id, url: response.data.source_url }); return response.data; }, 'MediaService.uploadMedia'); } async updateMedia(id: number, data: Partial<MediaUploadOptions>): Promise<any> { return ErrorHandler.wrapAsync(async () => { logger.info(`Updating media item ${id}`); const response = await this.client.post(`/media/${id}`, data); logger.info('Media updated successfully', { id }); return response.data; }, 'MediaService.updateMedia'); } async deleteMedia(id: number, force: boolean = false): Promise<any> { return ErrorHandler.wrapAsync(async () => { logger.info(`Deleting media item ${id}`, { force }); const response = await this.client.delete(`/media/${id}`, { params: { force } }); logger.info('Media deleted successfully', { id }); return response.data; }, 'MediaService.deleteMedia'); } async getMediaByPost(postId: number): Promise<any> { return this.getMedia({ parent: postId }); } async searchMedia(searchTerm: string, params: Omit<MediaQueryParams, 'search'> = {}): Promise<any> { return this.getMedia({ ...params, search: searchTerm }); } }

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/mbrown1837/Ultimate-Elementor-MCP'

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