search
Search for tokens, pools, and DEXes across all blockchain networks using names, symbols, or addresses to identify assets when the specific network is unknown.
Instructions
Search across ALL networks for tokens, pools, and DEXes by name, symbol, or address. Good starting point when you don't know the specific network.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search term (e.g., "uniswap", "bitcoin", or a token address) |
Implementation Reference
- src/index.js:245-252 (handler)The handler function for the 'search' tool. Validates the query input, sanitizes it, fetches search results from the DexPaprika API /search endpoint, and formats the response using formatMcpResponse.async ({ query }) => { if (!query.trim()) { throw new Error('Search query cannot be empty'); } const sanitizedQuery = encodeURIComponent(query.trim()); const data = await fetchFromAPI(`/search?query=${sanitizedQuery}`); return formatMcpResponse(data); }
- src/index.js:242-244 (schema)Input schema for the 'search' tool defined using Zod: requires a 'query' string parameter.{ query: z.string().describe('Search term (e.g., "uniswap", "bitcoin", or a token address)') },
- src/index.js:239-253 (registration)Registration of the 'search' MCP tool on the server, including name, description, schema, and handler function.server.tool( 'search', 'Search across ALL networks for tokens, pools, and DEXes by name, symbol, or address. Good starting point when you don\'t know the specific network.', { query: z.string().describe('Search term (e.g., "uniswap", "bitcoin", or a token address)') }, async ({ query }) => { if (!query.trim()) { throw new Error('Search query cannot be empty'); } const sanitizedQuery = encodeURIComponent(query.trim()); const data = await fetchFromAPI(`/search?query=${sanitizedQuery}`); return formatMcpResponse(data); } );
- src/index.js:10-34 (helper)fetchFromAPI helper function used by the search handler to make API requests to DexPaprika, handles errors like 410 (deprecated endpoint) and 429 (rate limit).async function fetchFromAPI(endpoint) { try { const response = await fetch(`${API_BASE_URL}${endpoint}`); if (!response.ok) { if (response.status === 410) { throw new Error( 'This endpoint has been permanently removed. Please use network-specific endpoints instead. ' + 'For example, use /networks/{network}/pools instead of /pools. ' + 'Get available networks first using the getNetworks function.' ); } if (response.status === 429) { throw new Error( 'Rate limit exceeded. You have reached the maximum number of requests allowed for the free tier. ' + 'To increase your rate limits and access additional features, please consider upgrading to a paid plan at https://docs.dexpaprika.com/' ); } throw new Error(`API request failed with status ${response.status}`); } return await response.json(); } catch (error) { console.error(`Error fetching from API: ${error.message}`); throw error; } }
- src/index.js:37-46 (helper)formatMcpResponse helper function used by the search handler to format API data into MCP-compatible response structure.function formatMcpResponse(data) { return { content: [ { type: "text", text: JSON.stringify(data) } ] }; }