check_scihub_mirrors
Verify the operational status of Sci-Hub mirror sites to identify accessible platforms for academic paper retrieval.
Instructions
Check the health status of all Sci-Hub mirror sites
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| forceCheck | No | Force a fresh health check even if recent data exists |
Implementation Reference
- src/mcp/handleToolCall.ts:315-323 (handler)Main execution logic for the 'check_scihub_mirrors' tool. Handles optional forceCheck, calls SciHub searcher's health check and status methods, formats and returns mirror status as JSON response.case 'check_scihub_mirrors': { const { forceCheck } = args; if (forceCheck) { await searchers.scihub.forceHealthCheck(); } const mirrorStatus = searchers.scihub.getMirrorStatus(); return jsonTextResponse(`Sci-Hub Mirror Status:\n\n${JSON.stringify(mirrorStatus, null, 2)}`); }
- src/mcp/tools.ts:338-351 (registration)Tool registration in the TOOLS array, defining name, description, and input schema for MCP tool integration.{ name: 'check_scihub_mirrors', description: 'Check the health status of all Sci-Hub mirror sites', inputSchema: { type: 'object', properties: { forceCheck: { type: 'boolean', description: 'Force a fresh health check even if recent data exists', default: false } } } },
- src/mcp/schemas.ts:142-146 (schema)Zod schema definition for input validation of the tool arguments.export const CheckSciHubMirrorsSchema = z .object({ forceCheck: z.boolean().optional().default(false) }) .strip();
- Core helper method that performs health checks on all Sci-Hub mirrors by pinging them, validating responses, updating status, and sorting by performance. Called by forceHealthCheck().private async checkMirrorHealth(): Promise<void> { logDebug('Checking Sci-Hub mirror sites health...'); const healthPromises = this.mirrorSites.map(async (mirror, index) => { try { const startTime = Date.now(); const response = await axios.get(mirror.url, { timeout: this.mirrorTestTimeout, headers: this.axiosInstance.defaults.headers as any, maxRedirects: 2 }); const responseTime = Date.now() - startTime; // 检查响应是否包含 Sci-Hub 特征 const html = response.data; const isValidSciHub = html.includes('sci-hub') || html.includes('Sci-Hub') || html.includes('alexandra elbakyan'); this.mirrorSites[index] = { ...mirror, lastChecked: new Date(), responseTime, isWorking: response.status === 200 && isValidSciHub, failureCount: 0 }; if (this.mirrorSites[index].isWorking) { logDebug(`${mirror.url} - OK (${responseTime}ms)`); } else { logDebug(`${mirror.url} - Invalid response`); } } catch (error) { this.mirrorSites[index] = { ...mirror, lastChecked: new Date(), isWorking: false, failureCount: mirror.failureCount + 1 }; logDebug(`${mirror.url} - Failed`); } }); await Promise.allSettled(healthPromises); // 按响应时间排序可用的镜像 this.mirrorSites.sort((a, b) => { if (a.isWorking && !b.isWorking) return -1; if (!a.isWorking && b.isWorking) return 1; if (a.isWorking && b.isWorking) { return (a.responseTime || Infinity) - (b.responseTime || Infinity); } return 0; }); this.lastHealthCheck = new Date(); const workingCount = this.mirrorSites.filter(m => m.isWorking).length; logDebug(`Health check complete: ${workingCount}/${this.mirrorSites.length} mirrors working`); if (workingCount === 0) { logWarn('Warning: No Sci-Hub mirrors are currently accessible!'); } }
- Helper method that returns the formatted status of all configured Sci-Hub mirrors, used directly by the tool handler.getMirrorStatus(): { url: string; status: string; responseTime?: number }[] { return this.mirrorSites.map(mirror => ({ url: mirror.url, status: mirror.isWorking ? 'Working' : 'Failed', responseTime: mirror.responseTime })); }