Use the X Live Search MCP server from your ATXP-powered agent to search X (formerly Twitter) for posts and conversations using xAI’s Grok models. Powered by xAI’s Agentic Search Tools API, the server uses AI agents that autonomously explore and make follow-up queries to provide comprehensive search results with citations.
Searches X (formerly Twitter) for posts matching the query and optional filters using xAI’s Agentic Search Tools API. The AI agent autonomously explores and makes follow-up queries to provide comprehensive results with citations to source posts.
Array of tool calls made by the AI agent during search, showing what searches were performed. Each object contains function name and arguments. Only present when status is “success”.
Error details if the search failed. Only present when status is “error”.
x_live_search_async
Starts an asynchronous search of X (formerly Twitter) for posts matching the query and optional filters using xAI’s Agentic Search Tools API. Returns a task ID immediately that can be used to check status and retrieve results. This is useful for avoiding timeouts on long-running searches.
The search result object. Only present when status is “completed”. Contains the same fields as the x_live_search response (status, query, message, citations, toolCalls).
Create a reusable service configuration that points to the MCP server and standardizes how you pass arguments and read results. This lets your agent easily interact with the X Live Search tool in a consistent manner.
Create a client using an ATXP account by importing the ATXP client SDK and other dependencies.
// Import the ATXP client SDKimport { atxpClient, ATXPAccount } from '@atxp/client';// Read the ATXP account details from environment variablesconst atxpConnectionString = process.env.ATXP_CONNECTION;// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account: new ATXPAccount(atxpConnectionString),});
Create a client using a Base account by importing the ATXP client SDK and other dependencies.
// Import the ATXP client SDK and Base accountimport { atxpClient } from '@atxp/client';import { BaseAccount } from '@atxp/base';// Read the Base account details from the environment variablesconst baseRpcUrl = process.env.BASE_RPC_URL;const basePrivateKey = process.env.BASE_PRIVATE_KEY;// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account: new BaseAccount(baseRpcUrl, basePrivateKey),});
Create a client using a Solana account by importing the ATXP client SDK and other dependencies.
// Import the ATXP client SDK and Solana accountimport { atxpClient } from '@atxp/client';import { SolanaAccount } from '@atxp/solana';// Read the Solana account details from the environment variablesconst solanaRpcUrl = process.env.SOLANA_RPC_URL;const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY;// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account: new SolanaAccount(solanaRpcUrl, solanaPrivateKey),});
Create a client using a Worldchain account with MiniKit integration.
// Import the ATXP client SDK and Worldchain account creatorimport { atxpClient } from '@atxp/client';import { createMiniKitWorldchainAccount } from '@atxp/worldchain';import { MiniKit } from '@worldcoin/minikit-js';// Create a Worldchain account using MiniKitconst account = await createMiniKitWorldchainAccount({ walletAddress: '0x1234...', // User's wallet address miniKit: MiniKit});// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account,});
Browser applications:
// Import the ATXP client SDK and Polygon browser accountimport { atxpClient } from '@atxp/client';import { PolygonBrowserAccount } from '@atxp/polygon';// Initialize the Polygon browser account with wallet providerconst account = await PolygonBrowserAccount.initialize({ provider: window.ethereum, // or any EIP-1193 provider walletAddress: '0x1234...', // User's wallet address});// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account,});
Server/CLI applications:
// Import the ATXP client SDK and Polygon server accountimport { atxpClient } from '@atxp/client';import { PolygonServerAccount } from '@atxp/polygon';// Read the Polygon account details from the environment variablesconst polygonRpcUrl = process.env.POLYGON_RPC_URL;const polygonPrivateKey = process.env.POLYGON_PRIVATE_KEY;// Create a Polygon server accountconst account = new PolygonServerAccount( polygonRpcUrl, polygonPrivateKey, 137 // Chain ID: 137 = Polygon mainnet, 80002 = Amoy testnet);// Create a client using the `atxpClient` functionconst client = await atxpClient({ mcpServer: xLiveSearchService.mcpServer, account,});
3
Use the X Live Search service in your agent
Synchronous Search
Asynchronous Search
Call the X Live Search tool by passing your search query and optional filters as arguments.Read the response using the getResult method.
const searchParams = { query: "What are the latest updates from Stripe?", allowed_x_handles: ["stripe"], from_date: "2024-01-01", min_likes: 100 // Only show posts with at least 100 likes};try { const result = await client.callTool({ name: xLiveSearchService.toolName, arguments: xLiveSearchService.getArguments(searchParams), }); const { status, query, message, citations, toolCalls, errorMessage } = xLiveSearchService.getResult(result); if (status === 'success') { console.log('Query:', query); console.log('Summary:', message); console.log('Citations:', citations); console.log('Tool Calls:', toolCalls); // See what the agent did } else { console.error('Search failed:', errorMessage); }} catch (error) { console.error(`Error with ${xLiveSearchService.description}:`, error); process.exit(1);}
You should see the search summary and citations printed in your console.
For longer search tasks or to avoid timeouts, use the async tools to start the search and poll for completion.
const searchParams = { query: "What are the latest updates from Stripe?", allowed_x_handles: ["stripe"], from_date: "2024-01-01", min_likes: 100 // Only show posts with at least 100 likes};try { // Start async search const asyncResult = await client.callTool({ name: xLiveSearchService.asyncSearchToolName, arguments: xLiveSearchService.getArguments(searchParams), }); const { taskId } = xLiveSearchService.getAsyncCreateResult(asyncResult); console.log('Search started with task ID:', taskId); // Poll for completion let completed = false; while (!completed) { await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds const statusResult = await client.callTool({ name: xLiveSearchService.getSearchAsyncToolName, arguments: { taskId }, }); const { status, result, error } = xLiveSearchService.getAsyncStatusResult(statusResult); console.log('Status:', status); if (status === 'completed') { console.log('Query:', result.query); console.log('Summary:', result.message); console.log('Citations:', result.citations); console.log('Tool Calls:', result.toolCalls); // See what the agent did completed = true; } else if (status === 'error') { console.error('Search failed:', error); completed = true; } }} catch (error) { console.error(`Error with ${xLiveSearchService.description}:`, error); process.exit(1);}
You should see the task ID printed first, followed by status updates, and finally the search summary and citations when the search completes.