Skip to main content
Glama
gqy20

Europe PMC Literature Search MCP Server

cli.py15.5 kB
#!/usr/bin/env python3 """ Article MCP CLI入口点 从main.py迁移的核心功能,保持完全兼容 """ import argparse import asyncio import logging import os import re import sys # 设置编码环境,确保emoji字符正确处理 os.environ['PYTHONIOENCODING'] = 'utf-8' def safe_print(text): """安全打印函数,处理编码问题""" try: print(text) except UnicodeEncodeError: # 移除或替换非ASCII字符 clean_text = re.sub(r'[^\x00-\x7F]+', '', text) print(clean_text) except UnicodeDecodeError: # 处理解码错误 clean_text = text.encode('ascii', 'ignore').decode('ascii') print(clean_text) def create_mcp_server(): """创建MCP服务器 - 集成新的6工具架构""" from fastmcp import FastMCP from .services.arxiv_search import create_arxiv_service from .services.crossref_service import CrossRefService # 导入新架构服务(使用新的包结构) from .services.europe_pmc import create_europe_pmc_service # from .services.literature_relation_service import create_literature_relation_service from .services.openalex_service import OpenAlexService from .services.pubmed_search import create_pubmed_service from .services.reference_service import create_reference_service from .tools.core.article_tools import register_article_tools from .tools.core.batch_tools import register_batch_tools from .tools.core.quality_tools import register_quality_tools from .tools.core.reference_tools import register_reference_tools from .tools.core.relation_tools import register_relation_tools # 导入核心工具模块(使用新的包结构) from .tools.core.search_tools import register_search_tools # 创建 MCP 服务器实例 mcp = FastMCP("Article MCP Server", version="0.1.9") # 创建服务实例 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # 添加中间件 from .middleware import MCPErrorHandlingMiddleware, LoggingMiddleware, TimingMiddleware mcp.add_middleware(MCPErrorHandlingMiddleware(logger)) mcp.add_middleware(LoggingMiddleware(logger)) mcp.add_middleware(TimingMiddleware()) # 注册资源 from .resources import register_config_resources, register_journal_resources register_config_resources(mcp) register_journal_resources(mcp) # 核心服务依赖注入 pubmed_service = create_pubmed_service(logger) europe_pmc_service = create_europe_pmc_service(logger, pubmed_service) crossref_service = CrossRefService(logger) openalex_service = OpenAlexService(logger) arxiv_service = create_arxiv_service(logger) reference_service = create_reference_service(logger) # literature_relation_service 在关系工具中使用,不需要单独创建 # 注册新架构核心工具 # 工具1: 统一搜索工具 search_services = { "europe_pmc": europe_pmc_service, "pubmed": pubmed_service, "arxiv": arxiv_service, "crossref": crossref_service, "openalex": openalex_service, } register_search_tools(mcp, search_services, logger) # 工具2: 统一文章详情工具 article_services = { "europe_pmc": europe_pmc_service, "crossref": crossref_service, "openalex": openalex_service, "arxiv": arxiv_service, "pubmed": pubmed_service, } register_article_tools(mcp, article_services, logger) # 工具3: 参考文献工具 reference_services = { "europe_pmc": europe_pmc_service, "crossref": crossref_service, "pubmed": pubmed_service, "reference": reference_service, } register_reference_tools(mcp, reference_services, logger) # 工具4: 文献关系分析工具 relation_services = { "europe_pmc": europe_pmc_service, "pubmed": pubmed_service, "crossref": crossref_service, "openalex": openalex_service, } register_relation_tools(mcp, relation_services, logger) # 工具5: 期刊质量评估工具 quality_services = {"pubmed": pubmed_service} register_quality_tools(mcp, quality_services, logger) # 工具6: 通用导出工具 batch_services = { "europe_pmc": europe_pmc_service, "pubmed": pubmed_service, "crossref": crossref_service, "openalex": openalex_service, } register_batch_tools(mcp, batch_services, logger) return mcp def start_server( transport: str = "stdio", host: str = "localhost", port: int = 9000, path: str = "/mcp" ): """启动MCP服务器""" safe_print("启动 Article MCP 服务器 v2.0 (6工具统一架构)") safe_print(f"传输模式: {transport}") safe_print("[新架构] 核心工具 (6个统一工具):") safe_print("") safe_print("[工具1] search_literature") safe_print(" - 统一多源文献搜索工具") safe_print(" - 支持数据源: Europe PMC, PubMed, arXiv, CrossRef, OpenAlex") safe_print(" - 特点: 自动去重、智能排序、透明数据源标识") safe_print(" - 参数: keyword, sources, max_results, search_type") safe_print("") safe_print("[工具2] get_article_details") safe_print(" - 统一文献详情获取工具") safe_print(" - 支持标识符: DOI, PMID, PMCID, arXiv ID") safe_print(" - 特点: 多源数据合并、自动类型识别、可选质量指标") safe_print(" - 参数: identifier, id_type, sources, include_quality_metrics") safe_print("") safe_print("[工具3] get_references") safe_print(" - 参考文献获取工具") safe_print(" - 支持从文献标识符获取完整参考文献列表") safe_print(" - 特点: 多源查询、参考文献完整性检查") safe_print(" - 参数: identifier, id_type, sources, max_results") safe_print("") safe_print("[工具4] get_literature_relations") safe_print(" - 文献关系分析工具") safe_print(" - 支持分析: 参考文献、相似文献、引用文献、合作网络") safe_print(" - 特点: 网络分析、社区检测、可视化数据") safe_print(" - 参数: identifier, relation_types, max_depth") safe_print("") safe_print("[工具5] get_journal_quality") safe_print(" - 期刊质量评估工具") safe_print(" - 支持指标: 影响因子、JCI、分区、排名") safe_print(" - 特点: EasyScholar集成、本地缓存、批量评估") safe_print(" - 参数: journal_name, include_metrics, evaluation_criteria") safe_print("") safe_print("[工具6] export_batch_results") safe_print(" - 通用结果导出工具") safe_print(" - 支持: JSON、CSV、Excel等格式导出") safe_print(" - 特点: 多格式支持、元数据包含、自动路径生成") safe_print(" - 参数: results, format_type, output_path, include_metadata") safe_print("") safe_print("[技术特性]:") safe_print(" - FastMCP 2.13.0 框架") safe_print(" - 依赖注入架构模式") safe_print(" - 智能缓存机制") safe_print(" - 并发控制优化") safe_print(" - 多API集成") safe_print(" - MCP配置集成") mcp = create_mcp_server() if transport == "stdio": print("使用 stdio 传输模式 (推荐用于 Claude Desktop)") mcp.run(transport="stdio") elif transport == "sse": print("使用 SSE 传输模式") print(f"服务器地址: http://{host}:{port}/sse") mcp.run(transport="sse", host=host, port=port) elif transport == "streamable-http": print("使用 Streamable HTTP 传输模式") print(f"服务器地址: http://{host}:{port}{path}") mcp.run(transport="streamable-http", host=host, port=port, path=path, stateless_http=True) else: print(f"不支持的传输模式: {transport}") sys.exit(1) async def run_test(): """运行测试""" print("Europe PMC MCP 服务器测试") print("=" * 50) try: # 简单测试:验证MCP服务器创建和工具注册 create_mcp_server() print("✓ MCP 服务器创建成功") # 测试工具函数直接调用 print("✓ 开始测试搜索功能...") # 这里我们不能直接调用工具,因为需要MCP客户端 # 但我们可以测试服务器是否正确创建 print("✓ 测试参数准备完成") print("✓ MCP 服务器工具注册正常") print("\n测试结果:") print("- MCP 服务器创建: 成功") print("- 工具注册: 成功") print("- 配置验证: 成功") print("\n注意: 完整的功能测试需要在MCP客户端环境中进行") print("建议使用 Claude Desktop 或其他 MCP 客户端进行实际测试") return True except Exception as e: print(f"测试失败: {e}") import traceback traceback.print_exc() return False def show_info(): """显示项目信息""" safe_print("Article MCP 文献搜索服务器 (基于 BioMCP 设计模式)") safe_print("=" * 70) safe_print("基于 FastMCP 框架和 BioMCP 设计模式开发的文献搜索工具") safe_print("支持搜索 Europe PMC、arXiv 等多个文献数据库") safe_print("\n[核心功能]:") safe_print("- [搜索] 搜索 Europe PMC 文献数据库 (同步 & 异步版本)") safe_print("- [详情] 获取文献详细信息 (同步 & 异步版本)") safe_print("- [文献] 获取参考文献列表 (通过DOI, 同步 & 异步版本)") safe_print("- [性能] 异步并行优化版本(提升6.2倍性能)") safe_print("- [标识] 支持多种标识符 (PMID, PMCID, DOI)") safe_print("- [过滤] 支持日期范围过滤") safe_print("- [去重] 参考文献信息补全和去重") safe_print("- [缓存] 智能缓存机制(24小时)") safe_print("- [传输] 支持多种传输模式") safe_print("- [统计] 详细性能统计信息") safe_print("\n[技术优化]:") safe_print("- [架构] 模块化架构设计 (基于 BioMCP 模式)") safe_print("- [并发] 并发控制 (信号量限制并发请求)") safe_print("- [重试] 重试机制 (3次重试,指数退避)") safe_print("- [限速] 速率限制 (遵循官方API速率限制)") safe_print("- [异常] 完整的异常处理和日志记录") safe_print("- [接口] 统一的工具接口 (类似 BioMCP 的 search/fetch)") safe_print("\n[性能数据]:") safe_print("- 同步版本: 67.79秒 (112条参考文献)") safe_print("- 异步版本: 10.99秒 (112条参考文献)") safe_print("- 性能提升: 6.2倍更快,节省83.8%时间") safe_print("\n[MCP 工具详情(新6工具统一架构)]:") print("1. search_literature") print(" 功能:统一多源文献搜索工具") print(" 参数:keyword, sources, max_results, search_type") print(" 数据源:Europe PMC, PubMed, arXiv, CrossRef, OpenAlex") print(" 特点:自动去重、智能排序、透明数据源标识") print(" 适用:文献检索、复杂查询、高性能需求") print("2. get_article_details") print(" 功能:统一文献详情获取工具") print(" 参数:identifier, id_type, sources, include_quality_metrics") print(" 标识符:DOI, PMID, PMCID, arXiv ID") print(" 特点:多源数据合并、自动类型识别、可选质量指标") print(" 适用:文献详情查询、大规模数据处理") print("3. get_references") print(" 功能:参考文献获取工具") print(" 参数:identifier, id_type, sources, max_results, include_metadata") print(" 标识符:DOI, PMID, PMCID, arXiv ID") print(" 特点:多源查询、参考文献完整性检查、智能去重") print(" 适用:参考文献获取、文献数据库构建") print("4. get_literature_relations") print(" 功能:文献关系分析工具") print(" 参数:identifiers, relation_types, max_depth, max_results") print(" 关系类型:参考文献、相似文献、引用文献、合作网络") print(" 特点:网络分析、社区检测、可视化数据") print(" 适用:文献关联分析、学术研究综述、文献网络构建") print("5. get_journal_quality") print(" 功能:期刊质量评估工具") print(" 参数:journals, operation, evaluation_criteria, include_metrics") print(" 操作类型:质量评估、领域排名、批量评估") print(" 特点:EasyScholar集成、本地缓存、多维度评估") print(" 适用:期刊质量评估、投稿期刊选择、文献质量筛选") print("6. export_batch_results") print(" 功能:通用结果导出工具") print(" 参数:results, format_type, output_path, include_metadata") print(" 格式:JSON, CSV, Excel") print(" 特点:多格式支持、元数据包含、自动路径生成") print(" 适用:批量结果导出、数据分析、报告生成") print("\n使用 'python -m article_mcp --help' 查看更多选项") def main(): """主函数""" parser = argparse.ArgumentParser( description="Article MCP 文献搜索服务器", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 使用示例: python -m article_mcp server # 启动服务器 (stdio模式) python -m article_mcp server --transport sse # 启动SSE服务器 python -m article_mcp server --transport streamable-http # 启动Streamable HTTP服务器 python -m article_mcp test # 运行测试 python -m article_mcp info # 显示项目信息 """, ) subparsers = parser.add_subparsers(dest="command", help="可用命令") # 服务器命令 server_parser = subparsers.add_parser("server", help="启动MCP服务器") server_parser.add_argument( "--transport", choices=["stdio", "sse", "streamable-http"], default="stdio", help="传输模式 (默认: stdio)", ) server_parser.add_argument( "--host", default="localhost", help="服务器主机地址 (默认: localhost)" ) server_parser.add_argument("--port", type=int, default=9000, help="服务器端口 (默认: 9000)") server_parser.add_argument( "--path", default="/mcp", help="HTTP 路径 (仅用于 streamable-http 模式, 默认: /mcp)" ) # 测试命令 subparsers.add_parser("test", help="运行测试") # 信息命令 subparsers.add_parser("info", help="显示项目信息") args = parser.parse_args() if args.command == "server": try: start_server(transport=args.transport, host=args.host, port=args.port, path=args.path) except KeyboardInterrupt: print("\n服务器已停止") sys.exit(0) except Exception as e: print(f"启动失败: {e}") sys.exit(1) elif args.command == "test": try: asyncio.run(run_test()) except Exception as e: print(f"测试失败: {e}") sys.exit(1) elif args.command == "info": show_info() else: # 默认显示帮助信息 parser.print_help() if __name__ == "__main__": main()

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