search_papers_advanced
Search academic papers using keywords, authors, venues, and filter by publication year or citation count to find relevant research.
Instructions
Advanced paper search functionality supporting multiple search criteria
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| author | No | Author name | |
| keyword | No | 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 | |
| venue | No | Venue/journal name |
Implementation Reference
- src/index.ts:166-211 (handler)Inline handler function for the search_papers_advanced tool. Validates inputs, calls AminerClient.searchPapers and formatSearchResults, handles errors, and returns formatted JSON results.async ({ keyword, venue, author, page, size, order }) => { try { // Validate at least one search condition is provided if (!keyword && !venue && !author) { return { content: [{ type: "text", text: JSON.stringify({ error: "Validation Error", message: "At least one of keyword, venue, or author must be provided" }, null, 2) }], isError: true }; } const result = await aminerClient.searchPapers({ keyword, venue, author, 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:154-164 (schema)Tool schema definition including title, description, and Zod input schema for parameters: keyword, venue, author, page, size, order.{ title: "Advanced Paper Search", description: "Advanced paper search functionality supporting multiple search criteria", inputSchema: { keyword: z.string().optional().describe("Search keyword"), venue: z.string().optional().describe("Venue/journal name"), author: z.string().optional().describe("Author name"), 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/index.ts:152-212 (registration)Registers the search_papers_advanced tool with the MCP server using server.registerTool, providing schema and handler.server.registerTool( "search_papers_advanced", { title: "Advanced Paper Search", description: "Advanced paper search functionality supporting multiple search criteria", inputSchema: { keyword: z.string().optional().describe("Search keyword"), venue: z.string().optional().describe("Venue/journal name"), author: z.string().optional().describe("Author name"), 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, venue, author, page, size, order }) => { try { // Validate at least one search condition is provided if (!keyword && !venue && !author) { return { content: [{ type: "text", text: JSON.stringify({ error: "Validation Error", message: "At least one of keyword, venue, or author must be provided" }, null, 2) }], isError: true }; } const result = await aminerClient.searchPapers({ keyword, venue, author, 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/aminer-client.ts:27-94 (helper)Core helper method in AminerClient that performs the actual API request to AMiner with advanced search parameters, handles response parsing and validation.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:165-198 (helper)Helper method that formats raw search results from API into structured, user-friendly JSON with paper details, summary, and pagination information.formatSearchResults(result: SearchResult): SearchResultFormatted { const { papers, total, page, size, hasMore } = result; // Ensure papers is not null or undefined const formattedPapers = papers && Array.isArray(papers) ? papers.map((paper, index) => { const formattedPaper = this.formatPaper(paper); // Only process successfully formatted papers, skip error results if ('error' in formattedPaper) { return null; } return { index: page * size + index + 1, ...formattedPaper }; }).filter((paper): paper is NonNullable<typeof paper> => paper !== null) : []; return { summary: { total, page: page + 1, size, hasMore, currentPageResults: formattedPapers.length }, papers: formattedPapers, pagination: { currentPage: page + 1, nextPage: hasMore ? page + 2 : null, previousPage: page > 0 ? page : null } }; }