Skip to main content
Glama
gqy20

Europe PMC Literature Search MCP Server

resources.py14.2 kB
""" MCP服务器资源模块 提供配置资源和期刊信息资源 """ import json import logging from pathlib import Path from typing import Any from fastmcp import FastMCP logger = logging.getLogger(__name__) def register_config_resources(mcp: FastMCP) -> None: """注册配置相关资源""" @mcp.resource("config://server-info") def get_server_info() -> str: """获取服务器基本信息""" try: from article_mcp import __version__, __author__, get_server_info info = get_server_info() info.update({ "current_version": __version__, "author": __author__, "python_version": f"{__import__('sys').version_info.major}.{__import__('sys').version_info.minor}.{__import__('sys').version_info.micro}", "supported_databases": ["Europe PMC", "arXiv", "PubMed", "CrossRef", "OpenAlex"], "available_tools": [ "search_literature", "get_article_details", "get_references", "get_literature_relations", "get_journal_quality", "export_batch_results" ] }) return json.dumps(info, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取服务器信息失败: {e}") return json.dumps({ "error": "无法获取服务器信息", "message": str(e) }, ensure_ascii=False, indent=2) @mcp.resource("config://tool-list") def get_tool_list() -> str: """获取可用工具列表""" try: tools = [] for tool_name, tool_info in mcp.tools.items(): tools.append({ "name": tool_name, "description": tool_info.description, "tags": getattr(tool_info, 'tags', []) }) return json.dumps({ "total_tools": len(tools), "tools": tools }, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取工具列表失败: {e}") return json.dumps({ "error": "无法获取工具列表", "message": str(e) }, ensure_ascii=False, indent=2) @mcp.resource("config://api-status") def get_api_status() -> str: """获取各API服务状态""" try: status = {} # 检查各API服务状态 apis = [ ("Europe PMC", "https://www.ebi.ac.uk/europepmc/api"), ("arXiv", "http://export.arxiv.org/api/query"), ("CrossRef", "https://api.crossref.org/works"), ("OpenAlex", "https://api.openalex.org"), ("PubMed", "https://eutils.ncbi.nlm.nih.gov/entrez/eutils") ] import requests for name, url in apis: try: response = requests.get(url, timeout=5) status[name] = { "status": "online" if response.status_code == 200 else "error", "response_code": response.status_code, "response_time_ms": round(response.elapsed.total_seconds() * 1000, 2) } except requests.RequestException as e: status[name] = { "status": "offline", "error": str(e) } return json.dumps({ "check_time": json.dumps({"timestamp": __import__('time').time()}, default=str), "services": status }, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取API状态失败: {e}") return json.dumps({ "error": "无法检查API状态", "message": str(e) }, ensure_ascii=False, indent=2) def register_journal_resources(mcp: FastMCP) -> None: """注册期刊信息相关资源""" @mcp.resource("journal://quality-metrics") def get_journal_quality_metrics() -> str: """获取期刊质量指标定义""" try: metrics = { "impact_factor": { "name": "影响因子", "description": "期刊前两年论文在当前年被引用的平均次数", "range": "通常 0.1 - 100+", "interpretation": { "high": ">10", "medium": "3-10", "low": "<3" } }, "quartile": { "name": "JCR分区", "description": "基于影响因子的学科排名分区", "range": "Q1, Q2, Q3, Q4", "interpretation": { "Q1": "前25%(顶级期刊)", "Q2": "25%-50%(优秀期刊)", "Q3": "50%-75%(良好期刊)", "Q4": "后25%(一般期刊)" } }, "jci": { "name": "期刊引文指标", "description": "标准化后的引文影响力,考虑学科差异", "range": "通常 0.5 - 5.0", "interpretation": { "high": ">2.0", "medium": "1.0-2.0", "low": "<1.0" } }, "cinese_quartile": { "name": "中科院分区", "description": "中国科学院期刊分区表", "range": "一区, 二区, 三区, 四区", "interpretation": { "一区": "顶级期刊(前5%)", "二区": "优秀期刊(6%-20%)", "三区": "良好期刊(21%-50%)", "四区": "一般期刊(后50%)" } } } return json.dumps(metrics, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取期刊质量指标定义失败: {e}") return json.dumps({ "error": "无法获取期刊质量指标定义", "message": str(e) }, ensure_ascii=False, indent=2) @mcp.resource("journal://top-journals") def get_top_journals() -> str: """获取顶级期刊列表""" try: # 预定义的顶级期刊列表 top_journals = { "综合类": [ {"name": "Nature", "impact_factor": 69.504, "quartile": "Q1", "country": "UK"}, {"name": "Science", "impact_factor": 63.714, "quartile": "Q1", "country": "USA"}, {"name": "Cell", "impact_factor": 66.850, "quartile": "Q1", "country": "USA"}, {"name": "PNAS", "impact_factor": 12.779, "quartile": "Q1", "country": "USA"} ], "医学类": [ {"name": "The Lancet", "impact_factor": 202.731, "quartile": "Q1", "country": "UK"}, {"name": "New England Journal of Medicine", "impact_factor": 158.432, "quartile": "Q1", "country": "USA"}, {"name": "Nature Medicine", "impact_factor": 82.889, "quartile": "Q1", "country": "USA"}, {"name": "JAMA", "impact_factor": 120.754, "quartile": "Q1", "country": "USA"} ], "计算机类": [ {"name": "Nature Machine Intelligence", "impact_factor": 25.898, "quartile": "Q1", "country": "UK"}, {"name": "IEEE Transactions on Pattern Analysis", "impact_factor": 24.314, "quartile": "Q1", "country": "USA"}, {"name": "Journal of Machine Learning Research", "impact_factor": 6.775, "quartile": "Q1", "country": "USA"} ] } return json.dumps(top_journals, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取顶级期刊列表失败: {e}") return json.dumps({ "error": "无法获取顶级期刊列表", "message": str(e) }, ensure_ascii=False, indent=2) @mcp.resource("journal://field-rankings") def get_field_rankings() -> str: """获取学科领域排名""" try: # 预定义的学科领域排名 field_rankings = [ { "field": "生物学", "top_journals": [ {"rank": 1, "name": "Nature", "impact_factor": 69.504}, {"rank": 2, "name": "Science", "impact_factor": 63.714}, {"rank": 3, "name": "Cell", "impact_factor": 66.850} ], "total_journals": 500, "description": "生物学领域顶级期刊" }, { "field": "医学", "top_journals": [ {"rank": 1, "name": "The Lancet", "impact_factor": 202.731}, {"rank": 2, "name": "New England Journal of Medicine", "impact_factor": 158.432}, {"rank": 3, "name": "Nature Medicine", "impact_factor": 82.889} ], "total_journals": 800, "description": "医学领域顶级期刊" }, { "field": "计算机科学", "top_journals": [ {"rank": 1, "name": "Nature Machine Intelligence", "impact_factor": 25.898}, {"rank": 2, "name": "IEEE Transactions on Pattern Analysis", "impact_factor": 24.314}, {"rank": 3, "name": "Journal of Machine Learning Research", "impact_factor": 6.775} ], "total_journals": 300, "description": "计算机科学领域顶级期刊" } ] return json.dumps(field_rankings, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取学科领域排名失败: {e}") return json.dumps({ "error": "无法获取学科领域排名", "message": str(e) }, ensure_ascii=False, indent=2) @mcp.resource("journal://cached-journals") def get_cached_journals() -> str: """获取缓存的期刊信息""" try: cache_file = Path("src/resource/journal_info.json") if not cache_file.exists(): return json.dumps({ "message": "暂无缓存的期刊信息", "cache_file": str(cache_file), "exists": False }, ensure_ascii=False, indent=2) with open(cache_file, encoding="utf-8") as f: journal_data = json.load(f) # 统计缓存信息 journals = journal_data.get("journals", []) total_journals = len(journals) # 按影响因子分类统计 high_impact = len([j for j in journals if j.get("metrics", {}).get("impact_factor", 0) > 10]) medium_impact = len([j for j in journals if 3 <= j.get("metrics", {}).get("impact_factor", 0) <= 10]) low_impact = len([j for j in journals if j.get("metrics", {}).get("impact_factor", 0) < 3]) cache_info = { "cache_file": str(cache_file), "exists": True, "total_journals": total_journals, "impact_distribution": { "high_impact": high_impact, "medium_impact": medium_impact, "low_impact": low_impact }, "last_updated": cache_file.stat().st_mtime, "journals": journals[:10] # 只返回前10个期刊作为示例 } return json.dumps(cache_info, ensure_ascii=False, indent=2) except Exception as e: logger.error(f"获取缓存期刊信息失败: {e}") return json.dumps({ "error": "无法获取缓存期刊信息", "message": str(e) }, ensure_ascii=False, indent=2) # 便捷函数用于注册所有资源 def register_all_resources(mcp: FastMCP) -> None: """注册所有资源""" register_config_resources(mcp) register_journal_resources(mcp) logger.info("所有MCP资源注册完成") # 资源列表工具函数 def get_available_resources() -> list[str]: """获取可用资源列表""" return [ "config://server-info", "config://tool-list", "config://api-status", "journal://quality-metrics", "journal://top-journals", "journal://field-rankings", "journal://cached-journals" ] def get_resource_description(resource_uri: str) -> str: """获取资源描述""" descriptions = { "config://server-info": "服务器基本信息和配置", "config://tool-list": "可用工具列表和描述", "config://api-status": "各API服务状态检查", "journal://quality-metrics": "期刊质量指标定义和解释", "journal://top-journals": "各学科顶级期刊列表", "journal://field-rankings": "学科领域期刊排名信息", "journal://cached-journals": "本地缓存的期刊信息" } return descriptions.get(resource_uri, "未知资源")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gqy20/article-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server