Skip to main content
Glama
crazyrabbitLTC

Twitter MCP Server

getHashtagAnalytics

Analyze Twitter hashtag performance by tracking metrics like engagement and reach within specified time periods to measure campaign effectiveness.

Instructions

Get analytics for a specific hashtag

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
hashtagYesThe hashtag to analyze (with or without #)
startTimeNoStart time for the analysis (ISO 8601)
endTimeNoEnd time for the analysis (ISO 8601)

Implementation Reference

  • The core handler function for 'getHashtagAnalytics' that searches for tweets containing the specified hashtag (optionally within a time range), computes aggregate analytics (total tweets, likes, retweets, replies), and returns formatted results. Handles errors including API tier requirements.
    export const handleHashtagAnalytics: TwitterHandler<HashtagAnalyticsArgs> = async ( client: TwitterClient | null, { hashtag, startTime, endTime }: HashtagAnalyticsArgs ): Promise<HandlerResponse> => { if (!client) { return createMissingTwitterApiKeyResponse('hashtagAnalytics'); } try { const query = `#${hashtag.replace(/^#/, '')}`; const searchResult = await client.v2.search(query, { max_results: 100, 'tweet.fields': 'public_metrics,created_at', start_time: startTime, end_time: endTime }); const tweets = Array.isArray(searchResult.data) ? searchResult.data : []; if (tweets.length === 0) { return createResponse(`No tweets found for hashtag: ${hashtag}`); } const analytics = { totalTweets: tweets.length, totalLikes: tweets.reduce((sum: number, tweet: TweetV2) => sum + (tweet.public_metrics?.like_count || 0), 0), totalRetweets: tweets.reduce((sum: number, tweet: TweetV2) => sum + (tweet.public_metrics?.retweet_count || 0), 0), totalReplies: tweets.reduce((sum: number, tweet: TweetV2) => sum + (tweet.public_metrics?.reply_count || 0), 0) }; return createResponse(`Hashtag Analytics for ${hashtag}:\n${JSON.stringify(analytics, null, 2)}`); } catch (error) { if (error instanceof Error) { if (error.message.includes('400') && error.message.includes('Invalid Request')) { throw new Error(`Hashtag analytics requires Pro tier access ($5,000/month) or higher for search functionality. Current Basic tier ($200/month) does not include recent search API access. Consider upgrading at https://developer.x.com/en/portal/products/pro or use alternative analytics sources.`); } throw new Error(formatTwitterError(error, 'getting hashtag analytics')); } throw error; } };
  • Tool schema definition including description and input schema (hashtag required, startTime/endTime optional ISO 8601 strings) used for MCP tool listing and validation.
    getHashtagAnalytics: { description: 'Get analytics for a specific hashtag', inputSchema: { type: 'object', properties: { hashtag: { type: 'string', description: 'The hashtag to analyze (with or without #)' }, startTime: { type: 'string', description: 'Start time for the analysis (ISO 8601)' }, endTime: { type: 'string', description: 'End time for the analysis (ISO 8601)' } }, required: ['hashtag'] } },
  • src/index.ts:318-326 (registration)
    Switch case in the main CallToolRequestHandler that registers and dispatches 'getHashtagAnalytics' calls to the handleHashtagAnalytics function.
    case 'getHashtagAnalytics': { const { hashtag, startTime, endTime } = request.params.arguments as { hashtag: string; startTime?: string; endTime?: string; }; response = await handleHashtagAnalytics(client, { hashtag, startTime, endTime }); break; }
  • TypeScript interface defining input arguments for getHashtagAnalytics (note: slightly differs from runtime schema; possibly legacy or additional).
    export interface GetHashtagAnalyticsArgs { hashtag: string; maxResults?: number; tweetFields?: string[]; }
  • Runtime type assertion function for validating getHashtagAnalytics arguments.
    export function assertGetHashtagAnalyticsArgs(args: unknown): asserts args is GetHashtagAnalyticsArgs { if (typeof args !== 'object' || args === null) { throw new Error('Invalid arguments: expected object'); } if (!('hashtag' in args) || typeof (args as any).hashtag !== 'string') { throw new Error('Invalid arguments: expected hashtag string'); } if ('maxResults' in args) { const maxResults = (args as any).maxResults; if (typeof maxResults !== 'number' || maxResults < 10 || maxResults > 100) { throw new Error('Invalid arguments: maxResults must be a number between 10 and 100'); } } if ('tweetFields' in args) { if (!Array.isArray((args as any).tweetFields)) { throw new Error('Invalid arguments: expected tweetFields to be an array'); } for (const field of (args as any).tweetFields) { if (typeof field !== 'string') { throw new Error('Invalid arguments: expected tweetFields to be an array of strings'); } } } }

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/crazyrabbitLTC/mcp-twitter-server'

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