Skip to main content
Glama
crazyrabbitLTC

Twitter MCP Server

getHashtagAnalytics

Analyze Twitter hashtag performance by extracting engagement metrics and trends within a specified time range using the Twitter MCP Server. Gain insights into hashtag usage and impact.

Instructions

Get analytics for a specific hashtag

Input Schema

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

Implementation Reference

  • Core handler implementation: Searches for recent tweets using the hashtag query via Twitter API v2, aggregates metrics (total tweets, likes, retweets, replies) from up to 100 tweets, handles errors including 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 in the TOOLS object, defining input validation schema, description, and parameters (hashtag required, optional start/end times). Used for MCP tool registration.
    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-325 (registration)
    Tool dispatcher/registration in main server request handler switch statement, extracts arguments and calls the specific handler 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;
  • Type assertion/validator function for input arguments, ensuring correct types though interface slightly differs from schema.
    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'); } } } }
  • TypeScript interface defining expected arguments (note: local handler uses startTime/endTime instead).
    export interface GetHashtagAnalyticsArgs { hashtag: string; maxResults?: number; tweetFields?: string[]; }

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