Copilot instructions
.github/copilot-instructions.mdCopilot instructions
Quality
77/100
Scores the file, not the repository.Length
2,907 words
108 headings · 27 code blocksRepository
23
— · pushed 0 days agoLast changed
today
First indexed 3 days ago.1# GitHub Copilot Instructions for PubMed Search MCP23This document provides guidance for AI assistants working with the PubMed Search MCP server.45---67## Repository Hook Notes89- `unicode-mojibake` blocks newly staged corrupted emoji/UTF-8 artifacts while allowing valid emoji; restore garbled text as UTF-8 before committing.1011## ⚡ 開發環境規範 (CRITICAL)1213### 套件管理:使用 UV (NOT pip)1415本專案**必須**使用 [UV](https://github.com/astral-sh/uv) 管理所有 Python 依賴。16**所有命令(包括測試、lint、type check)一律透過 `uv run` 執行**,確保使用正確的虛擬環境與依賴版本。1718> 💡 **UV 非常高效**:UV 使用 Rust 實作,比 pip 快 10-100 倍。即使是 `uv run pytest`,UV 也會在毫秒級確認環境一致後直接執行,幾乎零開銷。1920```bash21# ❌ 禁止使用 (一律禁止直接呼叫,必須透過 uv run)22pip install <package>23python -m pytest24pytest25ruff check .26mypy src/2728# ✅ 正確使用29uv add <package> # 新增依賴30uv add --dev <package> # 新增開發依賴31uv remove <package> # 移除依賴32uv sync # 同步依賴33uv run pytest # 透過 uv 執行測試(自動多核)34uv run python script.py # 透過 uv 執行 Python35```3637### 程式碼品質工具(全部透過 uv run 執行)3839```bash40uv run ruff check . # Lint 檢查41uv run ruff check . --fix # Lint 自動修復42uv run ruff format . # 格式化43uv run mypy src/ tests/ # 型別檢查(含 src 和 tests)44uv run pytest # ⩡ 多核平行測試(預設 -n auto --timeout=60)45uv run pytest --cov # 多核 + 覆蓋率46```4748> ⚠️ **永遠不要**直接呼叫 `pytest`、`ruff`、`mypy`,一律使用 `uv run` 前綴。4950### 🔒 Pre-commit Hooks (自動品質守門)5152本專案使用 [pre-commit](https://pre-commit.com/) 在每次 commit 時自動執行品質檢查。5354```bash55# 首次設定(uv sync 安裝依賴後)56uv run pre-commit install # 安裝 pre-commit hook57uv run pre-commit install --hook-type pre-push # 安裝 pre-push hook5859# 手動執行所有 hooks60uv run pre-commit run --all-files6162# 更新 hook 版本(建議每月一次)63uv run pre-commit autoupdate64```6566**Commit 階段自動檢查:**67- trailing-whitespace / end-of-file-fixer (自動修復)68- check-yaml / check-toml / check-json / check-ast69- check-added-large-files / check-merge-conflict / debug-statements / detect-private-key70- check-byte-order-marker / fix-byte-order-marker (自動修復)71- check-builtin-literals / check-case-conflict / check-docstring-first72- check-executables-have-shebangs / check-shebang-scripts-are-executable73- check-symlinks / destroyed-symlinks / check-vcs-permalinks74- check-illegal-windows-names / mixed-line-ending (自動修復)75- no-commit-to-branch (保護 main/master)76- name-tests-test (強制 test_*.py 命名)77- **ruff** lint (自動修復) + **ruff-format** (自動修復)78- **bandit** 安全掃描 (medium+ severity, `pyproject.toml [tool.bandit]`)79- **vulture** 死碼掃描 (`vulture_whitelist.py` 管理白名單)80- **deptry** 依賴衛生 (`pyproject.toml [tool.deptry]`)81- **semgrep** SAST 靜態安全分析 — **已移至 pre-push** (記憶體 300-500MB)82- **mypy** type check — **已移至 pre-push** (記憶體 500MB-1GB)83- **async-test-checker** async/sync 測試一致性 (`scripts/check_async_tests.py`)84- **file-hygiene** 檔案衛生檢查 (`scripts/hooks/check_file_hygiene.py`),只審查**新增**路徑;已在 HEAD 的檔案當初已被接受,再擋一次只會跟自動修復型 hook 互鎖85- **commit-size-guard** 限制每次 commit ≤30 檔案 (`scripts/hooks/check_commit_size.py`)86- **tool-count-sync** MCP 工具文檔同步 (`scripts/hooks/check_tool_sync.py`, 自動修復)87- **skills-frontmatter** 驗證 `.claude/skills/*/SKILL.md` 的 YAML frontmatter (`scripts/hooks/check_skills_frontmatter.py`)88- **evolution-cycle** 一致性驗證 (`scripts/hooks/check_evolution_cycle.py`)89- **future-annotations** 強制 `from __future__ import annotations` (`scripts/hooks/check_future_annotations.py`, 自動修復)90- **no-print-in-src** 禁止 src/ 使用 print() (`scripts/hooks/check_no_print.py`)91- **ddd-layer-imports** DDD 層級依賴檢查 (`scripts/hooks/check_ddd_layers.py`)92- **no-type-ignore-bare** 禁止裸 `# type: ignore` (`scripts/hooks/check_type_ignore.py`)93- **docstring-tools** MCP 工具必須有文檔字串 (`scripts/hooks/check_docstring_tools.py`)94- **no-env-inner-layers** 禁止內層 DDD 使用 os.environ (`scripts/hooks/check_env_config.py`)95- **tenant-scoped-storage** presentation 層儲存路徑須經 `tenant_data_dir()` (`scripts/hooks/check_tenant_scoped_storage.py`)96- **source-counts-guard** 確保每來源 API 回傳量顯示 (`scripts/hooks/check_source_counts.py`)97- **todo-scanner** TODO/FIXME 掃描器 (警告, 不阻擋) (`scripts/hooks/check_todo_scanner.py`)98- **instruction-drift** 工具 docstring 變更偵測 (警告, 不阻擋) (`scripts/hooks/check_instruction_drift.py`)99100**Push 階段自動檢查:**101- **mypy** type check (`uv run mypy src/`, 記憶體 500MB-1GB)102- **semgrep** SAST 靜態安全分析 (`p/python` ruleset, 記憶體 300-500MB)103- **pytest** 全套測試 (`-n auto --timeout=60 -m "not integration"`),排除會打真實第三方 API 的 integration 測試;需要時手動跑 `uv run pytest -m integration`104105```bash106# 跳過特定 hook107SKIP=mypy git commit -m "quick fix"108# 跳過所有 hooks(慎用)109git commit --no-verify -m "emergency fix"110```111112### 🔄 自演化循環 (Self-Evolution Cycle - IMPORTANT)113114本專案的 Instruction、Skill、Hook 形成一個自我演化的閉迴系統:115116```117Instruction (copilot-instructions.md)118 │ 定義規範、引導 AI 使用 Skills119 ▼120Skill (SKILL.md 檔案)121 │ 確保建構完整、創建新 Hook122 ▼123Hook (.pre-commit-config.yaml + scripts/hooks/)124 │ 自動執行檢查、自動修正125 ▼126evolution-cycle hook (check_evolution_cycle.py)127 │ 驗證三者一致性、報告不同步處128 ▼129Feedback → 更新 Instruction & Skill → 循環完成130```131132**新增 Hook 的完整流程:**1331. 創建 hook 腳本 → `scripts/hooks/<name>.py`1342. 註冊到 `.pre-commit-config.yaml`1353. 更新 `copilot-instructions.md` (Commit 階段自動檢查列表)1364. 更新 `git-precommit SKILL.md` (架構圖 + Hook 設定檔案表)1375. 更新 `CONTRIBUTING.md` (hooks 表格)1386. 執行 `uv run python scripts/hooks/check_evolution_cycle.py` 驗證139140> ⚠️ 如果只做了 1-2 而沒有 3-5,evolution-cycle hook 會在下次 commit 時報錯。141142**套件版本自動演化:**143```bash144uv run pre-commit autoupdate # 更新 ruff、pre-commit-hooks 等版本145uv run pre-commit run --all-files # 驗證更新後所有 hook 正常146```147148### ⏱️ 測試執行時間 (IMPORTANT - 請務必閱讀)149150本專案**強制**使用 **pytest-xdist** 多核平行測試(透過 `addopts = "-n auto --timeout=60"` 全局強制)。151152```bash153# ✅ 所有測試命令自動帶 -n auto --timeout=60(不需手動加)154uv run pytest # 多核執行(~67 秒)155uv run pytest tests/ -q # 多核 + 簡潔輸出156157# ✅ 導向檔案避免 terminal buffer 溢出158uv run pytest tests/ -q --no-header 2>&1 > scripts/_tmp/test_result.txt159# 等待 ~70 秒後再讀取結果160161# ✅ 多核 + 覆蓋率(pytest-cov 完全支援 xdist)162uv run pytest --cov -q163164# ⚠️ 僅在需要 benchmark 時停用 xdist165uv run pytest tests/test_performance.py --benchmark-only -p no:xdist166```167168| 指標 | 數值 |169|------|------|170| 測試檔案數 | 60+ |171| 測試案例數 | 2200+ |172| 測試程式碼行數 | 30,000+ |173| ⚡ 多核執行時間 (`-n auto`) | **~67 秒** |174| 每個測試超時 | 60 秒 (`--timeout=60`) |175| 建議 terminal timeout | **120,000+ ms** |176177> 💡 **pytest-xdist** 使用多 process 平行化,每個 worker 為獨立 process,singleton 隔離無衝突。178> ⚠️ `pytest-benchmark` 在 xdist 模式下自動停用(benchmark 需要單核確保精確度)。179180### 🔄 Async/Sync 測試一致性檢查 (MANDATORY)181182本專案使用 `asyncio_mode = "auto"`,所有 async 方法的測試必須正確使用 `await` 和 `AsyncMock`。183**每次新增或修改測試時,必須執行** `scripts/check_async_tests.py` 確認無 async/sync 不一致。184185```bash186# ✅ 必須在 commit 前執行187uv run python scripts/check_async_tests.py188189# 詳細模式(查看每個問題的具體位置)190uv run python scripts/check_async_tests.py --verbose191192# 自動修復 missing await(僅修復可安全自動修復的問題)193uv run python scripts/check_async_tests.py --fix194```195196#### 常見反模式與修正197198```python199# ❌ 錯誤:使用 Mock() mock async 方法200mock_searcher = Mock()201mock_searcher.search.return_value = []202result = await searcher.search(...) # TypeError: can't await Mock203204# ✅ 正確:使用 AsyncMock()205mock_searcher = AsyncMock()206mock_searcher.search.return_value = []207result = await searcher.search(...) # 正常運作208209# ❌ 錯誤:忘記 await async 方法210result = client.search(query="test") # 返回 coroutine,非結果211212# ✅ 正確:加上 await213result = await client.search(query="test") # 返回實際結果214215# ❌ 錯誤:sync def 測試呼叫 async 方法216def test_something():217 result = client.search(...) # 永遠不會正確執行218219# ✅ 正確:使用 async def220async def test_something():221 result = await client.search(...)222```223224#### 檢查清單(每次寫測試時)225226- [ ] async 方法的 mock 是否使用 `AsyncMock()`?227- [ ] 所有 async 方法呼叫是否加了 `await`?228- [ ] 測試函數是否為 `async def`?(當測試呼叫 async 方法時)229- [ ] `scripts/check_async_tests.py` 執行結果為 0 issues?230231### 依賴管理檔案232233- `pyproject.toml` - 主要依賴定義234- `uv.lock` - 鎖定版本 (自動生成,勿手動編輯)235236### 🧹 檔案衛生規範 (File Hygiene - MANDATORY)237238AI Agent 在工作過程中**絕對禁止**在專案中留下臨時檔案。違反此規範等同程式碼品質問題。239240#### 禁止事項241242```243# ❌ 禁止:將測試結果導向檔案244uv run pytest > test_results.txt245uv run pytest 2>&1 | Out-File result.txt246247# ❌ 禁止:在 scripts/ 放一次性修復腳本248scripts/auto_fix_something.py249scripts/fix_async_tests_v3.py250251# ❌ 禁止:在根目錄放任何臨時產出物252failed_lines.txt, test_summary.txt, v3_result.txt253```254255#### 正確做法256257```bash258# ✅ 正確:直接在終端看測試結果259uv run pytest --timeout=60260261# ✅ 正確:若真需要臨時檔案,放在 scripts/_tmp/ (已被 .gitignore 排除)262uv run pytest > scripts/_tmp/result.txt263264# ✅ 正確:修復腳本執行完畢後立即刪除265Remove-Item scripts/_tmp/fix_script.py266267# ✅ 正確:commit 前確認無臨時檔案268git status --short | Where-Object { $_ -match '^\?\?' }269```270271#### 允許在根目錄的檔案(白名單)272273| 類型 | 檔案 |274|------|------|275| 設定 | `pyproject.toml`, `Dockerfile`, `docker-compose*.yml`, `.gitignore`, `uv.lock` |276| 狀態 | `.instruction_drift_fingerprint` |277| 文檔 | `README.md`, `README.zh-TW.md`, `CHANGELOG.md`, `CONSTITUTION.md`, `ARCHITECTURE.md`, `ROADMAP.md`, `CONTRIBUTING.md`, `DEPLOYMENT.md`, `CITATION.cff`, `AGENTS.md`, `LICENSE` |278| Entrypoints | `pubmed-search-mcp`, `pubmed-search-mcp-http`, `pubmed-browser-fetch-broker`, `run_copilot.py`, `run_server.py` |279280> ⚠️ **任何不在白名單的檔案出現在根目錄都是錯誤。**281282### 🚫 禁止重造輪子與過度設計 (No Reinventing the Wheel - MANDATORY)283284AI Agent **必須持續檢查**是否存在以下反模式,並在每次新增或修改程式碼時主動排查:285286#### 重造輪子 (Reinventing the Wheel)287288```289# ❌ 禁止:自己實作已有標準庫/第三方可完成的功能290手寫 HTTP retry/backoff → 用 tenacity 或 httpx 內建 retry291手寫 JSON schema 驗證 → 用 pydantic292手寫 rate limiter → 用現有的 asyncio.Semaphore 或 aiolimiter293手寫 URL 解析/編碼 → 用 urllib.parse / yarl294手寫日期解析 → 用 dateutil.parser295手寫 CSV/XML 解析器 → 用 csv / lxml / xml.etree296自己包裝 logging 框架 → 直接用 logging 標準庫297手寫 LRU cache → 用 functools.lru_cache / cachetools298```299300#### 過度設計 (Over-Engineering)301302```303# ❌ 禁止:304- 只有一個實作卻建立 Abstract Base Class + Interface + Factory305- 為了「未來擴展」加入目前未使用的參數/類別/層306- 包裝層只是直接轉發呼叫,沒有增加任何邏輯 (Thin Wrapper 無價值)307- 為只用一次的功能建立獨立模組308- 把 3 行能解決的問題寫成 30 行的 class hierarchy309- 給 cfg/env 變數寫複雜的 getter/setter,直接讀取即可310311# ✅ 正確做法:312- YAGNI (You Ain't Gonna Need It) — 只實作當前需要的313- 優先使用函數,不需要狀態就不要用 class314- 先用最簡單的方案,有證據需要時才重構315- 第三方庫已解決的問題,直接 uv add 而非手寫316```317318#### 檢查清單 (每次 code review 時)319320- [ ] 這個功能有沒有現成的標準庫/第三方能做到?321- [ ] 這個 class 是否可以用簡單的函數取代?322- [ ] 這個抽象層是否真的有多個實作?還是只有一個?323- [ ] 這段程式碼有沒有「只是轉發」的 wrapper?324- [ ] 有沒有為「未來可能」而非「現在需要」而寫的程式碼?325326---327328## 🏗️ 專案架構 (DDD v0.2.0)329330本專案採用 **Domain-Driven Design (DDD)** 分層架構:331332```333src/pubmed_search/334├── domain/ # 核心業務邏輯335│ └── entities/ # 實體 (UnifiedArticle, TimelineEvent)336├── application/ # 應用服務/用例337│ ├── search/ # QueryAnalyzer, ResultAggregator338│ ├── export/ # 引用匯出 (RIS, BibTeX...)339│ ├── session/ # SessionManager340│ └── timeline/ # TimelineBuilder, MilestoneDetector341├── infrastructure/ # 外部系統整合342│ ├── ncbi/ # Entrez, iCite, Citation Exporter343│ ├── sources/ # Europe PMC, CORE, CrossRef...344│ └── http/ # HTTP 客戶端345├── presentation/ # 使用者介面346│ ├── mcp_server/ # MCP 工具、提示、資源347│ └── api/ # Auxiliary HTTP API (not pubmed_search.api)348└── shared/ # 跨層共用349 ├── exceptions.py # 例外處理350 └── async_utils.py # 非同步工具 (CircuitBreaker, RateLimiter, etc.)351```352353### Source Client 設計模式 (BaseAPIClient)354355所有外部 API 客戶端(`infrastructure/sources/`)都繼承自 `BaseAPIClient`:356357```python358# base_client.py 提供:359# - 自動 retry on 429 (Rate Limit) + Retry-After 支援360# - Rate limiting (configurable min_interval)361# - CircuitBreaker 錯誤容忍362# - 統一的 httpx.AsyncClient 管理363364class MySourceClient(BaseAPIClient):365 _service_name = "MyAPI"366367 def __init__(self):368 super().__init__(base_url="https://api.example.com", min_interval=0.1)369370 # 覆寫 _handle_expected_status() 處理 404 等預期狀態碼371 # 覆寫 _parse_response() 自訂回應解析372 # 覆寫 _execute_request() 自訂請求邏輯 (e.g., POST)373```374375**已整合的 8 個客戶端:** CrossRef, OpenAlex, Semantic Scholar, NCBI Extended, Europe PMC, CORE, Open-i, Unpaywall376377### 導入規則378379```python380# Stable Python SDK facade for external package/notebook callers381from pubmed_search.api import PubMedSearchClient, PubMedSearchConfig382383client = PubMedSearchClient(PubMedSearchConfig(email="your@email.com"))384385# Low-level/internal usage only386from pubmed_search.infrastructure.ncbi import LiteratureSearcher387388# ❌ 避免:深層相對導入389from ...infrastructure.ncbi import LiteratureSearcher390```391392---393394## 🎯 Project Overview395396PubMed Search MCP is a **professional literature research assistant** that provides:397- **45 MCP Tools** for literature search and analysis398- **Multi-source search**: PubMed, Europe PMC (33M+), CORE (200M+)399- **NCBI databases**: Gene, PubChem, ClinVar400- **Full text access**: Direct XML/text retrieval401- **Research Timeline**: Milestone detection, temporal evolution analysis402- **Official Citation Export**: NCBI Citation Exporter API (RIS, MEDLINE, CSL)403404---405406## 🔍 Search Strategy Selection407408### Quick Search (Default)409**Trigger**: "find papers about...", "search for...", "any articles on..."410```python411unified_search(query="<topic>", limit=10)412```413414When an agent needs a lightweight topic overview in the same response, prefer:415```python416unified_search(query="<topic>", options="context_graph")417```418419### Systematic Search420**Trigger**: "comprehensive search", "systematic review", "find all papers"421```python422# Step 1: Get MeSH terms and synonyms423generate_search_queries(topic="<topic>")424425# Step 2: Build a Boolean query from MeSH terms and synonyms426# Step 3: Validate the final query427analyze_search_query(query="<combined_boolean_query>")428429# Step 4: Execute the search430unified_search(query="<combined_boolean_query>")431```432433### PICO Clinical Question434**Trigger**: "Is A better than B?", "Does X reduce Y?", comparative questions435```python436# Step 1: Agent extracts P/I/C/O, then validates the structured handoff437parse_pico(438 description="<clinical question>",439 p="<Population>",440 i="<Intervention/exposure>",441 c="<Comparator, optional>",442 o="<Outcome, recommended>"443)444445# Step 2: Get materials for each PICO element (parallel!)446generate_search_queries(topic="<P>")447generate_search_queries(topic="<I>")448generate_search_queries(topic="<C>")449generate_search_queries(topic="<O>")450451# Step 3: Combine with Boolean logic452# (P) AND (I) AND (C) AND (O)453454# Step 4: Validate and execute455analyze_search_query(query="<combined_boolean_query>")456unified_search(query="<combined_boolean_query>")457```458459---460461## 📚 Tool Categories462463### 搜尋工具464*Unified multi-source literature search gateway*465466| Tool | Purpose |467|------|---------|468| `unified_search` | Unified Search - Single entry point for multi-source academic search. |469470471### 查詢智能472*MeSH expansion, agent-provided PICO handoff, and query analysis*473474| Tool | Purpose |475|------|---------|476| `parse_pico` | Validate agent-provided PICO elements and return a runnable search plan. |477| `generate_search_queries` | Gather search intelligence for a topic - returns RAW MATERIALS for Agent to decide. |478| `analyze_search_query` | Analyze a search query without executing the search. |479480481### 文章探索482*相關文章、引用網路*483484| Tool | Purpose |485|------|---------|486| `fetch_article_details` | Fetch detailed information for one or more PubMed articles. |487| `find_related_articles` | Find articles related to a given PubMed article. |488| `find_citing_articles` | Find articles that cite a given PubMed article. |489| `get_article_references` | Get the references (bibliography) of a PubMed article. |490| `get_citation_metrics` | Get citation metrics from NIH iCite for articles. |491492493### 全文工具494*全文取得與文本挖掘*495496| Tool | Purpose |497|------|---------|498| `get_fulltext` | Enhanced multi-source fulltext retrieval. |499| `get_text_mined_terms` | Get text-mined annotations from Europe PMC. |500501502### NCBI 延伸503*Gene, PubChem, ClinVar*504505| Tool | Purpose |506|------|---------|507| `search_gene` | Search NCBI Gene database for gene information. |508| `get_gene_details` | Get detailed information about a gene by NCBI Gene ID. |509| `get_gene_literature` | Get PubMed articles linked to a gene. |510| `search_compound` | Search PubChem for chemical compounds. |511| `get_compound_details` | Get detailed information about a compound by PubChem CID. |512| `get_compound_literature` | Get PubMed articles linked to a compound. |513| `search_clinvar` | Search ClinVar for clinical variants. |514515516### 引用網絡517*引用樹建構與探索*518519| Tool | Purpose |520|------|---------|521| `build_citation_tree` | Build a citation tree (network) from a single article. |522523524### 匯出工具525*引用格式匯出與本機文獻筆記保存*526527| Tool | Purpose |528|------|---------|529| `prepare_export` | Export citations to reference manager formats. |530| `save_literature_notes` | Save searched articles as guided local wiki/Foam/Markdown notes. |531532533### Session 管理534*PMID 暫存與歷史*535536| Tool | Purpose |537|------|---------|538| `read_session` | Read session data through a single facade. |539| `get_session_pmids` | 取得 session 中暫存的 PMID 列表。 |540| `get_cached_article` | 從 session 快取取得文章詳情。 |541| `get_session_summary` | 取得當前 session 的摘要資訊。 |542| `get_session_log` | 取得當前 session 的 activity log 與搜尋歷史摘要。 |543544545### 機構訂閱546*OpenURL Link Resolver*547548| Tool | Purpose |549|------|---------|550| `configure_institutional_access` | Configure your institution's link resolver for full-text access. |551| `get_institutional_link` | Generate institutional access link (OpenURL) for an article. |552| `list_resolver_presets` | List available institutional link resolver presets. |553| `test_institutional_access` | Test your institutional link resolver configuration. |554| `diagnose_institutional_access` | Diagnose why institutional fulltext access succeeds or fails for an article. |555556557### 視覺搜索558*圖片分析與搜索 (實驗性)*559560| Tool | Purpose |561|------|---------|562| `analyze_figure_for_search` | Analyze a scientific figure or image for literature search. |563564565### ICD 轉換566*ICD-10 與 MeSH 轉換*567568| Tool | Purpose |569|------|---------|570| `convert_icd_mesh` | Convert between ICD codes and MeSH terms (bidirectional). |571572573### 引用驗證574*Reference list verification with PubMed evidence*575576| Tool | Purpose |577|------|---------|578| `verify_reference_list` | Verify a plain-text reference list against PubMed evidence. |579580581### 圖表擷取582*文章圖表與視覺資料擷取*583584| Tool | Purpose |585|------|---------|586| `get_article_figures` | Get structured figure metadata (label, caption, image URL) and PDF links from a PMC Open Access arti |587588589### 研究編年史590*研究演化脈絡:持久化、可版本比對、證據支撐的時序主軸與分支投影*591592| Tool | Purpose |593|------|---------|594| `build_research_chronicle` | Build a persisted, versioned, evidence-backed Research Chronicle. |595| `read_research_chronicle` | Read stored Research Chronicles: load, list, diff, narrate, analyze, compare. |596597598### 圖片搜尋599*生物醫學圖片搜尋*600601| Tool | Purpose |602|------|---------|603| `search_biomedical_images` | Search biomedical images across Open-i and Europe PMC. |604605606### Pipeline 管理607*Pipeline 持久化、載入、排程*608609| Tool | Purpose |610|------|---------|611| `manage_pipeline` | Manage saved pipelines through a single facade. |612| `save_pipeline` | Save a pipeline configuration for later reuse. |613| `list_pipelines` | List all saved pipeline configurations. |614| `load_pipeline` | Load a pipeline configuration for review or editing. |615| `delete_pipeline` | Delete a saved pipeline configuration and its execution history. |616| `get_pipeline_history` | Get execution history for a saved pipeline. |617| `schedule_pipeline` | Schedule a saved pipeline for periodic execution. |618619---620621## 📋 Common Workflows622623### 1. Find Papers on a Topic624```python625unified_search(query="remimazolam ICU sedation", limit=10)626```627628### 2. Explore from a Key Paper629```python630# Found an important paper (PMID: 12345678)631find_related_articles(pmid="12345678") # Similar papers632find_citing_articles(pmid="12345678") # Who cited this?633get_article_references(pmid="12345678") # What did it cite?634```635636### 3. Get Full Text637```python638# Structured full text from PMC / Europe PMC639get_fulltext(pmcid="PMC7096777", sections="introduction,results")640641# DOI or PMID-based retrieval with broader source fallback642get_fulltext(doi="10.1038/s41586-021-03819-2", extended_sources=True)643```644645### 4. Research a Gene646```python647search_gene(query="BRCA1", organism="human")648get_gene_details(gene_id="672")649get_gene_literature(gene_id="672", limit=20)650```651652### 5. Research a Drug653```python654search_compound(query="propofol")655get_compound_details(cid="4943")656get_compound_literature(cid="4943", limit=20)657```658659### 6. Export Results660```python661prepare_export(pmids="last", format="ris") # Last search662save_literature_notes(pmids="last") # Default wiki note + Foam-compatible wikilinks + CSL JSON663get_fulltext(pmid="12345678", extended_sources=True) # Retrieve selected paper full text664```665666---667668## 📌 文檔自動同步規則 (IMPORTANT)669670當 MCP 工具被 **新增、移除、或重新命名** 時,以下文件必須同步更新:671672### 手動修改(AI Agent 負責)6731. `tool_registry.py` — 更新 `TOOL_CATEGORIES` dict6742. `tools/__init__.py` — import + 呼叫 `register_*_tools()`675676### 自動同步(腳本負責)677```bash678uv run python scripts/count_mcp_tools.py --update-docs679```680681此腳本自動更新以下 6 個文件:682- `instructions.py` — SERVER_INSTRUCTIONS 工具列表683- `.github/copilot-instructions.md` — Tool Categories 表格684- `.claude/skills/pubmed-mcp-tools-reference/SKILL.md` — 完整工具參考685- `TOOLS_INDEX.md` — 工具索引686- `README.md` / `README.zh-TW.md` — 工具數量687688> ⚠️ **必須在 git commit 前執行**。詳見 `.claude/skills/tool-sync/SKILL.md`。689690當 `save_literature_notes` 或 pipeline tutorial 這類 agent-facing export/persistence 行為變更時,還要同步 `AGENTS.md`、`.github/agents/research.agent.md`、`.clinerules/`、相關 `.claude/skills/`,並用 `scripts/build_docs_site.py` 更新 `docs/site-content/**` 與 skill reference copies。691692---693694## ⚠️ Important Notes6956961. **Session Auto-management**: Search results are automatically cached. Use `pmids="last"` to reference previous searches.6976981. **Tool Progress**: `unified_search`, timeline tools, and Europe PMC fulltext/text-mining tools can emit MCP progress updates when the client provides a progress token.6997002. **Session Resources and Artifacts**: Agents that support MCP resources can read `session://last-search`, `session://last-search/pmids`, and `session://last-search/results` instead of reconstructing recent search state from chat context. When `unified_search` returns an `artifact_summary`, use its `artifact_uri` with `read_session(action="artifact", artifact_uri=...)`; inspect `audit.json`, `query_strategy.json`, and `results.json` or `results.toon` for complete evidence.7017023. **Parallel Execution**: When generating search strategies or PICO elements, call `generate_search_queries()` in parallel for efficiency.7037044. **MeSH Expansion**: `generate_search_queries()` automatically expands terms using NCBI MeSH database. This finds papers using different terminology but same concepts.7057065. **Rate Limits**: The server automatically handles NCBI API rate limits. No manual throttling needed.7077086. **Full Text Priority**:709 - Europe PMC: Best for medical/biomedical, structured XML710 - CORE: Best for broader coverage, includes preprints7117127. **Citation Metrics**: Use `get_citation_metrics()` with `sort_by="rcr"` to find high-impact papers (RCR = Relative Citation Ratio).713714---715716## 🔗 MCP Prompts Available717718The server provides pre-defined prompts for common workflows:719- `quick_search` - Fast topic search720- `systematic_search` - Comprehensive MeSH-expanded search721- `pico_search` - Clinical question decomposition722- `explore_paper` - Deep exploration from a key paper723- `gene_drug_research` - Gene or drug focused research724- `export_results` - Export and full text access725- `find_open_access` - Find OA versions726- `literature_review` - Full review workflow727- `text_mining_workflow` - Extract entities from papers728729Use `prompts/list` to see available prompts, `prompts/get` to retrieve guidance.730
Also in u9401066/pubmed-search-mcp
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| u9401066/pubmed-search-mcp.clinerules/30-citation-ready.md · 23 | Cline rules | styledo-not | 36/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/60-pubmed-python.md · 23 | Cline rules | setuptestlint-formatstyle+2 | 86/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/80-pubmed-release.md · 23 | Cline rules | testlint-formatdeploymentdo-not | 68/100 | 3 days ago | |
| u9401066/pubmed-search-mcpAGENTS.md · 23 | AGENTS.md | teststyledo-notagent-behaviour | 86/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/30-mcp-surface-and-sync.md · 23 | Cline rules | do-not | 23/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/00-project.md · 23 | Cline rules | testlint-formatstylearch+1 | 86/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/00-workspace-baseline.md · 23 | Cline rules | monorepo | 16/100 | yesterday | |
| u9401066/pubmed-search-mcp.clinerules/00-zotero-project.md · 23 | Cline rules | testlint-formatstylearch+2 | 74/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/10-python-ddd.md · 23 | Cline rules | testlint-formatdo-not | 39/100 | yesterday | |
| u9401066/pubmed-search-mcp.clinerules/10-python.md · 23 | Cline rules | setuptestlint-formatstyle+1 | 78/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/10-zotero-python.md · 23 | Cline rules | setuptestlint-formatstyle+1 | 71/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/20-docs-and-generated-assets.md · 23 | Cline rules | styledo-notdocs | 35/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/20-vscode-extension.md · 23 | Cline rules | teststyledo-not | 55/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/20-zotero-vscode-extension.md · 23 | Cline rules | teststyledo-not | 69/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/30-zotero-research-workflow.md · 23 | Cline rules | styledo-notagent-behaviour | 50/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/35-foam-llm-wiki.md · 23 | Cline rules | styledo-notagent-behaviour | 55/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/40-release.md · 23 | Cline rules | testlint-formatdeploymentdo-not | 74/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/40-zotero-release.md · 23 | Cline rules | testlint-formatdeploymentdo-not | 67/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/50-pubmed-project.md · 23 | Cline rules | testlint-formatstylearch+1 | 94/100 | 3 days ago | |
| u9401066/pubmed-search-mcp.clinerules/70-pubmed-mcp-tools.md · 23 | Cline rules | apido-notagent-behaviourdocs | 59/100 | yesterday |
Diff against .clinerules/30-citation-ready.md Diff against .clinerules/60-pubmed-python.md Diff against .clinerules/80-pubmed-release.md Diff against AGENTS.md Diff against .clinerules/30-mcp-surface-and-sync.md Diff against .clinerules/00-project.md Diff against .clinerules/00-workspace-baseline.md Diff against .clinerules/00-zotero-project.md Diff against .clinerules/10-python-ddd.md Diff against .clinerules/10-python.md Diff against .clinerules/10-zotero-python.md Diff against .clinerules/20-docs-and-generated-assets.md Diff against .clinerules/20-vscode-extension.md Diff against .clinerules/20-zotero-vscode-extension.md Diff against .clinerules/30-zotero-research-workflow.md Diff against .clinerules/35-foam-llm-wiki.md Diff against .clinerules/40-release.md Diff against .clinerules/40-zotero-release.md Diff against .clinerules/50-pubmed-project.md Diff against .clinerules/70-pubmed-mcp-tools.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| pytorch/pytorch.github/copilot-instructions.md · 102k | Copilot instructions | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| JCodesMore/ai-website-cloner-template.github/copilot-instructions.md · 31k | Copilot instructions | buildlint-formatstylearch+3 | 97/100 | 2 days ago | |
| hiyouga/LlamaFactory.github/copilot-instructions.md · 74k | Copilot instructions | setupbuildtestlint-format+5 | 97/100 | 2 days ago | |
| bagisto/bagisto.github/copilot-instructions.md · 28k | Copilot instructions | setupbuildteststyle+5 | 97/100 | 3 days ago | |
| darkmatter/nixmac.github/copilot-instructions.md · 24 | Copilot instructions | setupbuildtestlint-format+8 | 96/100 | 3 days ago | |
| iloveitaly/llm-ide-rules.github/copilot-instructions.md · 13 | Copilot instructions | teststyledo-notagent-behaviour+1 | 92/100 | 3 days ago | |
| photoprism/photoprism.github/copilot-instructions.md · 40k | Copilot instructions | buildtestlint-formatstyle+5 | 90/100 | 2 days ago | |
| BryaanF/LiantPortfolio.github/copilot-instructions.md · 0 | Copilot instructions | setupbuildstylearch+4 | 89/100 | 3 days ago |
