search_papers_by_keyword
Search academic papers using keywords to find relevant research publications. Filter results by publication year or citation count and browse through paginated results for efficient research discovery.
Instructions
Search academic papers by keyword
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | Yes | Search keyword | |
| order | No | Sort order: year (by publication year) or n_citation (by citation count) | |
| page | No | Page number, starting from 0 | |
| size | No | Number of papers per page, maximum 10 |
Implementation Reference
- src/index.ts:35-71 (registration)Registration of the 'search_papers_by_keyword' tool using server.registerTool, including schema and inline handler.server.registerTool( "search_papers_by_keyword", { title: "Search Papers by Keyword", description: "Search academic papers by keyword", inputSchema: { keyword: z.string().describe("Search keyword"), page: z.number().min(0).default(0).describe("Page number, starting from 0"), size: z.number().min(1).max(10).default(10).describe("Number of papers per page, maximum 10"), order: z.enum(["year", "n_citation"]).optional().describe("Sort order: year (by publication year) or n_citation (by citation count)") } }, async ({ keyword, page, size, order }) => { try { const result = await aminerClient.searchByKeyword(keyword, page, size, order); const formattedResult = aminerClient.formatSearchResults(result); return { content: [{ type: "text", text: JSON.stringify(formattedResult, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: "Search failed", message: error instanceof Error ? error.message : 'Unknown error' }, null, 2) }], isError: true }; } } );
- src/index.ts:47-70 (handler)The inline handler function for the tool that invokes AminerClient.searchByKeyword, formats results, and handles errors.async ({ keyword, page, size, order }) => { try { const result = await aminerClient.searchByKeyword(keyword, page, size, order); const formattedResult = aminerClient.formatSearchResults(result); return { content: [{ type: "text", text: JSON.stringify(formattedResult, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: JSON.stringify({ error: "Search failed", message: error instanceof Error ? error.message : 'Unknown error' }, null, 2) }], isError: true }; } }
- src/index.ts:37-46 (schema)Input schema definition using Zod for tool parameters: keyword, page, size, order.{ title: "Search Papers by Keyword", description: "Search academic papers by keyword", inputSchema: { keyword: z.string().describe("Search keyword"), page: z.number().min(0).default(0).describe("Page number, starting from 0"), size: z.number().min(1).max(10).default(10).describe("Number of papers per page, maximum 10"), order: z.enum(["year", "n_citation"]).optional().describe("Sort order: year (by publication year) or n_citation (by citation count)") } },
- src/aminer-client.ts:27-94 (helper)Core helper method searchPapers that performs the actual HTTP request to AMiner API and processes the response.async searchPapers(params: SearchParams): Promise<SearchResult> { // Validate required parameters if (!params.keyword && !params.venue && !params.author) { throw new Error('At least one of keyword, venue, or author must be provided'); } if (params.size > 10) { throw new Error('Size parameter cannot exceed 10'); } // Build query parameters const searchParams = new URLSearchParams(); if (params.keyword) searchParams.append('keyword', params.keyword); if (params.venue) searchParams.append('venue', params.venue); if (params.author) searchParams.append('author', params.author); searchParams.append('page', params.page.toString()); searchParams.append('size', params.size.toString()); if (params.order) searchParams.append('order', params.order); const url = `${this.config.baseUrl}?${searchParams.toString()}`; try { const response = await fetch(url, { method: 'GET', headers: { 'Authorization': this.config.apiKey, 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json() as AminerSearchResponse; // Add detailed response data check if (!data) { throw new Error('API returned empty response'); } if (!data.success) { throw new Error(`API Error (${data.code}): ${data.msg}`); } // Check the completeness of the response data if (typeof data.total !== 'number') { console.warn('API response missing or invalid total field, defaulting to 0'); } // Ensure data.data is not null, if it is null, use an empty array const papers = data.data || []; const total = data.total || 0; return { papers, total, page: params.page, size: params.size, hasMore: (params.page + 1) * params.size < total, }; } catch (error) { if (error instanceof Error) { throw new Error(`Failed to search papers: ${error.message}`); } throw new Error('Unknown error occurred while searching papers'); } }
- src/aminer-client.ts:99-101 (helper)Convenience method searchByKeyword that delegates to searchPapers, directly called by the tool handler.async searchByKeyword(keyword: string, page = 0, size = 10, order?: 'year' | 'n_citation'): Promise<SearchResult> { return this.searchPapers({ keyword, page, size, order }); }