Skip to main content
Glama

searchTwitter

Search and filter Twitter data by query, section, engagement metrics, date range, and language to analyze Ethereum-related discussions and trends.

Input Schema

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

Implementation Reference

  • The async handler function for the searchTwitter tool. It processes the input query (including natural language to Twitter syntax conversion), calls the Twitter API via RapidAPI using performTwitterSearch, handles errors, and formats results using formatTwitterResults.
    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 searchTwitter: query (required string), section (latest/top), limit, min_retweets/likes/replies, date ranges, language.
    { 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() },
  • Registers the searchTwitter tool on the MCP server using server.tool(), providing name, schema, and handler.
    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}` }] }; } } );
  • main.js:65-65 (registration)
    Invokes registerTwitterTools(server) to register all Twitter tools including searchTwitter on the main MCP server.
    registerTwitterTools(server);
  • Reusable helper function performTwitterSearch that makes the actual RapidAPI request to Twitter search endpoint.
    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 || []; };

Other Tools

Related Tools

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