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.
106 lines • 3.46 kB
JavaScript
/**
* Paper Search MCP Server - Node.js Implementation
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { ListToolsRequestSchema, CallToolRequestSchema, InitializeRequestSchema, PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import * as dotenv from 'dotenv';
import { TOOLS } from './mcp/tools.js';
import { initializeSearchers } from './mcp/searchers.js';
import { handleToolCall } from './mcp/handleToolCall.js';
import { isMCPMode, logDebug } from './utils/Logger.js';
dotenv.config();
const server = new Server({
name: 'paper-search-mcp-nodejs',
version: '0.2.5'
}, {
capabilities: {
tools: {
listChanged: true
}
}
});
server.setRequestHandler(InitializeRequestSchema, async (request) => {
logDebug('Received initialize request:', request.params);
return {
protocolVersion: '2024-11-05',
capabilities: {
tools: {
listChanged: true
}
},
serverInfo: {
name: 'paper-search-mcp-nodejs',
version: '0.2.5'
}
};
});
server.setRequestHandler(PingRequestSchema, async () => {
logDebug('Received ping request');
return {};
});
server.setRequestHandler(ListToolsRequestSchema, async () => {
logDebug('Received tools/list request');
return { tools: TOOLS };
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
logDebug(`Received tools/call request: ${name}`);
try {
const currentSearchers = initializeSearchers();
return await handleToolCall(name, args, currentSearchers);
}
catch (error) {
logDebug(`Error in tool ${name}:`, error);
return {
content: [
{
type: 'text',
text: `Error executing tool '${name}': ${error?.message || 'Unknown error occurred'}`
}
],
isError: true
};
}
});
/**
* 启动服务器
*/
async function main() {
try {
logDebug('Starting Paper Search MCP Server (Node.js)...');
logDebug(`Working directory: ${process.cwd()}`);
logDebug(`Node.js version: ${process.version}`);
logDebug('Process arguments:', process.argv);
// 连接到标准输入输出传输
const transport = new StdioServerTransport();
logDebug('Connecting to stdio transport...');
await server.connect(transport);
logDebug('Paper Search MCP Server is running');
}
catch (error) {
logDebug('Failed to start server:', error);
process.exit(1);
}
}
// 处理未捕获的错误 - MCP模式下更温和
process.on('uncaughtException', (error) => {
if (!isMCPMode()) {
logDebug('Uncaught Exception:', error);
process.exit(1);
}
// MCP模式下不立即退出,避免干扰协议通信
});
process.on('unhandledRejection', (reason, promise) => {
if (!isMCPMode()) {
logDebug('Unhandled Rejection at:', promise, 'reason:', reason);
process.exit(1);
}
});
// 启动服务器 - 直接调用main()确保服务器总是启动
main().catch((error) => {
logDebug('Failed to start MCP server:', error);
process.exit(1);
});
//# sourceMappingURL=server.js.map