Skip to main content
Glama
researchPaperSearch.ts3.93 kB
import { z } from "zod"; import axios from "axios"; import { toolRegistry, API_CONFIG } from "./config.js"; import { ExaSearchRequest, ExaSearchResponse } from "../types.js"; import { createRequestLogger } from "../utils/logger.js"; // Register the research paper search tool toolRegistry["research_paper_search"] = { name: "research_paper_search", description: "Search across 100M+ research papers with full text access using Exa AI - performs targeted academic paper searches with deep research content coverage. Returns detailed information about relevant academic papers including titles, authors, publication dates, and full text excerpts. Control the number of results and character counts returned to balance comprehensiveness with conciseness based on your task requirements.", schema: { query: z.string().describe("Research topic or keyword to search for"), numResults: z.number().optional().describe("Number of research papers to return (default: 5)"), maxCharacters: z.number().optional().describe("Maximum number of characters to return for each result's text content (Default: 3000)") }, handler: async ({ query, numResults, maxCharacters }, extra) => { const requestId = `research_paper-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`; const logger = createRequestLogger(requestId, 'research_paper_search'); logger.start(query); try { // Create a fresh axios instance for each request const axiosInstance = axios.create({ baseURL: API_CONFIG.BASE_URL, headers: { 'accept': 'application/json', 'content-type': 'application/json', 'x-api-key': process.env.EXA_API_KEY || '' }, timeout: 25000 }); const searchRequest: ExaSearchRequest = { query, category: "research paper", type: "auto", numResults: numResults || API_CONFIG.DEFAULT_NUM_RESULTS, contents: { text: { maxCharacters: maxCharacters || API_CONFIG.DEFAULT_MAX_CHARACTERS }, livecrawl: 'fallback' } }; logger.log("Sending research paper request to Exa API"); const response = await axiosInstance.post<ExaSearchResponse>( API_CONFIG.ENDPOINTS.SEARCH, searchRequest, { timeout: 25000 } ); logger.log("Received research paper response from Exa API"); if (!response.data || !response.data.results) { logger.log("Warning: Empty or invalid response from Exa API for research papers"); return { content: [{ type: "text" as const, text: "No research papers found. Please try a different query." }] }; } logger.log(`Found ${response.data.results.length} research papers`); const result = { content: [{ type: "text" as const, text: JSON.stringify(response.data, null, 2) }] }; logger.complete(); return result; } catch (error) { logger.error(error); if (axios.isAxiosError(error)) { // Handle Axios errors specifically const statusCode = error.response?.status || 'unknown'; const errorMessage = error.response?.data?.message || error.message; logger.log(`Axios error (${statusCode}): ${errorMessage}`); return { content: [{ type: "text" as const, text: `Research paper search error (${statusCode}): ${errorMessage}` }], isError: true, }; } // Handle generic errors return { content: [{ type: "text" as const, text: `Research paper search error: ${error instanceof Error ? error.message : String(error)}` }], isError: true, }; } }, enabled: false // disabled by default };

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/jackedelic/exa-mcp-server'

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