Skip to main content
Glama
social-media-tools.tsβ€’10.3 kB
/** * Social media management tools for Simplified API */ import { createTool } from '../definitions.js'; import type { ToolDefinition } from '../../types/index.js'; import { AppError, ErrorType } from '../../types/index.js'; /** * Get social media accounts tool */ export const getSocialMediaAccountsTool: ToolDefinition = createTool() .name('get_social_media_accounts') .description('Retrieve all connected social media accounts') .category('social-media') .version('1.0.0') .optionalString('network', 'Filter by specific social media platform', { enum: ['facebook', 'instagram', 'twitter', 'linkedin', 'tiktok', 'youtube', 'pinterest', 'threads', 'google', 'bluesky', 'tiktokBusiness'] }) .handler(async (params, apiClient) => { if (!apiClient) { throw new AppError( ErrorType.TOOL_ERROR, 'API client not available - server configuration error' ); } try { const queryParams: Record<string, any> = {}; if (params.network) queryParams.network = params.network; const response = await apiClient.get('/api/v1/service/social-media/get-accounts', queryParams); return { content: [ { type: 'text', text: JSON.stringify({ success: true, accounts: response.data.accounts || response.data, total: response.data.total || (Array.isArray(response.data) ? response.data.length : 1), filters: { network: params.network || 'all' } }, null, 2) } ] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Failed to retrieve social media accounts: ${errorMessage}` }, null, 2) } ] }; } }) .build(); /** * Create social media post tool */ export const createSocialMediaPostTool: ToolDefinition = createTool() .name('create_social_media_post') .description('Create a new social media post with platform-specific settings for Google, TikTok, Threads, YouTube, Facebook, LinkedIn, Instagram, and Pinterest') .category('social-media') .version('1.1.0') .requiredString('message', 'Post message/content', { minLength: 1, maxLength: 5000 }) .requiredString('accountId', 'Social media account ID', { minLength: 1, maxLength: 100 }) .requiredString('action', 'Action to perform with the post', { enum: ['schedule', 'add_to_queue', 'draft'] }) .optionalString('date', 'Scheduled date for the post (format: YYYY-MM-DD HH:MM)', { pattern: '^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$' }) .optionalArray('media', 'Media file URLs to attach to the post', { type: 'string', pattern: '^https?://.+' }, { maxItems: 10 }) .optionalObject('additional', 'Platform-specific post settings and metadata', { // Google Business Profile google: { type: 'object', properties: { post: { type: 'object', properties: { title: { type: 'string', maxLength: 300 }, topicType: { type: 'string', enum: ['STANDARD', 'EVENT', 'OFFER', 'PRODUCT'] }, couponCode: { type: 'string', maxLength: 50 }, callToActionUrl: { type: 'string', pattern: '^https?://.+' }, redeemOnlineUrl: { type: 'string', pattern: '^https?://.+' }, termsConditions: { type: 'string', maxLength: 1000 }, callToActionType: { type: 'string', enum: ['SIGN_UP', 'LEARN_MORE', 'BOOK', 'ORDER', 'SHOP', 'CALL', 'GET_OFFER'] } } } } }, // TikTok / TikTok Business tiktok: { type: 'object', properties: { post: { type: 'object', properties: { brandContent: { type: 'boolean' }, brandOrganic: { type: 'boolean' }, duetDisabled: { type: 'boolean' }, privacyStatus: { type: 'string', enum: ['PUBLIC_TO_EVERYONE', 'MUTUAL_FOLLOW_FRIEND', 'FOLLOWER_OF_CREATOR', 'SELF_ONLY'] }, stitchDisabled: { type: 'boolean' }, commentDisabled: { type: 'boolean' } } }, channel: { type: 'object', properties: { value: { type: 'string', enum: ['direct', 'business'] } } }, postType: { type: 'object', properties: { value: { type: 'string', enum: ['video', 'image'] } } }, postPhoto: { type: 'object', properties: { title: { type: 'string', maxLength: 150 }, brandContent: { type: 'boolean' }, brandOrganic: { type: 'boolean' }, duetDisabled: { type: 'boolean' }, privacyStatus: { type: 'string', enum: ['PUBLIC_TO_EVERYONE', 'MUTUAL_FOLLOW_FRIEND', 'FOLLOWER_OF_CREATOR', 'SELF_ONLY'] }, stitchDisabled: { type: 'boolean' }, commentDisabled: { type: 'boolean' } } } } }, // Threads threads: { type: 'object', properties: { channel: { type: 'object', properties: { value: { type: 'string', enum: ['direct'] } } } } }, // YouTube youtube: { type: 'object', properties: { post: { type: 'object', properties: { title: { type: 'string', maxLength: 100 }, license: { type: 'string', enum: ['standard', 'creativeCommon'] }, privacyStatus: { type: 'string', enum: ['public', 'private', 'unlisted'] }, selfDeclaredMadeForKids: { type: 'string', enum: ['yes', 'no'] } } }, postType: { type: 'object', properties: { value: { type: 'string', enum: ['short', 'video'] } } } } }, // Facebook facebook: { type: 'object', properties: { postType: { type: 'object', properties: { value: { type: 'string', enum: ['story', 'feed', 'reel'] } } } } }, // LinkedIn linkedin: { type: 'object', properties: { audience: { type: 'object', properties: { value: { type: 'string', enum: ['PUBLIC', 'CONNECTIONS', 'LOGGED_IN_MEMBERS'] } } } } }, // Instagram instagram: { type: 'object', properties: { postReel: { type: 'object', properties: { audioName: { type: 'string', maxLength: 100 }, shareToFeed: { type: 'boolean' } } }, postType: { type: 'object', properties: { value: { type: 'string', enum: ['post', 'reel', 'story'] } } } } }, // Pinterest pinterest: { type: 'object', properties: { post: { type: 'object', properties: { link: { type: 'string', pattern: '^https?://.+' }, title: { type: 'string', maxLength: 100 }, imageAlt: { type: 'string', maxLength: 500 } } } } }, // Legacy fields for backward compatibility hashtags: { type: 'array', items: { type: 'string', maxLength: 50 }, maxItems: 30 }, mentions: { type: 'array', items: { type: 'object', properties: { username: { type: 'string' }, displayName: { type: 'string' } }, required: ['username'] }, maxItems: 20 }, location: { type: 'string', maxLength: 100 }, settings: { type: 'object', properties: { enableComments: { type: 'boolean' }, enableSharing: { type: 'boolean' }, targetAudience: { type: 'string', enum: ['public', 'friends', 'custom'] } } } }) .handler(async (params, apiClient) => { if (!apiClient) { throw new AppError( ErrorType.TOOL_ERROR, 'API client not available - server configuration error' ); } try { // Format the date if provided let formattedDate = null; if (params.date) { formattedDate = params.date; } // Prepare the payload according to the API specification const postData = { action: params.action, message: params.message.trim(), account_ids: [params.accountId], date: formattedDate, media: params.media || [], additional: params.additional || {} }; // Always use the specified endpoint const response = await apiClient.post('/api/v1/service/social-media/create', postData); // Determine the action type for the response message const actionMessages = { schedule: 'scheduled', add_to_queue: 'added to queue', draft: 'saved as draft' }; const actionType = actionMessages[params.action as keyof typeof actionMessages] || 'processed'; return { content: [ { type: 'text', text: JSON.stringify({ success: true, message: `Social media post ${actionType} successfully`, post: response.data, action: params.action, accountId: params.accountId, scheduledDate: formattedDate }, null, 2) } ] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: `Failed to create social media post: ${errorMessage}` }, null, 2) } ] }; } }) .build(); /** * Export all social media tools */ export const socialMediaTools: ToolDefinition[] = [ getSocialMediaAccountsTool, createSocialMediaPostTool ];

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/celeryhq/simplified-mcp-server'

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