getAINews
Search AI-related crypto and Web3 news by filtering with categories, blockchains, tokens, keywords, and date range.
Instructions
Fetch the latest AI-related crypto and Web3 news with optional filtering by categories, blockchains, tokens, keywords, and date range
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "getAINews"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| categories | No | Categories to filter by (e.g., ['defi', 'nft', 'gaming', 'dao', 'metaverse']) | |
| blockchains | No | Blockchains/networks to filter by (e.g., ['ethereum', 'bitcoin', 'solana', 'polygon']) | |
| tokens | No | Tokens/cryptocurrencies to filter by (e.g., ['bitcoin', 'ethereum', 'usdt', 'bnb']) | |
| searchQuery | No | Keyword or phrase to search for in news titles and descriptions | |
| fetchAfter | No | Only return news published after this date (ISO 8601 format, e.g., '2024-01-01T00:00:00Z') | |
| limit | No | Number of news articles to return (default: 10) | |
| offset | No | Number of items to skip for pagination (default: 0) |
Implementation Reference
- index.js:197-316 (registration)The tool is registered with the MCP server using server.tool(), defining its name, description, schema, and handler.
server.tool( "getAINews", "Fetch the latest AI-related crypto and Web3 news with optional filtering by categories, blockchains, tokens, keywords, and date range", { categories: z.array(z.string()).optional().describe("Categories to filter by (e.g., ['defi', 'nft', 'gaming', 'dao', 'metaverse'])"), blockchains: z.array(z.string()).optional().describe("Blockchains/networks to filter by (e.g., ['ethereum', 'bitcoin', 'solana', 'polygon'])"), tokens: z.array(z.string()).optional().describe("Tokens/cryptocurrencies to filter by (e.g., ['bitcoin', 'ethereum', 'usdt', 'bnb'])"), searchQuery: z.string().optional().describe("Keyword or phrase to search for in news titles and descriptions"), fetchAfter: z.string().optional().describe("Only return news published after this date (ISO 8601 format, e.g., '2024-01-01T00:00:00Z')"), limit: z.number().default(10).describe("Number of news articles to return (default: 10)"), offset: z.number().default(0).describe("Number of items to skip for pagination (default: 0)") }, async ({ categories, blockchains, tokens, searchQuery, fetchAfter, limit = 10, offset = 0 }) => { try { const apiKey = process.env.CHAINGPT_API_KEY; if (!apiKey) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: "ChainGPT API key not found. Please set the CHAINGPT_API_KEY environment variable.", suggestion: "Add CHAINGPT_API_KEY=your_api_key to your environment variables" }, null, 2) }] }; } const client = initializeClient(apiKey); const categoryIds = parseTermsToIds(categories, CATEGORY_MAPPINGS); const subCategoryIds = parseTermsToIds(blockchains, SUBCATEGORY_MAPPINGS); const tokenIds = parseTermsToIds(tokens, TOKEN_MAPPINGS); const requestParams = { limit, offset, sortBy: 'createdAt' }; if (categoryIds.length > 0) { requestParams.categoryId = categoryIds; } if (subCategoryIds.length > 0) { requestParams.subCategoryId = subCategoryIds; } if (tokenIds.length > 0) { requestParams.tokenId = tokenIds; } if (searchQuery) { requestParams.searchQuery = searchQuery; } if (fetchAfter) { try { requestParams.fetchAfter = new Date(fetchAfter); } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: "Invalid date format for fetchAfter. Please use ISO 8601 format (e.g., '2024-01-01T00:00:00Z')", providedDate: fetchAfter }, null, 2) }] }; } } const response = await client.getNews(requestParams); const result = { status: "success", metadata: { totalResults: response.data.length, limit, offset, appliedFilters: { categories: categories || [], blockchains: blockchains || [], tokens: tokens || [], searchQuery: searchQuery || null, fetchAfter: fetchAfter || null, mappedIds: { categoryIds, subCategoryIds, tokenIds } }, timestamp: new Date().toISOString() }, data: response.data }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: `Failed to fetch AI news: ${error.message}`, errorType: error.constructor.name, timestamp: new Date().toISOString() }, null, 2) }] }; } } ); - index.js:200-208 (schema)Zod schema defining the input parameters for the getAINews tool.
{ categories: z.array(z.string()).optional().describe("Categories to filter by (e.g., ['defi', 'nft', 'gaming', 'dao', 'metaverse'])"), blockchains: z.array(z.string()).optional().describe("Blockchains/networks to filter by (e.g., ['ethereum', 'bitcoin', 'solana', 'polygon'])"), tokens: z.array(z.string()).optional().describe("Tokens/cryptocurrencies to filter by (e.g., ['bitcoin', 'ethereum', 'usdt', 'bnb'])"), searchQuery: z.string().optional().describe("Keyword or phrase to search for in news titles and descriptions"), fetchAfter: z.string().optional().describe("Only return news published after this date (ISO 8601 format, e.g., '2024-01-01T00:00:00Z')"), limit: z.number().default(10).describe("Number of news articles to return (default: 10)"), offset: z.number().default(0).describe("Number of items to skip for pagination (default: 0)") }, - index.js:209-315 (handler)The handler function that executes the tool logic: validates API key, maps terms to IDs, calls the ChainGPT AI News API, and returns formatted results.
async ({ categories, blockchains, tokens, searchQuery, fetchAfter, limit = 10, offset = 0 }) => { try { const apiKey = process.env.CHAINGPT_API_KEY; if (!apiKey) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: "ChainGPT API key not found. Please set the CHAINGPT_API_KEY environment variable.", suggestion: "Add CHAINGPT_API_KEY=your_api_key to your environment variables" }, null, 2) }] }; } const client = initializeClient(apiKey); const categoryIds = parseTermsToIds(categories, CATEGORY_MAPPINGS); const subCategoryIds = parseTermsToIds(blockchains, SUBCATEGORY_MAPPINGS); const tokenIds = parseTermsToIds(tokens, TOKEN_MAPPINGS); const requestParams = { limit, offset, sortBy: 'createdAt' }; if (categoryIds.length > 0) { requestParams.categoryId = categoryIds; } if (subCategoryIds.length > 0) { requestParams.subCategoryId = subCategoryIds; } if (tokenIds.length > 0) { requestParams.tokenId = tokenIds; } if (searchQuery) { requestParams.searchQuery = searchQuery; } if (fetchAfter) { try { requestParams.fetchAfter = new Date(fetchAfter); } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: "Invalid date format for fetchAfter. Please use ISO 8601 format (e.g., '2024-01-01T00:00:00Z')", providedDate: fetchAfter }, null, 2) }] }; } } const response = await client.getNews(requestParams); const result = { status: "success", metadata: { totalResults: response.data.length, limit, offset, appliedFilters: { categories: categories || [], blockchains: blockchains || [], tokens: tokens || [], searchQuery: searchQuery || null, fetchAfter: fetchAfter || null, mappedIds: { categoryIds, subCategoryIds, tokenIds } }, timestamp: new Date().toISOString() }, data: response.data }; return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", message: `Failed to fetch AI news: ${error.message}`, errorType: error.constructor.name, timestamp: new Date().toISOString() }, null, 2) }] }; } } - index.js:167-179 (helper)Helper function to convert human-readable category/blockchain/token names to their numeric IDs using the mapping objects.
function parseTermsToIds(terms, mappingObject) { if (!terms || !Array.isArray(terms)) return []; const ids = []; for (const term of terms) { const normalizedTerm = term.toLowerCase().trim(); const id = mappingObject[normalizedTerm]; if (id !== undefined) { ids.push(id); } } return [...new Set(ids)]; } - index.js:183-188 (helper)Helper function that lazily initializes the AINews client singleton with the provided API key.
function initializeClient(apiKey) { if (!aiNewsClient) { aiNewsClient = new AINews({ apiKey }); } return aiNewsClient; }