Skip to main content
Glama

searchTwitter

Search Twitter for Ethereum-related discussions by query, filter results by engagement metrics, date range, and language to analyze community sentiment and trends.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
sectionNolatest
limitNo
min_retweetsNo
min_likesNo
min_repliesNo
start_dateNo
end_dateNo
languageNo

Implementation Reference

  • Main execution logic for the searchTwitter tool: query preprocessing, API call via performTwitterSearch, error handling, and result formatting.
    async ({ query, section, limit, min_retweets, min_likes, min_replies, start_date, end_date, language }) => { try { // ENHANCEMENT: Pre-analyze the query to determine if it needs formatting let formattedQuery = query; // Determine if query appears to be in natural language vs. Twitter syntax const isNaturalLanguageQuery = !query.includes('(') && !query.includes(':') && !query.includes('-') && !query.includes('"') && !query.startsWith('@'); if (isNaturalLanguageQuery) { // This appears to be a natural language query, try to extract intent // Check for user mentions that should be converted to from: syntax if (query.toLowerCase().includes('from user') || query.toLowerCase().includes('by user')) { const userMatch = query.match(/from user\s+(\w+)/i) || query.match(/by user\s+(\w+)/i) || query.match(/from\s+@?(\w+)/i) || query.match(/by\s+@?(\w+)/i); if (userMatch && userMatch[1]) { const username = userMatch[1]; // Remove the matched part from the query and add proper Twitter syntax formattedQuery = query.replace(/from user\s+\w+/i, '') .replace(/by user\s+\w+/i, '') .replace(/from\s+@?\w+/i, '') .replace(/by\s+@?\w+/i, ''); // Add the proper Twitter syntax formattedQuery = `(from:${username}) ${formattedQuery.trim()}`; } } } else { // Already has some Twitter syntax, just do simple formatting // Format query if it's not already formatted with parentheses if (query.startsWith('@') && !query.includes('(')) { formattedQuery = `(from:${query.substring(1)})`; } } console.error(`Original query: "${query}"`); console.error(`Formatted query: "${formattedQuery}"`); // Use the shared search function with the formatted query const tweets = await performTwitterSearch( formattedQuery, section, limit, min_retweets, min_likes, min_replies, start_date, end_date, language ); // Format the response return { content: [{ type: "text", text: formatTwitterResults(formattedQuery, tweets, section) }] }; } catch (error) { console.error('Error searching Twitter:', error); return { content: [{ type: "text", text: `Error searching Twitter: ${error.message}` }] }; } }
  • Zod input schema defining parameters for the searchTwitter tool.
    query: z.string().min(1, "Search query is required"), section: z.enum(["latest", "top"]).optional().default("latest"), limit: z.number().int().positive().optional().default(10), min_retweets: z.number().int().optional(), min_likes: z.number().int().optional(), min_replies: z.number().int().optional(), start_date: z.string().optional(), end_date: z.string().optional(), language: z.string().optional() },
  • Registration of the searchTwitter tool using server.tool() with inline schema and handler.
    // Add Twitter search tool with built-in guide consultation server.tool("searchTwitter", { query: z.string().min(1, "Search query is required"), section: z.enum(["latest", "top"]).optional().default("latest"), limit: z.number().int().positive().optional().default(10), min_retweets: z.number().int().optional(), min_likes: z.number().int().optional(), min_replies: z.number().int().optional(), start_date: z.string().optional(), end_date: z.string().optional(), language: z.string().optional() }, async ({ query, section, limit, min_retweets, min_likes, min_replies, start_date, end_date, language }) => { try { // ENHANCEMENT: Pre-analyze the query to determine if it needs formatting let formattedQuery = query; // Determine if query appears to be in natural language vs. Twitter syntax const isNaturalLanguageQuery = !query.includes('(') && !query.includes(':') && !query.includes('-') && !query.includes('"') && !query.startsWith('@'); if (isNaturalLanguageQuery) { // This appears to be a natural language query, try to extract intent // Check for user mentions that should be converted to from: syntax if (query.toLowerCase().includes('from user') || query.toLowerCase().includes('by user')) { const userMatch = query.match(/from user\s+(\w+)/i) || query.match(/by user\s+(\w+)/i) || query.match(/from\s+@?(\w+)/i) || query.match(/by\s+@?(\w+)/i); if (userMatch && userMatch[1]) { const username = userMatch[1]; // Remove the matched part from the query and add proper Twitter syntax formattedQuery = query.replace(/from user\s+\w+/i, '') .replace(/by user\s+\w+/i, '') .replace(/from\s+@?\w+/i, '') .replace(/by\s+@?\w+/i, ''); // Add the proper Twitter syntax formattedQuery = `(from:${username}) ${formattedQuery.trim()}`; } } } else { // Already has some Twitter syntax, just do simple formatting // Format query if it's not already formatted with parentheses if (query.startsWith('@') && !query.includes('(')) { formattedQuery = `(from:${query.substring(1)})`; } } console.error(`Original query: "${query}"`); console.error(`Formatted query: "${formattedQuery}"`); // Use the shared search function with the formatted query const tweets = await performTwitterSearch( formattedQuery, section, limit, min_retweets, min_likes, min_replies, start_date, end_date, language ); // Format the response return { content: [{ type: "text", text: formatTwitterResults(formattedQuery, tweets, section) }] }; } catch (error) { console.error('Error searching Twitter:', error); return { content: [{ type: "text", text: `Error searching Twitter: ${error.message}` }] }; } } );
  • Helper function that performs the actual Twitter search API call using RapidAPI.
    const performTwitterSearch = async (query, section, limit, min_retweets, min_likes, min_replies, start_date, end_date, language) => { // Check for API key if (!RAPIDAPI_KEY) { throw new Error("RAPIDAPI_KEY environment variable is not set"); } // Build the query parameters const params = new URLSearchParams({ query: query, section: section, limit: limit.toString() }); // Add optional parameters if provided if (min_retweets) params.append('min_retweets', min_retweets.toString()); if (min_likes) params.append('min_likes', min_likes.toString()); if (min_replies) params.append('min_replies', min_replies.toString()); if (start_date) params.append('start_date', start_date); if (end_date) params.append('end_date', end_date); if (language) params.append('language', language); // Make the API request const response = await axios({ method: 'GET', url: `https://twitter154.p.rapidapi.com/search/search?${params.toString()}`, headers: { 'x-rapidapi-key': RAPIDAPI_KEY, 'x-rapidapi-host': RAPIDAPI_HOST } }); // Process the response return response.data.results || []; };
  • Helper function to format Twitter search results into a readable text output.
    function formatTwitterResults(query, tweets, section) { if (!tweets || tweets.length === 0) { return `No tweets found for query: ${query}`; } let output = []; output.push(`=== Twitter Search Results ===`); output.push(`Query: ${query}`); output.push(`Section: ${section}`); output.push(`Found ${tweets.length} tweets\n`); tweets.forEach((tweet, index) => { output.push(`[${index + 1}] @${tweet.user.username} (${tweet.user.name})`); output.push(`${tweet.text}`); output.push(`❤️ ${tweet.favorite_count || 0} | 🔄 ${tweet.retweet_count || 0} | 💬 ${tweet.reply_count || 0}`); output.push(`Posted: ${new Date(tweet.creation_date).toLocaleString()}`); if (tweet.media_url && tweet.media_url.length > 0) { output.push(`Media: ${tweet.media_url.join(', ')}`); } output.push(`URL: https://twitter.com/${tweet.user.username}/status/${tweet.tweet_id}`); output.push(``); }); return output.join('\n'); }

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/0xGval/evm-mcp-tools'

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