paper-search-mcp-nodejs
Version:
A Node.js MCP server for searching and downloading academic papers from multiple sources, including arXiv, PubMed, bioRxiv, Web of Science, and more.
124 lines • 3.38 kB
JavaScript
/**
* 学术论文搜索平台的抽象基类
* 定义了所有平台搜索器必须实现的核心接口
*/
/**
* 抽象基类:论文搜索平台
*/
export class PaperSource {
baseUrl;
apiKey;
platformName;
constructor(platformName, baseUrl, apiKey) {
this.platformName = platformName;
this.baseUrl = baseUrl;
this.apiKey = apiKey;
}
/**
* 根据DOI获取论文信息
* @param doi DOI标识符
* @returns Promise<Paper | null> 论文信息或null
*/
async getPaperByDoi(doi) {
try {
const results = await this.search(doi, { maxResults: 1 });
return results.length > 0 ? results[0] : null;
}
catch (error) {
console.error(`Error getting paper by DOI from ${this.platformName}:`, error);
return null;
}
}
/**
* 验证API密钥是否有效
* @returns Promise<boolean> 是否有效
*/
async validateApiKey() {
if (!this.getCapabilities().requiresApiKey) {
return true;
}
if (!this.apiKey) {
return false;
}
try {
// 尝试一个简单的搜索来验证密钥
await this.search('test', { maxResults: 1 });
return true;
}
catch (error) {
return false;
}
}
/**
* 获取平台名称
*/
getPlatformName() {
return this.platformName;
}
/**
* 获取基础URL
*/
getBaseUrl() {
return this.baseUrl;
}
/**
* 是否配置了API密钥
*/
hasApiKey() {
return !!this.apiKey;
}
/**
* 通用的HTTP请求错误处理
*/
handleHttpError(error, operation) {
const message = error.response?.data?.message || error.message || 'Unknown error';
const status = error.response?.status;
const url = error.config?.url;
const method = error.config?.method?.toUpperCase();
// 详细错误信息用于调试
console.error(`❌ ${this.platformName} ${operation} Error Details:`, {
status,
message,
url,
method,
responseData: error.response?.data,
requestConfig: {
params: error.config?.params,
headers: error.config?.headers
}
});
throw new Error(`${this.platformName} ${operation} failed${status ? ` (${status})` : ''}: ${message}. URL: ${method} ${url}`);
}
/**
* 通用的日期解析
*/
parseDate(dateString) {
if (!dateString)
return null;
const date = new Date(dateString);
return isNaN(date.getTime()) ? null : date;
}
/**
* 清理和规范化文本
*/
cleanText(text) {
if (!text)
return '';
return text
.replace(/\s+/g, ' ')
.replace(/\n+/g, ' ')
.trim();
}
/**
* 从URL中提取文件名
*/
extractFilename(url, paperId, extension = 'pdf') {
const urlParts = url.split('/');
const lastPart = urlParts[urlParts.length - 1];
if (lastPart && lastPart.includes('.')) {
return lastPart;
}
return `${paperId}.${extension}`;
}
}
//# sourceMappingURL=PaperSource.js.map