Skip to main content
Glama

PubMed Search MCP

PyPI version Python 3.10+ License: Apache 2.0 MCP CI

AIエージェントのためのプロフェッショナル文献リサーチアシスタント - 単なるAPIラッパーではありません

PubMed Search MCP research workflow

AIエージェント向けのインテリジェントなリサーチアシスタントとして機能する、ドメイン駆動設計(DDD)ベースのMCPサーバーです。タスク指向の文献検索・分析機能を提供します。

✨ 含まれるもの:

  • 🔧 45個のMCPツール - PubMed、Europe PMC、CORE、NCBIデータベースへの効率的なアクセス、およびResearch Chronicle / Context Graph

  • 🛡️ マルチエージェントサービスモード - 一度デプロイすれば多くのエージェントに提供可能: テナントごとのセッション、キャッシュ、アーティファクト、ベアラートークン認証、テナントごとのフェアシェア制限。 DEPLOYMENT.md を参照

  • 🖼️ OA図の抽出 - PMCオープンアクセス論文から図のキャプション、直接画像URL、PDFリンクを取得

  • 📘 ドキュメントサイト - 言語切替対応の完全なハンドブックを閲覧: ユーザーワークフロー、アーキテクチャ、45ツールリファレンス、パイプラインチュートリアル、ソース/ブローカー契約、統合と運用、セキュリティ、デプロイメントは u9401066.github.io/pubmed-search-mcp を参照

  • 📖 GitHub Wiki - 同じ正規ドキュメントのGitHubネイティブミラー: github.com/u9401066/pubmed-search-mcp/wiki

  • 📚 26のClaudeスキル - AIエージェント向けのすぐ使えるワークフローガイド(Claude Code専用)

  • 📖 Copilot Instructions - VS Code GitHub Copilot統合ガイド

🌐 言語: English | 繁體中文

📘 ドキュメントマップ: READMEはプロジェクトへのクイックエントリーポイントです。最適な読書体験にはドキュメントサイト、GitHubネイティブなナビゲーションにはGitHub Wiki、編集用のソースドキュメントは以下を参照: ユーザーガイド | 高度なワークフロー | 機能ファーストガイド | プロバイダーデータプレーン | BioMCPアーキテクチャ分析 | 開発者ガイド | 完全な索引


🚀 クイックインストール

前提条件

  • Python 3.10+ — ダウンロード

  • uv (推奨) — uvをインストール

    # macOS / Linux
    curl -LsSf https://astral.sh/uv/install.sh | sh
    # Windows
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
  • NCBI Email — NCBI APIポリシーで必須。任意の有効なメールアドレス。

  • NCBI API Key (任意) — レート制限の引き上げ(3 req/s に対して 10 req/s)のためこちらで取得

  • OpenAlex API Key (任意) — 認証済みクレジット割り当てを使用するには OPENALEX_API_KEY を設定します。設定しない場合、リクエストはOpenAlexの現在の匿名カジュアル利用予算を使用します。 mailto は連絡先メタデータであり、認証ではありません。ソース固有のメールがない場合、サーバーはOpenAlex、CrossRef、Unpaywallに対して設定済みのランタイム連絡先メールを再利用します。

インストールと実行

# Option 1: Zero-install with uvx (recommended for trying out)
uvx pubmed-search-mcp

# Option 2: Add as project dependency
uv add pubmed-search-mcp

# Option 3: pip install
pip install pubmed-search-mcp

Python SDKファサード

プロセス内Python統合には、MCPツールモジュールをインポートする代わりに安定したSDKファサードを使用してください:

from pubmed_search.api import PubMedSearchClient, PubMedSearchConfig

client = PubMedSearchClient(PubMedSearchConfig(email="your@email.com"))
result = await client.unified_search("remimazolam ICU sedation", limit=20)

print(result.articles)
print(result.source_counts)
print(result.artifact)  # artifact locator when persistence is enabled

エージェントツールの検出には uvx pubmed-search-mcp または /mcp を使用します。型付きオブジェクトがMCPレスポンス文字列の解析より簡単なPythonパッケージ/ノートブック呼び出しにはSDKを使用してください。

ランタイム契約の選択

契約

コマンド

ネットワークと信頼境界

ローカル stdio

uvx pubmed-search-mcp

ローカルAIクライアント1台に推奨。MCPポートをリッスンしません

ローカルループバックHTTP

pubmed-search-mcp-http --mode local --host 127.0.0.1

信頼できるシングルユーザー統合。MCPリクエストは永続的なdefaultテナントを共有し、ポートを公開してはなりません

マルチユーザーサービス

pubmed-search-mcp-http --mode service

HTTPS経由のリモート/チーム利用。ベアラー認証、許可されたホスト/オリジン、プリンシパルごとのストレージが必須です

ローカル展開とサービス展開は意図的に別々の契約です。バインドアドレスだけを変更してローカルHTTPコマンドを公開サービスにしないでください。明示的なローカルプロファイルは、pmids="last"、セッション、キャッシュ、エクスポートをMCPリクエスト間および再接続時にも永続的なdefaultテナントに保持します。これは強制されたループバック/Host/Origin境界内でのみ安全です。サービスの環境とComposeプロファイルについてはDEPLOYMENT.mdを参照してください。現在のサービスプロファイルは1つのサーバープロセスで多くの認証済みプリンシパルをサポートします。セッション、ロック、アーティファクト、サブスクリプションに共有バックエンドができるまでレプリカは1台に保ってください。

プロトコルベースラインはMCP SDK v2(mcp>=2.0,<3)です。最新の2026-07-28クライアントはinitializeハンドシェイクやMcp-Session-Idなしでtools/listとtools/callを直接送信します。ローカルモードはファイルシステム機能を保持します。認証済みサービス呼び出し元はfile:パイプラインをロードしたり、ノートoutput_dir/template_fileを選択したり、プロセス全体のパイプラインワークスペースを継承したりできません。サービスComposeスケジューラは無効です。機能マトリックスについては統合・運用ガイドを参照してください。


Related MCP server: ScholarMCP

⚙️ 設定

このMCPサーバーはあらゆるMCP互換AIツールで動作します。お好みのクライアントを選択してください:

VS Code / Cursor (.vscode/mcp.json)

{
  "servers": {
    "pubmed-search": {
      "type": "stdio",
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com"
      }
    }
  }
}

任意: ブラウザセッションPDFフォールバックを一度有効にすると、ツールが自動的に使用します:

{
  "servers": {
    "pubmed-search": {
      "type": "stdio",
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com",
        "BROWSER_FETCH_CONFIG": "{\"enabled\":true,\"auto_enabled\":true,\"broker_url\":\"http://127.0.0.1:8766/fetch\",\"token\":\"<random-32-byte-token>\",\"allowed_hosts\":[\"jamanetwork.com\",\"*.jamanetwork.com\",\"nejm.org\",\"*.nejm.org\"]}"
      }
    }
  }
}

この設定により、get_fulltextは機関向けまたは出版社のランディングページに対してローカルブローカーを自動的に試行します。特定の呼び出しで抑制したい場合のみ allow_browser_session=false を渡してください。

ダウンロードインターセプト付きでローカルブローカーを実行:

uv sync --extra browser-broker
uv run playwright install chromium
uv run python -c "import secrets; print(secrets.token_urlsafe(32))"
uv run pubmed-browser-fetch-broker --token "<same-random-32-byte-token>"

生成された値を両方のコマンド/設定にコピーしてください。公開されているサンプルトークンを再利用しないでください。--tokenを省略すると、ブローカーは高エントロピーのランタイムトークンを生成して出力します。ブローカーはダウンロードインターセプトが有効な永続ブラウザプロファイルを起動します。そのブローカー制御のブラウザウィンドウ内で一度ログインすると、以降のPDFダウンロードはネイティブの「Save As」ダイアログなしで自動的にキャプチャされます。

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "pubmed-search": {
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com"
      }
    }
  }
}

設定ファイルの場所:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

Claude Code

claude mcp add pubmed-search -- uvx pubmed-search-mcp

またはプロジェクトルートの .mcp.json に追加:

{
  "mcpServers": {
    "pubmed-search": {
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com"
      }
    }
  }
}

Zed AI (settings.json)

Zedエディタ(z.ai)はMCPサーバーをネイティブにサポートします。Zedのsettings.jsonに追加:

{
  "context_servers": {
    "pubmed-search": {
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com"
      }
    }
  }
}

ヒント: コマンドパレットを開いて zed: open settings を実行して編集するか、Agent Panel → Settings → "Add Custom Server" に移動します。

OpenClaw 🦞 (~/.openclaw/openclaw.json)

OpenClawはmcp-adapterプラグインを介してMCPサーバーを使用します。最初にアダプターをインストール:

openclaw plugins install mcp-adapter

次に ~/.openclaw/openclaw.json に追加:

{
  "plugins": {
    "entries": {
      "mcp-adapter": {
        "enabled": true,
        "config": {
          "servers": [
            {
              "name": "pubmed-search",
              "transport": "stdio",
              "command": "uvx",
              "args": ["pubmed-search-mcp"],
              "env": {
                "NCBI_EMAIL": "your@email.com"
              }
            }
          ]
        }
      }
    }
  }
}

設定後、ゲートウェイを再起動:

openclaw gateway restart
openclaw plugins list  # Should show: mcp-adapter | loaded

Cline (cline_mcp_settings.json)

{
  "mcpServers": {
    "pubmed-search": {
      "command": "uvx",
      "args": ["pubmed-search-mcp"],
      "env": {
        "NCBI_EMAIL": "your@email.com",
        "S2_API_KEY": "your_semantic_scholar_key",
        "PUBMED_SEARCH_DISABLED_SOURCES": ""
      },
      "alwaysAllow": [],
      "disabled": false
    }
  }
}

その他のMCPクライアント

MCP互換クライアントはstdioトランスポート経由でこのサーバーを使用できます:

# Command
uvx pubmed-search-mcp

# With environment variable
NCBI_EMAIL=your@email.com uvx pubmed-search-mcp

注: NCBI_EMAIL はNCBI APIポリシーで必須です。レート制限を上げるには任意で NCBI_API_KEY を設定してください(3 req/s に対して 10 req/s)。 📖 詳細な統合ガイド: すべての環境変数、Copilot Studioのセットアップ、Dockerデプロイ、プロキシ設定、トラブルシューティングについてはdocs/INTEGRATIONS.mdを参照してください。


🎯 設計思想

中核となる位置付け: AIエージェントと学術検索エンジンの間のインテリジェントミドルウェア。

なぜこのサーバーなのか?

他のツールは生のAPIアクセスを提供します。当社は語彙変換+インテリジェントルーティング+リサーチ分析を提供します:

課題

当社のソリューション

エージェントがICDコードを使用、PubMedはMeSHが必要

✅ 自動ICD→MeSH変換

複数のデータベース、異なるAPI

✅ 統合検索 単一エントリポイント

臨床質問には構造化検索が必要

✅ PICOハンドオフ+パイプライン(parse_picoはエージェント提供のP/I/C/Oを検証し、実行可能なtemplate: picoパイプラインを返します)

医療用語のタイプミス

✅ ESpell自動修正

1つのソースから多すぎる結果

✅ 並列マルチソース 重複排除付き

研究の進化を追跡する必要がある

✅ Research Chronicle & Tree ランドマーク検出、診断、サブトピック分岐、バージョン管理されたリビジョン付き

引用コンテキストが不明確

✅ Citation Tree 前方/後方/ネットワーク

全文にアクセスできない

✅ マルチソース全文(Europe PMC XML、Unpaywall OAロケーション、機関直接/EZproxy、CORE、ダウンローダーフォールバック)

遺伝子/薬剤情報がDBに分散

✅ NCBI Extended(Gene、PubChem、ClinVar)

最先端のプレプリントが必要

✅ プレプリント検索(arXiv、medRxiv、bioRxiv)査読フィルタリング付き

参考文献管理ツールへのエクスポート

✅ ワンクリックエクスポート(公式RIS/MEDLINE/CSL JSON、ローカルRIS/BibTeX/CSV/MEDLINE/JSON)

主な差別化ポイント

  1. 語彙変換レイヤー - エージェントは自然に話し、各データベースの用語体系(MeSH、ICD-10、テキストマイニングされたエンティティ)に変換します

  2. 統合検索ゲートウェイ - 1回の unified_search() 呼び出しで、PubMed、Europe PMC、CORE、OpenAlex、Semantic Scholar、および有効化されたプレプリント・商用ソースに対して、機能を認識したディスパッチを行います

  3. PICOハンドオフ + パイプライン - エージェントがP/I/C/Oを抽出し、parse_pico() がその構造化ハンドオフを検証し、バックエンドの template: pico パイプラインがOを考慮した精度/再現率検索を実行します

  4. 研究クロニクルと系統ツリー - ポリシー駆動のヒューリスティックでマイルストーンを検出し、マルチシグナルスコアリングでランドマーク論文を特定し、診断情報を提示し、差分を確認できるバージョン管理されたリビジョンを保持し、研究の進化をサブトピックごとの分岐ツリーとして可視化します

  5. 引用ネットワーク分析 - 単一の論文から研究全体の状況を把握するための多段階引用ツリーを構築します

  6. 研究ライフサイクル全体 - 検索 → 発見 → 全文 → 分析 → エクスポートまで、すべてを1つのサーバーで実現

  7. エージェントファースト設計 - 人間が読むためではなく、機械の意思決定に最適化された出力


📡 外部APIとデータソース

このMCPサーバーは、複数の学術データベースおよびAPIと統合されています:

コアデータソース

ソース

対象範囲

語彙

自動変換

説明

NCBI PubMed

36M+ 論文

MeSH

✅ ネイティブ

主要な生物医学文献

NCBI Entrez

マルチDB

MeSH

✅ ネイティブ

遺伝子、PubChem、ClinVar

Europe PMC

33M+

テキストマイニング

✅ 抽出

全文XMLアクセス

CORE

200M+

なし

➡️ フリーテキスト

オープンアクセスアグリゲータ

Semantic Scholar

進化するグラフ + オペレータデータセット

S2フィールド / バルク構文

✅ ブローカーコンパイル済みモード

関連性、制限付きバルク、バッチ、引用グラフ、およびメタデータのみのリリース/差分プレーン。パーティションのダウンロードなし

OpenAlex

進化するオープン研究グラフ

トピック / キーワード

✅ キーワード + 制限付きネイティブセマンティック

カーソル、コストの来歴、エンティティグラフ、および宣言されたオペレータースナップショットパス。ローカルインデックスはまだなし

NIH iCite

PubMed

N/A

N/A

引用メトリクス(RCR)

🔑 キー: ✅ = 完全な語彙サポート | ➡️ = クエリパススルー(統制語彙なし)

ICDコード: PubMed検索の前に自動検出されMeSHに変換されます

環境変数

# Required
NCBI_EMAIL=your@email.com          # Required by NCBI policy

# Optional - For higher rate limits
NCBI_API_KEY=your_ncbi_api_key     # Get from: https://www.ncbi.nlm.nih.gov/account/settings/
CORE_API_KEY=your_core_api_key     # Get from: https://core.ac.uk/services/api
CROSSREF_EMAIL=your@email.com      # Optional override; defaults to server/NCBI email
UNPAYWALL_EMAIL=your@email.com     # Optional override; defaults to server/NCBI email
S2_API_KEY=your_s2_api_key         # Alias: SEMANTIC_SCHOLAR_API_KEY
OPENALEX_API_KEY=your_openalex_key # Raises the OpenAlex credit budget; actual grant is response-driven
PUBMED_SEARCH_DISABLED_SOURCES=    # Example: semantic_scholar

# Optional - Network settings
HTTP_PROXY=http://proxy:8080       # HTTP proxy for API requests
HTTPS_PROXY=https://proxy:8080     # HTTPS proxy for API requests

# Optional - Institutional fulltext access
INSTITUTIONAL_DIRECT_FETCH=true    # Try DOI publisher pages before CORE fallback
EZPROXY_ENABLED=false              # Enable only after configuring EZPROXY_HOST + cookie
EZPROXY_HOST=ezproxy.example.edu
EZPROXY_COOKIE_FILE=/path/to/cookies.json

# Optional - Local note export
PUBMED_NOTES_DIR=/path/to/wiki/references  # save_literature_notes target folder
PUBMED_WORKSPACE_DIR=/path/to/project       # fallback: references/ under this workspace
PUBMED_DATA_DIR=~/.pubmed-search-mcp        # fallback: references/ under this data dir

CrossRefとUnpaywallは、ソース固有のメールが設定されていない限り、ランタイムサーバーの連絡先メール(NCBI_EMAIL、CLIの--email、または検出されたgitメール)を再利用します。OpenAlexはカジュアルな匿名利用とオプションのAPIキーを受け入れます。ブローカーは、永続的な「ポライトプール」クォータを想定する代わりに、応答のクレジット/レートメタデータを読み取ります。

ローカルノートのエクスポートは、output_dir引数、PUBMED_NOTES_DIR、PUBMED_WORKSPACE_DIR/references、PUBMED_DATA_DIR/references、次に~/.pubmed-search-mcp/referencesの順にディレクトリを解決します。 このパス/テンプレート選択は、信頼できるローカルモードにのみ適用されます。認証済みサービスノートは、常に現在のテナントの分離されたreferences/ディレクトリの下にある組み込み形式を使用します。 LLMウィキ互換性のため、wikiおよびfoamエクスポートはPMID、DOI、PMCID、またはフォールバック識別子に基づく安定したリンクターゲットを使用します。タイトルはエイリアス/表示ラベルのままとなり、応答には未解決のウィキリンクチェック用のwiki_validationが含まれます。

🔄 仕組み:ミドルウェアアーキテクチャ

┌─────────────────────────────────────────────────────────────────────────────┐
│                              AI AGENT                                        │
│                                                                              │
│   "Find papers about I10 hypertension treatment in diabetic patients"       │
│                                                                              │
└─────────────────────────────────┬───────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                     🔄 PUBMED SEARCH MCP (MIDDLEWARE)                        │
│  ┌─────────────────────────────────────────────────────────────────────────┐│
│  │  1️⃣ VOCABULARY TRANSLATION                                              ││
│  │     • ICD-10 "I10" → MeSH "Hypertension"                                ││
│  │     • "diabetic" → MeSH "Diabetes Mellitus"                             ││
│  │     • ESpell: "hypertention" → "hypertension"                           ││
│  └─────────────────────────────────────────────────────────────────────────┘│
│  ┌─────────────────────────────────────────────────────────────────────────┐│
│  │  2️⃣ INTELLIGENT ROUTING                                                 ││
│  │     ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐             ││
│  │     │ PubMed   │  │Europe PMC│  │   CORE   │  │ OpenAlex │             ││
│  │     │  36M+    │  │   33M+   │  │  200M+   │  │  250M+   │             ││
│  │     │  (MeSH)  │  │(fulltext)│  │  (OA)    │  │(metadata)│             ││
│  │     └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘             ││
│  │          └──────────────┴──────────────┴──────────────┘                 ││
│  │                              ▼                                          ││
│  │  3️⃣ RESULT AGGREGATION: Dedupe + Rank + Enrich                         ││
│  └─────────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────┬───────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         UNIFIED RESULTS                                      │
│   • 150 unique papers (deduplicated from 4 sources)                          │
│   • Ranked by relevance + citation impact (RCR)                              │
│   • Full text links enriched from Europe PMC                                 │
└─────────────────────────────────────────────────────────────────────────────┘

🛠️ MCPツール概要

ツールの全体像を使えるシステムとして理解したいなら、45個のツール名を暗記することから始めないでください。

ツール使用ガイドから始めてください。そこには現在の45ツールが8つの機能ファミリーに圧縮され、理論上の下限が説明され、人間とエージェントの両方に対する意図ベースのルーティングが示されています。

🔍 検索とクエリインテリジェンス

検索とクエリインテリジェンスのワークフロー

┌─────────────────────────────────────────────────────────────────┐
│                      SEARCH ENTRY POINT                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   unified_search()          ← 🌟 Single entry for all sources    │
│        │                                                         │
│        ├── Quick search     → Direct multi-source query          │
│        ├── Native semantic → Bounded OpenAlex semantic mode    │
│        ├── Systematic       → Bounded provider bulk/cursor mode  │
│        ├── PICO hints       → Detects comparison, shows P/I/C/O  │
│        └── ICD expansion    → Auto ICD→MeSH conversion           │
│                                                                  │
│   Sources: PubMed · Europe PMC · CORE · OpenAlex · S2            │
│   Auto: Deduplicate → Rank → Enrich full-text links              │
│                                                                  │
├─────────────────────────────────────────────────────────────────┤
│   QUERY INTELLIGENCE                                             │
│                                                                  │
│   generate_search_queries() → MeSH expansion + synonym discovery │
│   parse_pico()              → Agent-provided PICO handoff        │
│   analyze_search_query()    → Query analysis without execution   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

1つの検索エントリ、3つの取得ポリシー

一般的な文献発見は、意図的に正確に1つのMCPツールunified_searchとして公開されています。プロバイダー固有のAPIは、内部ブローカー機能のままです。

# Default relevance/keyword routing across enabled sources
unified_search(query="treatment resistance")

# OpenAlex native semantic search (provider maximum 50 results)
unified_search(
    query="mechanisms of treatment resistance",
    sources="openalex",
    options="native_semantic",
)

# Deterministic/bounded retrieval: OpenAlex cursor and S2 bulk where selected
unified_search(
    query="melanoma AND immunotherapy",
    sources="pubmed,openalex,semantic_scholar",
    options="systematic",
)

native_semanticとsystematicは相互排他的であり、マルチストラテジーのディープサーチ展開を無効にします。要求された取得モードがサポートされていない場合、明示的なソース選択はネットワーク呼び出しの前に失敗します。自動ソース選択は、対応可能なプロバイダーのみを保持します。limitはソースごとに最大100のままなので、systematicは決定論的で制限付きのプロバイダー実行を意味し、網羅的な系統的レビューの保証ではありません。構造化出力とアーティファクトは、retrieval_modeに加えてソースごとのsource_metadata(要求/プロバイダーモード、正規またはコンパイル済みクエリ、継続可能性、コスト/レートメタデータ、利用可能な場合は警告)を記録します。

公開リクエスト境界はフェイルクローズドです。limitは1から100までの整数である必要があります。不明または不正なfilters/options、逆順または範囲外の年、サポートされていないランキングまたは出力モードは、プロバイダーI/Oの前に検証エラーを返します。デフォルトのディープサーチポリシーでは、limitはそのソースのクエリ戦略全体に分割されるソースごとの合計予算であり、すべての戦略に対するlimit件の結果ではありません。戦略呼び出しは、グローバル/ソースごとの制限付き同時実行とタイムアウトを使用し、別のソースがタイムアウト、レート制限、または失敗した場合でも、成功したソースは使用可能なままです。

Europe PMC、Scopus、Web of Scienceは今リリースではキーワードのみのままです。これらのソースに対する明示的な系統的リクエストは、単一ページを系統的カバレッジと誤って表示する代わりに、I/Oの前に失敗します。

プロバイダーの制限とオペレーターのデータプレーン境界については、ソース契約、Semantic Scholar、OpenAlexを参照してください。

🔬 発見ツール(重要な論文を見つけた後)

論文発見と引用のワークフロー

                        Found important paper (PMID)
                                   │
           ┌───────────────────────┼───────────────────────┐
           │                       │                       │
           ▼                       ▼                       ▼
    ┌─────────────┐        ┌─────────────┐        ┌─────────────┐
    │  BACKWARD   │        │  SIMILAR    │        │  FORWARD    │
    │  ◀──────    │        │  ≈≈≈≈≈≈     │        │  ──────▶    │
    │             │        │             │        │             │
    │ get_article │        │find_related │        │find_citing  │
    │ _references │        │ _articles   │        │ _articles   │
    │             │        │             │        │             │
    │ Foundation  │        │  Similar    │        │ Follow-up   │
    │  papers     │        │   topic     │        │  research   │
    └─────────────┘        └─────────────┘        └─────────────┘

    fetch_article_details()   → Detailed article metadata
    get_citation_metrics()    → iCite RCR, citation percentile
    build_citation_tree()     → Full network visualization (6 formats)

📚 全文、図の抽出、エクスポート

全文、図、および生物医学画像のワークフロー

カテゴリ

ツール

全文

get_fulltext → PMCIDが利用可能な場合はEurope PMC XML。必要な場合はDOI連携のUnpaywall、機関ダイレクト/EZproxy、CORE、ダウンローダーのフォールバック

図

get_article_figures → PMCオープンアクセス記事から図のラベル、キャプション、画像URL、PDFリンクを抽出

図対応の全文

get_fulltext(include_figures=True) → 図のメタデータを構造化全文と一緒に埋め込む

テキストマイニング

get_text_mined_terms → 遺伝子、疾患、化学物質を抽出

エクスポート

prepare_export → 公式RIS/MEDLINE/CSL JSONまたはローカルRIS/BibTeX/CSV/MEDLINE/JSON。save_literature_notes → ローカルwiki/Foam互換/Markdown/MedPaperスタイルのノートに加えて、コレクションレベルのCSL JSON

🖼️ OA図ファースト探索

エージェントが記事のテキストだけでなく証拠となる図を必要とする場合は、PMCオープンアクセスパスを使用します:

  • get_article_figures(identifier="PMC12086443") → 図のラベル、キャプション、画像URL、PDF/記事リンク

  • get_fulltext(pmcid="PMC7096777", include_figures=True) → 図をインラインに含む構造化全文

  • 図の出力は記事の文脈を保持するため、エージェントは各図をそれが言及されているセクションに接続できます

🧬 NCBI拡張データベース

NCBI拡張生物医学データワークフロー

ツール

説明

search_gene

NCBI Geneデータベースを検索

get_gene_details

NCBI Gene IDによる遺伝子詳細

get_gene_literature

遺伝子にリンクされたPubMed論文

search_compound

PubChem化合物を検索

get_compound_details

PubChem CIDによる化合物詳細

get_compound_literature

化合物にリンクされたPubMed論文

search_clinvar

ClinVarの臨床バリアントを検索

🕰️ 研究クロニクルと系統ツリー

評価とタイムラインのワークフロー

ツール

説明

build_research_chronicle

ランドマーク検出を備えた、永続化・バージョン管理されたクロニクルを構築します。出力: summary、chronicle_map、timeline、tree、graph、evidence、milestones、mermaid、timeline_mermaid、mindmap、narrative、json

read_research_chronicle

リビジョンのロード、一覧表示、差分、引用付きのナレーション、マイルストーン分布の分析、または最大5つのトピックの比較

mermaidは標準の結合ビューです。水平の年軸を持ち、観測された各研究ラインが、取得された範囲内で最も古い日付の論文で分岐します。これは説明可能なグループ化であり、因果関係の系譜や、その分野の真の最初の論文に関する主張ではありません。系統は、複数の論文で共有されているMeSH記述子と著者キーワードを優先します。シングルトンしかない、または不十分なシグナルの場合は、警告付きの研究ステージフォールバックがトリガーされます。同年内の表示順は安定していますが、出版の精度がそれを証明できない場合に優先順位を主張するものではありません。timeline_mermaidは従来のフラットなタイムラインビューを維持します。実装された契約については、docs/RESEARCH_CHRONICLE_REFACTOR_SPEC.mdを参照してください。

Chronicle Mermaid の出力は、構造化されたノードとエッジから構築され、安全なラベルエスケープ、サイクル/孤立ノードの修復、衝突耐性のある ID、グラフサイズの制限を備えています。クロニクル全体を失敗させる代わりに、リッチ構文からセーフ構文、最小構文へとフォールバックします。mermaid_validation.json はすべての修正、フォールバック、省略された視覚アイテムを記録し、chronicle.mmd は純粋な Mermaid ソースのままです。

Chronicle のリビジョンは不変であり、アトミックに追記されます。セッションの成果物(アーティファクト)永続化が有効な場合、アーティファクトの失敗は明示的に表面化されますが、保存された Chronicle のリビジョンは引き続き利用可能です。

トピック構築は、境界付き取得の前に年制限を PubMed に送信し、上限をランドマークと時間的広がりで埋めながら、最初と最後に観測された論文を保持します。監査は PubMed の returned / available カウントを記録し、可用性が不明な場合、または取得/選択の上限によってビューが非網羅的になる場合に警告します。PubMed エラーや記事エビデンスのないスコープでは、空のリビジョンを公開しません。

明示的な PMID 入力は厳格です(12345678 または PMID:12345678、正の ASCII 数字、最大 20 桁)。DOI や混在テキストは強制変換されずに拒否されます。信頼できる発行日がないレコードは、日付付きエントリの後に Undated として表示され、表示される年範囲から除外されます。エントリ ID は、日付や分類子の修正をまたいで PMID/DOI のエビデンス同一性に従い、トピックの連続性は 1 つの Unicode/大文字小文字/空白の正規化キーを使用します。複数シグナルの論文は、1 つのプライマリブランチと明示的な相互リンクを維持します。20% 以上の重複は警告として監査されます。リビジョンの差分では、不在は not_observed_in_revision / removed_from_view を意味し、決定的な退役を意味しません。

🏥 機関アクセスと ICD 変換

Institutional access workflow

ツール

説明

configure_institutional_access

機関のリンクリゾルバを構成する

get_institutional_link

OpenURL アクセスリンクを生成する

list_resolver_presets

リゾルバのプリセットを一覧表示する

test_institutional_access

リゾルバの構成をテストする

diagnose_institutional_access

直接 DOI、EZproxy、OpenURL ハンドオフ経路を診断する

convert_icd_mesh

ICD コードと MeSH 用語を相互変換する(双方向)

unified_search

クエリ内の ICD コードを自動検出し、MeSH に展開する

💾 セッション管理

Session and pipeline workflow

ツール

説明

get_session_pmids

キャッシュされた PMID リストを取得する

get_cached_article

セッションキャッシュから記事を取得する(API コストなし)

get_session_summary

セッションステータスの概要

read_session

PMID、キャッシュされた記事、永続的な検索実行、リプレイ引数、履歴、永続的アーティファクトのファサード

動的 MCP リソースも、リソースを直接読み取れるエージェント向けに利用できます。

  • session://context — アクティブなセッションステータス

  • session://last-search — 最新の検索メタデータ

  • session://last-search/pmids — 最新の PMID リスト + CSV 形式

  • session://last-search/results — 最新の検索用にキャッシュされた記事ペイロード

永続的アーティファクト

セッション永続化が構成されている場合、再利用可能な unified_search および get_fulltext レスポンスに対して、永続的な MCP 出力アーティファクトが保存されます。ツールのレスポンスはインデックスカードのように機能します。エージェントが即座に回答できるだけのカウント、ソース警告、アーティファクトのヒントが含まれる一方、完全なエビデンスペイロードは繰り返し読み取れるファイルに保持されます。コンパクトな artifact ロケーターには、artifact_id、artifact_uri、primary_file、summary、ファイルインベントリ、read_order、監査ステータス、正確な read_session(...) 取得ヒントが含まれます。ローカル MCP クライアントが local_path と manifest_path も直接受け取る必要がある場合にのみ、PUBMED_ARTIFACT_INCLUDE_LOCAL_PATHS=true を設定してください。

サーバーのファイルシステムを読み取れないリモートクライアントは、セッションファサードを通じて同じコンテンツを取得できます。

read_session(action="list_artifacts")
read_session(action="artifact", artifact_id="...")
read_session(action="artifact", artifact_uri="artifact://...")
read_session(action="artifact", artifact_uri="artifact://...", artifact_file="audit.json")
read_session(action="artifact", artifact_uri="artifact://...", artifact_file="query_strategy.json")
read_session(action="artifact", artifact_uri="artifact://...", artifact_file="results.json", offset=0, max_chars=200000)
read_session(action="list_artifacts", include_local_paths=true)

リカバリ可能な検索実行

セッション管理がアクティブな場合、すべての unified_search 呼び出しは安定した実行 ID を受け取ります。これには、通常の検索、検証/計画の失敗、インライン、saved:<name>、または dry_run=true のパイプライン実行が含まれます。構造化された結果とエラーには search_run ハンドオフが添付されます。Markdown は同じ実行 ID をコンパクトなリカバリノートとして返します。通常の文献結果エンベロープは、2 つの別々のマシン契約を公開します。

  • search_status は境界付き取得の結果を説明します: state (completed、empty、partial、または failed)、bounded=true、exhaustive=false、返された件数、試行済み/成功/失敗/再試行可能なソース、継続/完全性不明のソースリスト。

  • search_run はリカバリのハンドオフです: 安定した run_id、ジャーナルステータス、recoverable、正確な read_session の検査/リプレイ引数、およびコミットされた場合のアーティファクト URI。

テナントスコープの search-run/v1 ジャーナルは、プロバイダー I/O または終端検証レスポンスの前に公開され、サニタイズされたリクエスト、計画、物理的なソース別またはパイプラインステップ別の試行、カウント、安全な失敗、結果参照、該当する場合はアーティファクトロケーターを記録します。これは終端状態 completed、partial、failed、または cancelled に到達します。有効なゼロ結果検索は、search_status.state が empty である completed 実行です。再起動時、未完了の started / planned / running エントリは消える代わりに、一度だけ interrupted としてリカバリされます。非ドライランの保存済みパイプラインは、さらに PipelineStore のレポート/実行履歴を保持します。これは呼び出しレベルの検索ジャーナルを補完するものであり、その代替ではありません。

パイプラインのリプレイは、元のインラインまたは saved:<name> 引数に加えて dry_run / stop_at を保持します。キー、トークン、クッキー、パスワード、その他の資格情報を含むパイプラインテキストは拒否され、失敗した実行として記録されます。プロバイダーの資格情報はサーバーの環境/構成に属するものであり、パイプラインの YAML や JSON には決して含めません。

read_session(action="search_runs")
read_session(action="search_runs", run_status="partial")
read_session(action="search_run", run_id="...")
read_session(action="replay_search", run_id="...")

replay_search は、元の資格情報を含まない unified_search kwargs のみを返します。ネットワーク呼び出しを自動的に実行することはありません。エージェントまたはユーザーがそれらを確認し、明示的に送信する必要があります。プロバイダーのカーソル/トークン値は、source_metadata と query_strategy.json 内で不透明な来歴として保持されますが、公開カーソル再開パラメータはまだないため、リプレイは新しい境界付き検索を開始します。

終端ジャーナルの書き込みをリカバリできない場合、レスポンスは search_run.status="history_unavailable"、history_available=false、意図された終端ステータス、および警告を報告します。永続的なリカバリが保証されないため、検査/リプレイアクションは意図的に省略されます。検索結果自体は引き続き使用できる可能性があります。

unified_search のアーティファクトはリサーチエンベロープを使用します。ソース数と完全性の警告については audit.json から始め、次に実行された正確なプランについては query_strategy.json、最後に完全な記事リストについては results.json / results.toon を使用します。これにより、学術的なトレーサビリティを失うことなく、MCP レスポンストークンを小さく保つことができます。

アーティファクトはすでに計算済みの結果オブジェクトから生成されるため、アーティファクトを読み取っても検索や全文取得は再実行されません。 アーティファクトディレクトリがアトミックに公開された後、セッションインデックスが更新される前にクラッシュが発生した場合、セッションの再ロードでは完全なチェックサム索引付きマニフェストのみを検出し、孤児となったアーティファクトを search_run_id によってその検索実行に再リンクします(古いアーティファクトには控えめなクエリマッチを使用)。read_session はデフォルトでローカルファイルシステムのパスを編集します。local_path と manifest_path はサーバーローカルパスであり、移植可能なクライアントパスではありません。get_fulltext からのアーティファクトには、購読または機関アクセスされたコンテンツを含む記事本文が含まれる場合があります。発行者、ライセンス、機関のアクセス条件に従って保存および共有してください。 大きな get_fulltext レスポンスは、アーティファクトが利用可能な場合、プレビューとしてインラインで返されます。アーティファクトロケーターを使用して、保存された全文コンテンツを取得してください。

1 つのソースが失敗しても検索全体が続行できる場合、JSON レスポンスには source_errors が含まれることがあります。Markdown レスポンスには Source warnings 行が表示されます。Semantic Scholar の HTTP 429 の場合は、S2_API_KEY / SEMANTIC_SCHOLAR_API_KEY を設定するか、後で再試行するか、sources="auto,-semantic_scholar" または PUBMED_SEARCH_DISABLED_SOURCES=semantic_scholar で一時的に除外してください。

パイプライン管理

Session and pipeline workflow

manage_pipeline は、パイプラインの CRUD、履歴、スケジュール設定の主要ファサードです。より具体的なパイプラインツールは、互換性ラッパーとして引き続き利用できます。

ツール

説明

manage_pipeline

保存、一覧表示、ロード、削除、履歴、スケジュールアクションの主要ファサード

save_pipeline

後で再利用するためのパイプライン構成を保存する(YAML/JSON、自動検証)

list_pipelines

保存済みパイプラインを一覧表示する(タグ/スコープでフィルタリング)

load_pipeline

保存名でロードする。信頼できるローカル呼び出し元はファイルをロードすることもできる

delete_pipeline

パイプラインとその実行履歴を削除する

get_pipeline_history

記事差分分析付きの実行履歴を表示する

schedule_pipeline

定期的なパイプラインスケジュールを作成、更新、または削除する

認証されたサービス呼び出し元は、テナント派生ストア内の名前付きパイプラインを使用します。workspace および file: アクセスはローカルのみです。サービス Compose プロファイルは、別途設計された単一リーダーなしではスケジュールを実行しません。

ステップバイステップのチュートリアル:

👁️ ビジョンと画像検索

Full text, figures, and biomedical image workflow

ツール

説明

analyze_figure_for_search

アップロードされた画像、画像 URL、またはデータ URI をエージェントビジョンに渡し、検索語の抽出を行う

search_biomedical_images

Open-i 全体で生物医学画像を検索する(X線、顕微鏡、写真、図)

ユーザーが画像を提供し、エージェントが最初にその意味を解釈する必要がある場合は、analyze_figure_for_search を使用します。このツールは MCP の ImageContent と、LLM エージェントが英語の生物医学用語を抽出するための指示を返します。その後、類似した Open-i 画像については search_biomedical_images を、関連論文については unified_search を続行します。

📄 プレプリント検索

unified_search の options フラグを使用して、arXiv、medRxiv、bioRxiv のプレプリントサーバーを検索します。

  • preprints: プレプリントサーバーを検索し、article_type=PREPRINT でプレプリントをメインの集約結果セットに統合します。

  • all_types: プレプリントサーバーのクロールなしでも、選択した学術ソースが返した非査読コンテンツを保持します。

推奨される組み合わせ:

  • 空の options: 査読済み結果のみ。プレプリント類似のレコードはフィルタリングされます。

  • options="preprints": arXiv、medRxiv、bioRxiv を検索し、それらのプレプリントをメイン結果とランキング/重複排除します。

  • options="preprints, all_types": 同じプレプリントサーバーのクロールに加え、選択したソースからの他の非査読レコードも保持されます。

  • options="all_types": プレプリントサーバーのクロールは行いませんが、検索ソースからの非査読アイテムは保持されます。

プレプリント検出 — 記事がプレプリントとして識別される条件:

  • ソースAPI(OpenAlex、CrossRef、Semantic Scholar)による記事タイプ

  • PubMed ID なしで arXiv ID が存在する

  • 既知のプレプリントサーバーのソースまたはジャーナル名

  • DOIプレフィックスがプレプリントサーバーと一致する(例: 10.1101/ → bioRxiv/medRxiv、10.48550/ → arXiv)

🌳 研究コンテキストグラフ

unified_search は、PMID に基づくランキング結果から構築された軽量な研究系統図ビューを追加できます:

オプションフラグ

説明

context_graph

現在の PMID ベースのランキングセットから軽量な研究コンテキストグラフプレビューを Markdown 出力に追加し、research_context を JSON 出力に含めます。

これは、エージェントが2回目の build_research_chronicle 呼び出しを行わずに迅速なテーマ分岐を必要とする場合に役立ちます。

🧪 臨床試験レジストリ補助

ClinicalTrials.gov は暗黙的に照会されることはありません。制限付きレジストリ補助が有用な場合は、Markdown 検索に options="trials" を追加してください。これは文献ソース計画やソース数とは別に保たれ、永続化アーティファクトはその切り詰められた物理クエリと結果を adjunct_queries の下に記録します。構造化 JSON/TOON 検索では、この表示専用の補助は実行されません。

unified_search(query="remimazolam ICU sedation", options="trials")

📊 件数優先オリエンテーション

unified_search は、ランキングリストを読む前にルーティング支援を求めるエージェント向けに、既存のソースカバレッジと意思決定ヒントを前面に出すこともできます:

オプションフラグ

説明

counts_first

ソース件数テーブル、カバレッジ概要、次のツール推奨をレスポンスに追加します

例:

unified_search(query="remimazolam ICU sedation", options="counts_first")

このモードは、エージェントがソースを拡張するか、リード PMID を検査するか、全文を取得するか、図を抽出するか、タイムライン探索に切り替えるかを決定する必要がある場合に役立ちます。

⏱️ MCP 進捗レポート

MCP クライアントが進捗トークンを提供すると、unified_search、build_research_chronicle、get_fulltext、get_text_mined_terms は主要フェーズの進捗更新を発行します。 これにより、長時間の検索中にエージェントが感じる「ブラックボックス」の待ち時間が短縮されます。 進捗コールバックはベストエフォートであり、ツール呼び出しがアクティブな間はサーバーによってキャンセルされないため、進捗通知のバックプレッシャーによるホスト側の Canceled: Canceled メッセージを回避できます。


📋 エージェント使用例

1️⃣ クイック検索(最もシンプル)

# Agent just asks naturally - middleware handles everything
unified_search(query="remimazolam ICU sedation", limit=20)

# Or with clinical codes - auto-converted to MeSH
unified_search(query="I10 treatment in E11.9 patients")
#                     ↑ ICD-10           ↑ ICD-10
#                     Hypertension       Type 2 Diabetes

2️⃣ PICO 臨床疑問

PICO 臨床検索ワークフロー

シンプルパス — unified_search は直接検索できます(PICO 分解なし):

# unified_search searches as-is; detects "A vs B" pattern and shows PICO hints in metadata
unified_search(query="Is remimazolam better than propofol for ICU sedation?")
# → Multi-source keyword search + PICO hint metadata in output
# ⚠️ This does NOT auto-decompose PICO or expand MeSH!
# For structured PICO search, use the Agent workflow below

エージェントワークフロー — エージェント提供の PICO + バックエンドパイプライン検索(臨床疑問に推奨):

┌─────────────────────────────────────────────────────────────────────────┐
│  "Is remimazolam better than propofol for ICU sedation?"                │
└─────────────────────────────────┬───────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         parse_pico()                                     │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐                     │
│  │    P    │  │    I    │  │    C    │  │    O    │                     │
│  │  ICU    │  │remimaz- │  │propofol │  │sedation │                     │
│  │patients │  │  olam   │  │         │  │outcomes │                     │
│  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘                     │
└───────┼────────────┼────────────┼────────────┼──────────────────────────┘
        │            │            │            │
        ▼            ▼            ▼            ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              generate_search_queries() × 4 (parallel)                    │
│                                                                          │
│  P → "Intensive Care Units"[MeSH]                                        │
│  I → "remimazolam" [Supplementary Concept], "CNS 7056"                   │
│  C → "Propofol"[MeSH], "Diprivan"                                        │
│  O → "Conscious Sedation"[MeSH], "Deep Sedation"[MeSH]                   │
└─────────────────────────────────┬───────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              Agent combines with Boolean logic                           │
│                                                                          │
│  (P) AND (I) AND (C) AND (O)  ← High precision                           │
│  (P) AND (I OR C) AND (O)     ← High recall                              │
└─────────────────────────────────┬───────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────┐
│              unified_search() (auto multi-source + dedup)                │
│                                                                          │
│  PubMed + Europe PMC + CORE + OpenAlex → Auto deduplicate & rank         │
└─────────────────────────────────────────────────────────────────────────┘
# Step 1: Agent extracts P/I/C/O, then validates the structured handoff
pico = parse_pico(
    description="Is remimazolam better than propofol for ICU sedation?",
    p="ICU patients requiring sedation",
    i="remimazolam",
    c="propofol",
    o="sedation efficacy, delirium, hypotension"
)
# Returns validation plus a ready-to-run `template: pico` pipeline.

# Step 2: Get MeSH for each element (parallel!)
generate_search_queries(topic="ICU patients")   # P
generate_search_queries(topic="remimazolam")    # I
generate_search_queries(topic="propofol")       # C
generate_search_queries(topic="sedation")       # O

# Step 3: Either pass expanded fragments back as p_query/i_query/c_query/o_query
# or let the backend pipeline use the structured P/I/C/O labels.

# Step 4: Search (backend runs O-aware precision/recall searches, dedup, rank)
unified_search(
    query="Is remimazolam better than propofol for ICU sedation?",
    pipeline=pico["pipeline"]
)

3️⃣ キーペーパーから探索

# Found landmark paper PMID: 33475315
find_related_articles(pmid="33475315")   # Similar methodology
find_citing_articles(pmid="33475315")    # Who built on this?
get_article_references(pmid="33475315")  # What's the foundation?

# Build complete research map
build_citation_tree(pmid="33475315", depth=2, output_format="mermaid")

4️⃣ 遺伝子/薬剤リサーチ

# Research a gene
search_gene(query="BRCA1", organism="human")
get_gene_literature(gene_id="672", limit=20)

# Research a drug compound
search_compound(query="propofol")
get_compound_literature(cid="4943", limit=20)

5️⃣ 結果のエクスポート

# Export last search results
prepare_export(pmids="last", format="ris")      # → EndNote/Zotero
prepare_export(pmids="last", format="bibtex", source="local")  # → LaTeX
prepare_export(pmids="last", format="csl")      # → CSL JSON from the official NCBI Citation API
save_literature_notes(pmids="last")              # → local wiki note + Foam-compatible wikilinks + CSL JSON
save_literature_notes(pmids="last", note_format="medpaper", output_dir="./references")
save_literature_notes(pmids="last", template_file="./reference-template.md")

# Retrieve full text for a selected paper from the last search
get_fulltext(pmid="12345678", extended_sources=True)

6️⃣ プレプリント検索

# Include preprints alongside peer-reviewed results
unified_search(query="COVID-19 vaccine efficacy", options="preprints")
# → Main aggregated results include labelled arXiv, medRxiv, and bioRxiv preprints

# Include preprints and retain non-peer-reviewed items in main results
unified_search(query="CRISPR gene therapy", options="preprints, all_types")
# → Preprint-server crawl + non-peer-reviewed items retained in main results

# Only peer-reviewed (default behavior)
unified_search("diabetes treatment")
# → Preprints from any source automatically filtered out

# Add a research context graph preview to the same search response
unified_search("remimazolam ICU sedation", options="context_graph")

7️⃣ パイプライン(再利用可能な検索プラン)

# Save a template-based pipeline through the primary facade
manage_pipeline(
  action="save",
    name="icu_sedation_weekly",
    config="template: pico\nparams:\n  P: ICU patients\n  I: remimazolam\n  C: propofol\n  O: delirium",
    tags="anesthesia,sedation",
    description="Weekly ICU sedation monitoring"
)

# Save a custom DAG pipeline
manage_pipeline(
  action="save",
    name="brca1_comprehensive",
    config="""
steps:
  - id: expand
    action: expand
    params: { topic: BRCA1 breast cancer }
  - id: pubmed
    action: search
    params: { query: BRCA1, sources: pubmed, limit: 50 }
  - id: expanded
    action: search
    inputs: [expand]
    params: { strategy: mesh, sources: pubmed,openalex, limit: 50 }
  - id: merged
    action: merge
    inputs: [pubmed, expanded]
    params: { method: rrf }
  - id: enriched
    action: metrics
    inputs: [merged]
output:
  limit: 30
  ranking: quality
"""
)

# Execute a saved pipeline
unified_search(pipeline="saved:icu_sedation_weekly")

# List & manage
manage_pipeline(action="list", tag="anesthesia")
manage_pipeline(action="load", source="brca1_comprehensive")  # Review YAML
manage_pipeline(action="history", name="icu_sedation_weekly")  # View past runs

🔍 検索モード比較

┌─────────────────────────────────────────────────────────────────────────┐
│                        SEARCH MODE DECISION TREE                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│   "What kind of search do I need?"                                       │
│         │                                                                │
│         ├── Know exactly what to search?                                 │
│         │   └── unified_search(query="topic keywords")                   │
│         │       → Quick, auto-routing to best sources                    │
│         │                                                                │
│         ├── Have a clinical question (A vs B)?                           │
│         │   └── Agent P/I/C/O → parse_pico() handoff                  │
│         │       → unified_search(template:pico) or expanded Boolean    │
│         │                                                                │
│         ├── Need comprehensive systematic coverage?                      │
│         │   └── generate_search_queries() → parallel search              │
│         │       → MeSH expansion, multiple strategies, merge             │
│         │                                                                │
│         └── Exploring from a key paper?                                  │
│             └── find_related/citing/references → build_citation_tree     │
│                 → Citation network, research context                     │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

モード

エントリーポイント

最適

自動機能

クイック

unified_search()

高速なトピック検索

ICD→MeSH、マルチソース、重複排除

PICO

エージェント P/I/C/O -> parse_pico()

臨床疑問

ハンドオフ検証 -> template:pico バックエンド検索

系統的

generate_search_queries() → unified_search(options="systematic")

再現可能なレビューの種

MeSH/同義語に加え、制限付きバルク/カーソル実行。網羅性を主張するものではありません

ネイティブセマンティック

unified_search(options="native_semantic")

タイトル/アブストラクト空間での概念的な類似性

機能検証。OpenAlex セマンティックモード、最大50件

探索

find_*_articles()

キーペーパーから

引用ネットワーク、関連記事


🤖 Claude スキル(AI エージェントワークフロー)

.claude/skills/ にある事前構築済みのワークフローガイドで、使用スキル(MCP サーバーの利用向け)と開発スキル(プロジェクトの保守向け)に分かれています:

📚 使用スキル (11) — この MCP サーバーを使用する AI エージェント向け

スキル

説明

pubmed-quick-search

フィルター付き基本検索

pubmed-systematic-search

MeSH 展開、包括的

pubmed-pico-search

臨床疑問の分解

pubmed-paper-exploration

引用ツリー、関連記事

pubmed-research-chronicle

永続的でバージョン管理された研究の進化

pubmed-gene-drug-research

遺伝子/PubChem/ClinVar

pubmed-fulltext-access

Europe PMC、CORE 全文

pubmed-export-citations

RIS/BibTeX/CSV/CSL エクスポートガイド

pubmed-multi-source-search

クロスデータベース統合検索

pubmed-mcp-tools-reference

完全なツールリファレンスガイド

pipeline-persistence

検索プランの保存、読み込み、再利用

🔧 開発スキル (15) — プロジェクト貢献者向け

スキル

説明

changelog-updater

CHANGELOG.md を自動更新

code-refactor

DDD アーキテクチャのリファクタリング

code-reviewer

コード品質とセキュリティレビュー

ddd-architect

新機能のための DDD スキャフォールド

git-doc-updater

コミット前のドキュメント同期

git-precommit

プリコミットワークフローのオーケストレーション

memory-checkpoint

コンテキストをメモリーバンクに保存

memory-updater

メモリーバンクファイルを更新

pdf-asset-extractor

引用可能な PDF アセットの抽出とインベントリ作成

project-init

新規プロジェクトの初期化

readme-i18n

多言語 README の同期

readme-updater

コード変更に合わせて README を同期

roadmap-updater

ROADMAP.md のステータスを更新

test-generator

テストスイートを生成

tool-sync

MCP レジストリと生成されたツールドキュメントの整合性を維持

📁 場所: .claude/skills/*/SKILL.md(Claude Code 固有であり、リポジトリのスキルに関する唯一の情報源) リポジトリのスキルを .github/skills/ にミラーリングしたり分割したりしないでください。 これらのリポジトリスキルはプロジェクトスコープであり、バージョン管理下に保つ必要があります。個人のクロスプロジェクトスキルは ~/.copilot/skills/ や ~/.claude/skills/ などのユーザーディレクトリに属し、このリポジトリには属しません。


🏗️ アーキテクチャ(DDD)

このプロジェクトは ドメイン駆動設計(DDD) アーキテクチャを採用しており、文献研究のドメイン知識を中核モデルとしています。

src/pubmed_search/
├── domain/                     # Core business logic
│   └── entities/article.py     # UnifiedArticle, Author, etc.
├── application/                # Use cases
│   ├── search/                 # QueryAnalyzer, ResultAggregator
│   ├── export/                 # Citation export (RIS, BibTeX...)
│   └── session/                # SessionManager
├── infrastructure/             # External systems
│   ├── ncbi/                   # Entrez, iCite, Citation Exporter
│   ├── sources/                # Europe PMC, CORE, CrossRef...
│   └── http/                   # HTTP clients
├── presentation/               # User interfaces
│   ├── mcp_server/             # MCP tools, prompts, resources
│   │   └── tools/              # discovery, strategy, pico, export...
│   └── api/                    # Auxiliary HTTP API routes (not pubmed_search.api)
└── shared/                     # Cross-cutting concerns
    ├── exceptions.py           # Unified error handling
    └── async_utils.py          # Rate limiter, retry, circuit breaker

内部メカニズム(エージェントに対して透過的)

メカニズム

説明

セッション

自動作成、自動切り替え

キャッシュ

検索結果を自動キャッシュし、重複 API 呼び出しを回避

レート制限

NCBI API の制限に自動対応(0.34秒/0.1秒)

MeSH ルックアップ

generate_search_queries() が NCBI MeSH データベースを自動照会

ESpell

自動スペル修正(remifentanyl → remifentanil)

クエリ分析

各提案クエリが、PubMed が実際にどのように解釈するかを表示

語彙変換層(主要機能)

私たちのコアバリュー: 私たちはエージェントと検索エンジンの中間に位置するインテリジェントミドルウェアであり、エージェントが各データベースの用語を知る必要がないよう、語彙の標準化を自動的に処理します。

異なるデータソースは異なる統制語彙システムを使用します。このサーバーは自動変換を提供します:

API / データベース

語彙システム

自動変換

PubMed / NCBI

MeSH(医学件名標目表)

✅ expand_with_mesh() による完全サポート

ICD コード

ICD-10-CM / ICD-9-CM

✅ 自動検出して MeSH に変換

Europe PMC

テキストマイニングされたエンティティ(遺伝子、疾患、化学物質)

✅ get_text_mined_terms() による抽出

OpenAlex

トピック/キーワード(モデル推論)

✅ ブローカーキーワードモード。選択時は制限付きネイティブセマンティックモード

Semantic Scholar

S2 フィールド/バルククエリ構文

✅ ブローカーが関連性モードか制限付きバルクモードを選択。プロバイダー注釈が来歴を保持

CORE

なし

❌ フリーテキストのみ

CrossRef

なし

❌ フリーテキストのみ

自動 ICD → MeSH 変換

ICD コード(例: 高血圧の I10)で検索すると、unified_search() は自動的に:

  1. detect_and_expand_icd_codes() を使用して ICD-10/ICD-9 パターンを検出します

  2. 内部マッピング(ICD10_TO_MESH、ICD9_TO_MESH)から対応する MeSH 用語を検索します

  3. 包括的な検索のために MeSH 同義語でクエリを拡張します

# Agent calls unified_search with clinical terminology
unified_search(query="I10 treatment outcomes")

# Server auto-expands to PubMed-compatible query
"(I10 OR Hypertension[MeSH]) treatment outcomes"

📖 完全なアーキテクチャドキュメント: ARCHITECTURE.md

MeSH 自動展開 + クエリ分析

generate_search_queries("remimazolam sedation") を呼び出すと、内部では次の処理が行われます:

  1. ESpell 修正 - スペルミスを修正します

  2. MeSH クエリ - Entrez.esearch(db="mesh") を使用して標準ボキャブラリを取得します

  3. 同義語抽出 - MeSH Entry Terms から同義語を取得します

  4. クエリ分析 - PubMed が各クエリをどのように解釈するかを分析します

{
  "mesh_terms": [
    {
      "input": "remimazolam",
      "preferred": "remimazolam [Supplementary Concept]",
      "synonyms": ["CNS 7056", "ONO 2745"]
    }
  ],
  "all_synonyms": ["CNS 7056", "ONO 2745", ...],
  "suggested_queries": [
    {
      "id": "q1_title",
      "query": "(remimazolam sedation)[Title]",
      "purpose": "Exact title match - highest precision",
      "estimated_count": 8,
      "pubmed_translation": "\"remimazolam sedation\"[Title]"
    },
    {
      "id": "q3_and",
      "query": "(remimazolam AND sedation)",
      "purpose": "All keywords required",
      "estimated_count": 561,
      "pubmed_translation": "(\"remimazolam\"[Supplementary Concept] OR \"remimazolam\"[All Fields]) AND (\"sedate\"[All Fields] OR ...)"
    }
  ]
}

クエリ分析の価値: Agent は remimazolam AND sedation がこれら2つの単語のみを検索すると考えますが、PubMed は実際には Supplementary Concept + 同義語に展開するため、結果は 8 件から 561 件に増えます。これにより Agent は 意図 と 実際の検索 の違いを理解できます。


🔒 ローカル HTTPS デモとサービスデプロイ

同梱の自己署名証明書と curl -k フローは ローカル TLS デモ であり、 本番セキュリティプロファイルではありません。共有サービスとして使用する場合は、 DEPLOYMENT.md に記載されている認証付きサービス用 Compose ファイルと 信頼された証明書を使用してください。

ローカル HTTPS スモークテスト

# Step 1: Generate SSL certificates
./scripts/generate-ssl-certs.sh

# Step 2: Start HTTPS service (Docker)
./scripts/start-https-docker.sh up

# Verify deployment
curl -k https://localhost/

HTTPS エンドポイント

サービス

URL

説明

MCP

https://localhost/mcp

Streamable HTTP MCP エンドポイント

Health

https://localhost/health

ヘルスチェック

Ready

https://localhost/ready

レディネスチェック

Info

https://localhost/info

ランタイムトランスポートとエンドポイントメタデータ

Exports

https://localhost/exports

ローカルの準備済みエクスポート一覧。サービスモードではベアラー認証とテナントスコープが必要です

リモート MCP クライアント設定

{
  "mcpServers": {
    "pubmed-search": {
      "url": "https://localhost/mcp"
    }
  }
}

🏢 Microsoft Copilot Studio 連携

PubMed Search MCP を Microsoft 365 Copilot (Word、Teams、Outlook) と統合します!

クイックスタート

# Unpublished local schema/protocol smoke only; never tunnel local mode
pubmed-search-mcp-http --mode local --transport streamable-http \
  --copilot-compatible --host 127.0.0.1 --port 8765

# Public Copilot endpoint: authenticated service mode is mandatory
export PUBMED_AUTH_TOKENS="copilot:$(openssl rand -hex 32)"
export NGROK_DOMAIN="your-assigned-domain.ngrok.dev"
./scripts/start-copilot-studio.sh --with-ngrok

Copilot Studio 設定

フィールド

値

サーバー名

PubMed Search

サーバーURL

https://your-server.com/mcp

認証

サービスモードではベアラートークン。None は未公開のローカルデモのみ

📖 完全なドキュメント: copilot-studio/README.md

パッケージ化された Copilot HTTP セマンティクスには pubmed-search-mcp-http --copilot-compatible を使用します。run_server.py はソースツリー開発用ラッパーのままです。run_copilot.py はループバック専用の 12 ツールプリミティブスキーマスモークテストのみに使用します。この簡略化されたサーフェスは、unified_search(query, limit, min_year, max_year, sources, options) を通じて共有ランナーを呼び出し、検索実行、リプレイ引数、成果物の復旧のためにプリミティブスキーマの read_session を公開します。ただし、PubMed 専用の汎用検索エイリアスは公開しません。トンネルスクリプトは割り当てられた NGROK_DOMAIN を必要とし、占有されたバックエンドポートを拒否し、--mode service がレディネスチェックと未認証拒否チェックに合格した後にのみ公開します。

⚠️ 注記: SSE トランスポートは 2025 年 8 月に非推奨となりました。streamable-http を使用してください。


📖 その他のドキュメント:


🔐 セキュリティ

セキュリティ機能

レイヤー

機能

説明

HTTPS

TLS 終端

リモート認証情報に必要。同梱の自己署名プロファイルはローカルのみ

ベアラー認証

安定したプリンシパル

サービスモードで必須であり、テナント認証に使用されます

テナントストレージ

ファイルシステム分離

セッション、成果物、エクスポート、クロニクル、パイプラインは認証済みプリンシパルの下に保存されます

公平性とレートポリシー

テナント並行性 + 共有アップストリーム予算

1 つの呼び出し元がアップストリーム API 割り当てを増幅することを防ぎます

セキュリティヘッダー

クリックジャッキング/MIME 強化

リバースプロキシヘッダーは認証を補完します。CSRF 認証ではありません

シークレット処理

ランタイムシークレット注入

API キーとベアラートークンはデプロイのシークレット/環境から取得する必要があり、コミットやログに記録してはなりません

詳細なデプロイ手順については DEPLOYMENT.md を参照してください。


📤 エクスポート形式

Export and local notes workflow

検索結果を主要な参考文献管理ツールに対応した形式でエクスポートします。

形式

ソース

対応ツール

ユースケース

RIS

公式またはローカル

EndNote、Zotero、Mendeley

汎用インポート

MEDLINE

公式またはローカル

PubMed ツール

ネイティブな PubMed 形式のアーカイブ

CSL JSON

公式

引用処理プロセッサ

プログラムによる引用スタイル設定

BibTeX

ローカル

LaTeX、Overleaf、JabRef

学術執筆

CSV

ローカル

Excel、Google Sheets

データ分析

JSON

ローカル

プログラムからのアクセス

カスタム処理

エクスポートされるフィールド

  • コア: PMID、Title、Authors、Journal、Year、Volume、Issue、Pages

  • 識別子: DOI、PMC ID、ISSN

  • コンテンツ: Abstract (HTML タグは除去済み)

  • メタデータ: Language、Publication Type、Keywords

  • アクセス: DOI URL、PMC URL、全文の利用可能性

特殊文字の処理

  • BibTeX エクスポートは、適切な LaTeX エンコーディングのために pylatexenc を使用します

  • 北欧文字 (ø、æ、å)、ウムラウト (ü、ö、ä)、およびアクセント記号は正しく変換されます

  • 例: Søren Hansen → S{\o}ren Hansen


📚 引用

GitHub は CITATION.cff から Cite this repository を表示します。研究、方法セクション、または社内テクニカルレポートで PubMed Search MCP を使用する場合は、GitHub が生成した引用を優先するか、リポジトリのメタデータを直接再利用してください。

@software{pubmed_search_mcp,
  title = {PubMed Search MCP},
  author = {u9401066},
  url = {https://github.com/u9401066/pubmed-search-mcp}
}

📄 ライセンス

Apache License 2.0 - LICENSE を参照


🔗 リンク

Available Tools

41 tools
analyze_search_queryA
Read-onlyIdempotent

Analyze a search query without executing the search.

Useful for understanding how unified_search will process your query before actually running it.

Args: query: The search query to analyze

Returns: Analysis including: - Complexity level (SIMPLE/MODERATE/COMPLEX/AMBIGUOUS) - Intent (LOOKUP/EXPLORATION/COMPARISON/SYSTEMATIC) - PICO elements (if detected) - Recommended sources - Recommended strategies

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds the key behavioral fact that no search is executed and enumerates the analysis output (complexity, intent, PICO, recommendations), which is genuine value beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and constraint in the first sentence, then efficiently documents args and returns. The Returns list is a bit verbose but each line conveys distinct return fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by enumerating the analysis return fields. For a single-param read-only tool whose annotations cover safety, this is nearly complete; only deeper query-format guidance is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and there is one parameter, so the description must carry the meaning. It only restates 'query: The search query to analyze' with no added syntax, format, or length guidance beyond the schema's minLength/maxLength constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Analyze a search query') and immediately scopes it with the constraint 'without executing the search', which cleanly distinguishes it from the sibling unified_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames usage as a pre-flight step to unified_search ('understanding how unified_search will process your query before actually running it'), naming the alternative and the condition that selects this tool. It does not state when not to use it, but the routing is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

build_citation_treeA
Read-onlyIdempotent

Build a citation tree (network) from a single article.

🌳 Creates a visual citation network showing research lineage:

  • Forward (citing): Who cites this paper? (newer research)

  • Backward (references): What does this paper cite? (foundational work)

⚠️ IMPORTANT: Only accepts ONE PMID at a time to control API load. For multiple papers, call this tool separately for each.

📊 Output Formats (output_format parameter):

  • "cytoscape": Cytoscape.js format (default, academic standard)

  • "g6": AntV G6 format (modern, high-performance)

  • "d3": D3.js force graph format (flexible, Observable)

  • "vis": vis-network format (simple, quick prototypes)

  • "graphml": GraphML XML (desktop tools: Gephi, yEd, VOSviewer)

  • "mermaid": Mermaid diagram (VS Code preview, Markdown)

Args: pmid: Single PubMed ID (e.g., "12345678"). Only ONE PMID accepted - do NOT pass multiple. depth: How many levels to traverse (1-3, default 2). - depth=1: Direct citations/references only - depth=2: Also get citations of citations (recommended) - depth=3: Maximum depth (can be slow, ~100+ API calls) direction: Which direction to build the tree: - "forward": Only citing articles (who cites this) - "backward": Only references (what this cites) - "both": Both directions (default, recommended) limit_per_level: Max articles to fetch per node per level (default 5) output_format: Graph format for visualization (default "cytoscape") - "cytoscape": Cytoscape.js (academic standard, bioinformatics) - "g6": AntV G6 (modern, TypeScript, great for large graphs) - "d3": D3.js force layout (most flexible, Observable notebooks) - "vis": vis-network (simple and easy) - "graphml": GraphML XML (Gephi, VOSviewer, yEd, Pajek) - "mermaid": Mermaid diagram (preview in VS Code Markdown)

Returns: Markdown summary followed by JSON with graph data in the requested format. Includes metadata and statistics regardless of format.

Example usage: # Build 2-level tree for a paper (default Cytoscape.js format) build_citation_tree(pmid="33475315", depth=2, direction="both")

# Use AntV G6 format for modern web visualization
build_citation_tree(pmid="33475315", depth=2, output_format="g6")

# Export GraphML for Gephi analysis
build_citation_tree(pmid="33475315", depth=2, output_format="graphml")
ParametersJSON Schema
NameRequiredDescriptionDefault
pmidYesComplete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers.
depthNo
directionNoboth
output_formatNocytoscape
limit_per_levelNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the one-PMID API-load constraint, that depth=3 can trigger ~100+ API calls and be slow, and that depth controls traversal cost.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is well structured with headers, bullets and an example block, and the critical one-PMID warning is front-loaded. However, the output_format enum is fully documented twice (once in the 'Output Formats' section and again under Args), which is redundant padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the Returns section describes the response shape (Markdown summary plus JSON graph data with metadata and statistics) and the examples cover the main call patterns, leaving nothing essential missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, so the description must carry the load, and it does: it documents pmid (single value, example format), depth (range 1-3 with per-level meaning), direction (forward/backward/both), limit_per_level (default 5), and every output_format enum value with its intended consumer.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (build) and resource (citation tree/network) and clearly defines the two axes of the tree (forward/citing vs backward/references), which lets an agent distinguish it from the single-direction siblings find_citing_articles and get_article_references without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage conditions: only ONE PMID per call with an explicit instruction to call separately for multiple papers, plus recommendations for depth and direction defaults. It never names a sibling tool as an alternative, so the routing guidance is implicit rather than exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

build_research_chronicleA

Build a persisted, versioned, evidence-backed Research Chronicle.

A chronicle is the durable record of how a research topic evolved, and the single entry point for research-evolution work (it replaces the older one-shot timeline tools). It is stored with a monotonic revision number, so re-running it later produces revision N+1 and you can diff revisions to see exactly what changed.

The primary axis is chronological; research branches are a secondary organizing dimension. Both come from the same stored snapshot, and preserve shared provenance in output="timeline" and output="tree". Agreement between projections is not independent evidence verification.

Every entry carries:

  • a one-sentence claim with inline citations

  • supporting / contradicting / updating evidence articles

  • a research branch (lineage) assignment

  • provenance and a confidence score

The typed provenance graph links Topic → Branch → Entry → EvidenceArticle and is validated against edge invariants. The audit reports evidence coverage, identifier coverage, branch coverage, graph integrity, and chronology gaps, so you always know how complete the picture is.

Args: topic: Research topic (drug, gene, disease, intervention). Required unless pmids or a stored chronicle_id is supplied. pmids: Delimited PMIDs, a string array or JSON array string, or "last" to chronicle the previous search results instead of running a new search. max_events: Maximum timeline events to consider (topic mode). Omit to inherit the continued revision's value, else 30. min_year: Earliest publication year to include (topic mode). max_year: Latest publication year to include (topic mode). chronicle_id: Continue an existing chronicle (creates revision N+1) instead of deriving the ID from the topic. Passing it alone re-runs the stored scope, so the resulting diff shows research movement rather than a changed window. output: "summary" (default compact Markdown with the chronological spine), "json", "chronicle_map", "timeline", "tree", "graph", "evidence", "milestones", "mermaid" (horizontal time spine with lineage branches), or "narrative". "json", "chronicle_map", "timeline", "tree", "graph", "evidence", and "milestones" return JSON; the rest return Markdown.

Returns: The requested rendering plus an artifact locator when durable artifact persistence is enabled and succeeds. The artifact contains the full snapshot, projections, evidence table, milestone analysis, and audit regardless of output. Artifact failure is reported but does not roll back the already saved Chronicle revision.

Examples: build_research_chronicle(topic="remimazolam") build_research_chronicle(pmids="last", topic="My Reading List") build_research_chronicle(topic="CAR-T therapy", output="mermaid") build_research_chronicle(chronicle_id="remimazolam-9f2b1c4d")

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsNo
topicNo
outputNosummary
max_yearNo
min_yearNo
max_eventsNo
chronicle_idNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, and the description adds substantial side-effect context beyond them: the chronicle is persisted with a monotonic revision number, re-runs create revision N+1, and artifact persistence failure 'is reported but does not roll back the already saved Chronicle revision'. That is exactly the write/persistence semantics an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then organized into description, Args, Returns, and Examples – a clean structure where each section is useful. It is longer than strictly necessary; lines like 'Agreement between projections is not independent evidence verification' and the Topic → Branch → Entry → EvidenceArticle walkthrough are informative but add bulk for an agent that mainly needs mode and output selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter, zero-required tool with no output schema, the description covers everything needed: entry conditions, parameter interactions, the artifact-plus-locator return shape, what the audit reports, and four concrete invocation examples. Nothing essential to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage reported at 0%, the description carries the full burden and does so thoroughly: it explains the topic/pmids/chronicle_id mutual fallbacks, the max_events inheritance rule and default of 30, min/max_year scoping to topic mode, and enumerates all ten output values, noting which return JSON vs Markdown. This meaningfully exceeds anything the schema conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb and artifact ('Build a persisted, versioned, evidence-backed Research Chronicle') and defines what a chronicle is (durable record of how a topic evolved). It explicitly positions itself against siblings, noting it 'replaces the older one-shot timeline tools' and is 'the single entry point for research-evolution work', so an agent can distinguish it from read_research_chronicle and build_citation_tree.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for each mode: topic mode for new searches, pmids='last' to reuse prior search results, and chronicle_id to 're-run the stored scope' as revision N+1 so the diff shows research movement. It does not explicitly state when NOT to use the tool or name read_research_chronicle as the read-only alternative, so it stops short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

configure_institutional_accessA
DestructiveIdempotent

Configure your institution's link resolver for full-text access.

═══════════════════════════════════════════════════════════════════════════════ 🏛️ INSTITUTIONAL ACCESS CONFIGURATION ═══════════════════════════════════════════════════════════════════════════════

This tool configures OpenURL link resolver integration, allowing you to access paywalled articles through your institution's library subscription.

Remote service callers may call this tool with no configuration arguments to inspect the operator-installed configuration, but cannot mutate the server-owned, deployment-wide OpenURL settings. Configure those at deployment time or from a trusted local server instead.

═══════════════════════════════════════════════════════════════════════════════ HOW IT WORKS: ═══════════════════════════════════════════════════════════════════════════════

  1. Your library subscribes to journals through publishers

  2. Library provides a "Link Resolver" service (SFX, 360 Link, Primo, etc.)

  3. OpenURL passes article metadata to the resolver

  4. Resolver checks your subscriptions and provides full-text access

═══════════════════════════════════════════════════════════════════════════════ USAGE: ═══════════════════════════════════════════════════════════════════════════════

Option 1: Use a preset (easiest) ───────────────────────────────── configure_institutional_access(preset="ntu")

Available presets:

  • 台灣: "ntu" (台大), "ncku" (成大), "nthu" (清大), "nycu" (陽明交大)

  • 美國: "harvard", "stanford", "mit", "yale"

  • 英國: "oxford", "cambridge"

  • 通用: "sfx", "360link", "primo" (需要 resolver_url)

Option 2: Custom URL ───────────────────── configure_institutional_access( resolver_url="https://your.library.edu/openurl" )

Option 3: Disable ───────────────────── configure_institutional_access(enable=False)

═══════════════════════════════════════════════════════════════════════════════ FINDING YOUR RESOLVER URL: ═══════════════════════════════════════════════════════════════════════════════

  1. Go to your library's website

  2. Look for "Find Full Text", "Link Resolver", or "OpenURL"

  3. Or search: "[Your University] link resolver"

  4. The URL usually looks like:

Args: resolver_url: Your institution's link resolver URL preset: Use a known institution's preset configuration enable: Whether to enable OpenURL links (default: True) Returns: Configuration status message

ParametersJSON Schema
NameRequiredDescriptionDefault
enableNo
presetNo
resolver_urlNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavioral context beyond annotations: remote service callers may call with no arguments to inspect operator-installed config but cannot mutate server-owned deployment-wide OpenURL settings, and enable defaults to True. It also discloses idempotence implicitly via the preset/config model. It doesn't spell out the full destructive implications for existing config, keeping it at 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the body is padded with ASCII-art banners and a multi-step 'how link resolvers work' explanation that an agent doesn't need to select or invoke the tool. Several sentences could be cut without losing invocation-relevant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter mutation tool with no output schema, the description covers the key risks (server-owned settings, remote vs local mutation), the option space, and default behavior. It leaves the exact returned configuration status format vague, but the rest is complete enough to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does: the Args section plus usage examples explain resolver_url, preset (with the full preset list), and enable/disable semantics. It's strong compensation, though it doesn't note the enum values embedded in the schema pattern or URL length limit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (configure) and resource (institution's OpenURL link resolver for full-text access), and immediately clarifies the integration type and its purpose. An agent can distinguish this from siblings like diagnose_institutional_access or test_institutional_access.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly lays out three usage modes (preset, custom URL, disable) with example invocations, and notes that remote callers can inspect but not mutate deployment-wide settings. It doesn't explicitly name sibling alternatives such as list_resolver_presets or diagnose_institutional_access for related tasks, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_icd_meshA
Read-onlyIdempotent

Query the curated ICD/MeSH crosswalk in one explicit direction.

Use icd_to_mesh with one complete ICD-9-CM or ICD-10-CM code, or mesh_to_icd with a MeSH term. The returned mapping is a limited convenience crosswalk, not a substitute for a current licensed UMLS terminology service.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYes
directionYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world). The description adds genuinely new context by disclosing the mapping's reliability limits — a "limited convenience crosswalk, not a substitute for a current licensed UMLS terminology service." Useful, though it says nothing about return shape or handling of unmapped codes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the purpose, then usage per direction, then the reliability caveat. No filler; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter conversion tool with no output schema, the description covers purpose, per-direction input semantics, and data limitations. It leaves the return format only loosely implied ("the returned mapping"), which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it does: it explains what ``value`` must contain for each ``direction`` (a complete ICD code vs. a MeSH term) and names both direction literals. It could add format examples, but it meaningfully compensates for the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Query the curated ICD/MeSH crosswalk in one explicit direction." This is unambiguous and, since no sibling tool performs code/terminology conversion, an agent can immediately identify its role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent per mode: use ``icd_to_mesh`` with a complete ICD-9-CM/ICD-10-CM code, or ``mesh_to_icd`` with a MeSH term. It stops short of a when-not to use the tool (beyond the UMLS caveat), so it falls just short of the top tier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_pipelineA
DestructiveIdempotent

Permanently delete a saved pipeline configuration and execution history.

For the default tenant, any process-level schedule is removed only after the stored pipeline deletion succeeds. Isolated tenants never mutate the shared process scheduler.

Args: name: Name of the saved pipeline to delete.

Returns: Confirmation of deletion.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds genuinely useful context beyond them: that execution history is destroyed (not just the config) and that process-level schedules are removed only after the deletion succeeds, with isolated tenants exempt from scheduler mutation. That is real side-effect disclosure the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the destructive action in the first sentence, then adds the tenant/scheduler caveat, then Args/Returns. Efficient and well-organized, though the tenant-scheduler sentence is somewhat more detailed than most callers need.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description covers the return ('Confirmation of deletion'), the scope of destruction, and the scheduler side effect. It is nearly complete for a single-parameter destructive tool; only name-discovery and irreversibility recovery guidance are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description only restates the obvious ('name: Name of the saved pipeline to delete'). It does not explain the naming constraints already implied by the schema (lowercase, pattern, 64-char limit) or how to discover valid names, so it adds little beyond a bare restatement.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Permanently delete a saved pipeline configuration and execution history'), which is enough to separate it from save_pipeline, list_pipelines, and load_pipeline. It does not explicitly contrast itself with the very similar unschedule_pipeline sibling, which also touches scheduling, so sibling differentiation is only partial.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the word 'Permanently' hints this is the irreversible removal path, but there is no explicit when-to-use/when-not guidance and no pointer to unschedule_pipeline for the case where the user only wants to cancel scheduling. The agent must infer the boundary between delete and unschedule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_institutional_accessA
Read-onlyIdempotent

Diagnose why institutional fulltext access succeeds or fails for an article.

Runs up to three probes and reports each path's outcome:

  1. Direct fetch (Phase 1, IP-aware) — follows https://doi.org/<doi> and classifies whether the publisher served fulltext, a paywall, or a login page. Works automatically when your network IP is on the publisher's institutional allow-list (campus / VPN).

  2. EZproxy fetch (Phase 2, BYO-cookie) — rewrites the publisher hostname to your library's EZproxy host and replays your exported browser session cookie. Configured via env vars:

    • EZPROXY_HOST (e.g. ezproxy.lib.ntu.edu.tw)

    • EZPROXY_COOKIE_FILE (path to browser-exported cookies.json)

    • EZPROXY_ENABLED=1

  3. OpenURL handoff — generated for you to open manually in a browser when the automated paths fail.

Usage: diagnose_institutional_access( source={"kind": "doi", "value": "10.1097/ALN.0000000000003599"} )

diagnose_institutional_access(
    source={"kind": "pmid", "value": "38353755"},
    try_ezproxy=False
)

Args: source: Exactly one PMID or DOI. A PMID is resolved to a DOI when possible so direct and EZproxy probes can run. try_direct: Run the Phase 1 direct probe (default True). try_ezproxy: Run the Phase 2 EZproxy probe (default True).

Returns: Markdown report listing every probe's status, classification, and advice on the next action to take.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes
try_directNo
try_ezproxyNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/openWorld/non-destructive, and the description adds substantial behavior beyond them: the three probe phases, what each probe does with the DOI, that EZproxy requires exported browser cookies and specific env vars, and that it probes live external hosts. Auth and network prerequisites are disclosed, which is exactly the added value expected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and organized into numbered phases plus a Usage block, so it is easy to scan. It is somewhat long and the docstring-style Args/Returns sections partly restate the schema, but each section contributes usable detail rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter diagnostic tool with no output schema, the description covers purpose, all probe phases, configuration prerequisites, and the markdown report it returns. The only notable gap is the absence of any pointer to the overlapping institutional-access siblings, which leaves an agent unsure of routing between them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the top-level parameters, so the description must carry the burden, and it does: it defines source (exactly one PMID or DOI, with the PMID-to-DOI resolution behavior explained), try_direct (Phase 1 toggle, default True), and try_ezproxy (Phase 2 toggle, default True). This adds real meaning — the resolution side effect — beyond the schema's bare booleans.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource ("Diagnose why institutional fulltext access succeeds or fails for an article") and enumerates the three probes it runs, so the agent knows exactly what it does. However, it never differentiates itself from closely related siblings such as test_institutional_access, configure_institutional_access, or get_institutional_link, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is well conveyed through two concrete invocation examples and clear preconditions (campus/VPN IP for Phase 1; EZPROXY_HOST/COOKIE_FILE/ENABLED for Phase 2; manual OpenURL when automated paths fail). There is no explicit when-not-to-use guidance or routing to the sibling tools that overlap this space, so it is clear context without alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetch_article_detailsB
Read-onlyIdempotent

Fetch detailed information for one or more PubMed articles.

Args: pmids: PubMed IDs - accepts multiple formats: - "12345678" (single) - "12345678,87654321" (comma-separated) - "PMID:12345678" (with prefix) - ["12345678", "87654321"] (list) - '["12345678", "87654321"]' (JSON array string) - Newlines, semicolons, pipes, and Chinese separators are also accepted. Inputs are string-only and fail as a complete batch when any PMID is invalid.

Returns: Detailed information for each article.

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsYesExplicit PMIDs; last is not supported.
output_formatNomarkdown

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description nonetheless adds a real behavioral trait beyond them: inputs are string-only and the whole batch fails if any single PMID is invalid — an all-or-nothing failure mode an agent must plan around.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The Args block is well organized and front-loads the key batch-failure constraint, but the long format enumeration partially duplicates the schema examples, and the 'Returns: Detailed information for each article' line is nearly tautological and adds little.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the return value is described only as 'detailed information for each article', leaving the agent unsure what fields come back. Combined with no usage guidance, the definition is adequate for calling but thin on what to expect and when to choose it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema coverage at 50%, the description compensates well for the pmids parameter, enumerating single, comma-separated, prefixed, list, JSON-array-string forms plus newlines, semicolons, pipes and Chinese separators — more than the schema examples convey. It says nothing about output_format, which the schema's enum/default already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Fetch detailed information for one or more PubMed articles.' This is clear enough to distinguish from lookup-style siblings like get_fulltext or get_citation_metrics, though it never explicitly names what it is not versus those tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus alternatives such as get_fulltext (full text), get_citation_metrics (metrics), or get_article_figures. The description assumes the agent already knows it wants article metadata; there are no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_citing_articlesA
Read-onlyIdempotent

Find articles that cite a given PubMed article. Uses PubMed Central's citation data to find papers that reference this article.

═══════════════════════════════════════════════════════════════ 📈 FORWARD CITATION SEARCH (Impact Tracking) ═══════════════════════════════════════════════════════════════

Direction: Source Paper → Papers that cite it (FORWARD in time)

USE CASES: ──────────

  • 🔬 Track research impact: Who built on this work?

  • 📊 Find follow-up studies: What happened after this discovery?

  • 🔄 Identify controversies: Papers that challenge or refute findings

  • 📚 Literature review: Ensure you have the latest developments

COMPLEMENTARY TOOLS: ────────────────────

  • get_article_references(): BACKWARD search (what this paper cited)

  • find_related_articles(): Similar papers (topic-based, not citation-based)

═══════════════════════════════════════════════════════════════ EXAMPLE: ═══════════════════════════════════════════════════════════════

Find papers that cite a landmark CRISPR paper

find_citing_articles(pmid="23287718", limit=20) → Returns papers published AFTER 2012 that reference this work

Then analyze citation metrics

get_citation_metrics(pmids="last") → See which citing papers are most influential

Args: pmid: PubMed ID of the source article ("12345678" or "PMID:12345678"). limit: Maximum number of citing articles to return (1-100, default: 10).

Returns: List of citing articles with details.

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidYesComplete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers.
limitNo

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so the safety profile is fully covered by structured data. The description reinforces the forward-in-time direction and notes the PubMed Central data source, which is mild added context. It does not add behavioral detail beyond annotations (no coverage notes, ordering, or pagination), so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose well, but the heavy ASCII-banner formatting, emoji, and an EXAMPLE block that largely restates the usage section consume substantial space beyond the essential two-sentence purpose. Helpful but not tight; every line does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only lookup with no output schema, the description covers when to use it, the direction of the search, the data source, and both parameters. It lacks detail on result ordering/return fields, but annotations and the schema carry most remaining burden. Nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%. The description documents pmid (accepting '12345678' or 'PMID:12345678') and the limit range/default (1-100, default 10), which matches the schema even though the schema actually supports more formats (URLs, backticks). The description adds no syntax beyond the schema's own pmid description, so baseline 3 is right.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Find articles that cite a given PubMed article') and explains the data source. It explicitly distinguishes itself from citation-based backward search (get_article_references) and topic-based search (find_related_articles), so an agent can route correctly among the many siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit use cases (impact tracking, follow-up studies, controversies, literature review) and a COMPLEMENTARY TOOLS section naming both alternatives with the condition that selects each. 'Direction: Source Paper → Papers that cite it (FORWARD in time)' unambiguously frames when to use this versus backward search.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_search_queriesA
Read-onlyIdempotent

Gather search intelligence for a topic - returns RAW MATERIALS for Agent to decide.

This tool provides the BUILDING BLOCKS for search, not finished queries. The Agent decides how to use them.

══════════════════════════════════════════════════════════════════════ TWO USAGE MODES: ══════════════════════════════════════════════════════════════════════

MODE 1: KEYWORD SEARCH (single topic) ───────────────────────────────────── User: "搜尋 remimazolam 的文獻"

Step 1: generate_search_queries("remimazolam") Step 2: Build a Boolean query from returned materials Step 3: analyze_search_query(query="") Step 4: unified_search(query="")

══════════════════════════════════════════════════════════════════════

MODE 2: PICO SEARCH (clinical question) ─────────────────────────────────────── User: "remimazolam 在 ICU 鎮靜比 propofol 好嗎?會減少 delirium 嗎?"

Step 1: Agent extracts P/I/C/O from the clinical question, then calls validate_pico_plan(description=..., p=..., i=..., c=..., o=...) to validate the structured handoff and get a runnable PICO pipeline.

Step 2: For EACH PICO element, call generate_search_queries() IN PARALLEL: - generate_search_queries("ICU patients") → P materials - generate_search_queries("remimazolam") → I materials - generate_search_queries("propofol") → C materials - generate_search_queries("delirium") → O materials

Step 3: Combine materials using Boolean logic: High precision: (P_terms) AND (I_terms) AND (C_terms) AND (O_terms) Recall-oriented: (P_terms) AND (I_terms OR C_terms); validate against eligible seed papers

Step 4: Add Clinical Query filter if appropriate: - filters="clinical_query:therapy" → 治療效果比較 - filters="clinical_query:diagnosis" → 診斷相關 - filters="clinical_query:prognosis" → 預後相關 - filters="clinical_query:etiology" → 病因相關

Step 5: Validate the final query with analyze_search_query()
Step 6: Execute unified_search() with the final Boolean query

══════════════════════════════════════════════════════════════════════

Features:

  • Spelling correction via NCBI ESpell

  • MeSH term lookup for standardized vocabulary

  • Synonym expansion from MeSH database

  • Query analysis: Shows how PubMed actually interprets each query (Agent's understanding vs PubMed's actual interpretation)

Args: topic: Search topic - can be a single keyword or PICO element strategy: Affects suggested_queries (if included) - "comprehensive": Multiple angles, includes reviews (default) - "focused": Adds RCT publication-type filter; study quality still requires appraisal - "exploratory": Broader search with more synonyms check_spelling: Whether to check/correct spelling (default: True) include_suggestions: Include pre-built query suggestions (default: True)

Returns: JSON with RAW MATERIALS: - corrected_topic: Spell-checked topic - keywords: Extracted significant keywords - mesh_terms: MeSH data with preferred terms and synonyms - all_synonyms: Flattened list of all synonyms - suggested_queries: Optional pre-built queries with: - estimated_count: How many results PubMed would return - pubmed_translation: How PubMed actually interprets the query

ParametersJSON Schema
NameRequiredDescriptionDefault
topicYes
strategyNocomprehensive
check_spellingNo
include_suggestionsNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so safety and idempotency are covered. The description adds real behavioral context: reliance on external NCBI ESpell and MeSH services, the note that 'focused' adds an RCT publication-type filter but 'study quality still requires appraisal', and a detailed Returns breakdown. It stops short of stating rate limits or failure modes, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded and the Args/Returns blocks earn their place, but the two MODE walkthroughs are very long and largely re-document orchestration that overlaps the sibling tools' own descriptions (e.g. detailed PICO steps and filter syntax). The box-drawing formatting pads length without adding call-time clarity, so it is over-sized relative to the marginal value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 0% parameter description coverage, the description supplies everything needed: purpose, the two invocation patterns, full parameter semantics, and the exact JSON return fields including estimated_count and pubmed_translation. An agent can call this correctly and interpret the result without consulting other sources.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it does: 'topic' is explained as 'a single keyword or PICO element', each 'strategy' enum value is given distinct meaning including the caveat that focused adds an RCT filter without guaranteeing quality, and check_spelling/include_suggestions are explained with their defaults. This fully compensates for the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening lines state a specific purpose — 'Gather search intelligence for a topic - returns RAW MATERIALS' and 'BUILDING BLOCKS for search, not finished queries' — and it expands this into concrete outputs (corrected_topic, keywords, mesh_terms, all_synonyms, suggested_queries). This clearly distinguishes it from siblings like unified_search (executes) and analyze_search_query (interprets), and even resolves the naming tension between 'generate_search_queries' and 'not finished queries'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It spells out two distinct usage modes with user-intent examples and explicit step-by-step routing to sibling tools (validate_pico_plan, analyze_search_query, unified_search), plus when to apply each clinical_query filter. An agent knows exactly when to pick keyword mode vs PICO mode and what to call next, so nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_article_figuresA
Read-onlyIdempotent

Get structured figure metadata (label, caption, image URL) and PDF links from a PMC Open Access article.

Returns all figures with their captions and direct image URLs, plus PDF download links for the complete article.

source is a discriminated identifier object, so the schema itself requires exactly one explicit PMID or PMCID.

Args: source: {"kind":"pmcid","value":"PMC12086443"} or {"kind":"pmid","value":"40384072"}. include_subfigures: Parse sub-figures (e.g., Figure 3A, 3B) as separate entries. include_tables: Also extract tables rendered as images.

Returns: Structured figure data with image URLs, captions, and PDF links.

Example: get_article_figures(source={"kind":"pmcid","value":"PMC12086443"})

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes
output_formatNomarkdown
include_tablesNo
include_subfiguresNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so safety and repeatability are covered. The description adds real value beyond that by disclosing the return contents (figure labels, captions, image URLs, PDF links) and the open-access-only limitation, though it says nothing about failure modes for non-OA articles or result limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in sentence one, then the Args/Returns/Example blocks are scannable and each line is actionable. There is minor duplication between the prose return sentence and the 'Returns:' block, but the structure is efficient for the amount of parameter complexity it must carry.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a small read-only tool with no output schema, the description covers the identifier format, the two optional extraction flags, and the shape of the result, which is what an agent needs to call it. The unmentioned output_format parameter and the absence of any behavior note for non-open-access input are the only remaining gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With top-level schema coverage at 0%, the description carries the load and does so for three of four parameters: it explains the discriminated source object with concrete PMID/PMCID examples, and clarifies include_subfigures and include_tables. The gap is output_format (markdown/json/toon, default markdown), which is never mentioned in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb, resource, and scope: structured figure metadata (label, caption, image URL) plus PDF links from a PMC Open Access article. That scope cleanly separates it from siblings like get_fulltext, search_biomedical_images, and prepare_figure_search without needing to name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied through the 'PMC Open Access article' constraint, which tells the agent this won't work for closed-access papers. There is no explicit statement of when to choose this over get_fulltext or prepare_figure_search, and no stated preconditions such as whether a prior resolve/lookup step is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_article_referencesA
Read-onlyIdempotent

Get the references (bibliography) of a PubMed article.

Returns the list of articles that this paper cites in its bibliography. This is the OPPOSITE of find_citing_articles:

  • get_article_references: Papers THIS article cites (backward in time)

  • find_citing_articles: Papers that cite THIS article (forward in time)

═══════════════════════════════════════════════════════════════ 📚 BACKWARD CITATION SEARCH (Foundation Discovery) ═══════════════════════════════════════════════════════════════

Direction: Source Paper → Papers it cited (BACKWARD in time)

USE CASES: ──────────

  • 🏛️ Find foundational papers: Core works the field builds on

  • ⚗️ Methodology sources: Papers describing techniques used

  • 📖 Background reading: Build understanding of a topic

  • 🔍 Verify claims: Check sources for specific assertions

═══════════════════════════════════════════════════════════════ EXAMPLE WORKFLOW: ═══════════════════════════════════════════════════════════════

Start with a recent review article

get_article_references(pmid="38123456", limit=50) → Get the bibliography of this review

Find most-cited foundational papers

get_citation_metrics(pmids="last", sort_by="citation_count") → Identify which references are the most influential

Read a foundational paper

fetch_article_details(pmids="12345678") → Get full details of an important reference

Args: pmid: PubMed ID of the source article ("12345678" or "PMID:12345678"). limit: Maximum number of references to return (1-100, default: 20).

Returns: List of referenced articles with details.

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidYesComplete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers.
limitNo

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is fully covered by structured data. The description adds directional semantics and a worked multi-tool workflow, but says nothing about error behavior for an invalid/unknown pmid, whether missing references yield an empty list, or pagination beyond the limit cap. With annotations carrying the behavioral load, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core statement is front-loaded and the example workflow genuinely helps an agent chain calls, but the ASCII banner blocks, emoji headings and repeated direction framing consume a large fraction of the text without adding decision-relevant content. Information is real but over-formatted for its size.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description gives only a thin return statement ('List of referenced articles with details'), but the direction, scoping, example chaining and error-free happy path make the tool callable correctly. A short note on return fields or empty-result behavior would close the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: pmid is richly documented in the schema (prefixes, URL form, backticks, rejection rules), while limit carries only bounds. The description restates pmid formats ('12345678' or 'PMID:12345678') and the limit range/default, both of which already appear in the schema, so it adds no meaning beyond the structured fields. Baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get the references (bibliography) of a PubMed article') and immediately positions it against a named sibling: 'This is the OPPOSITE of find_citing_articles'. The backward-vs-forward citation contrast lets an agent pick the right tool without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use categories (foundational papers, methodology sources, background reading, verifying claims) and an explicit alternative with the selecting condition (get_article_references = papers this article cites; find_citing_articles = papers that cite it). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_citation_metricsA
Read-onlyIdempotent

Get citation metrics from NIH iCite for articles.

Returns field-normalized citation data including:

  • citation_count: Total number of citations

  • relative_citation_ratio (RCR): Field-normalized metric (1.0 = average)

  • nih_percentile: Percentile ranking (0-100)

  • citations_per_year: Citation velocity

  • apt: Approximate Potential to Translate (clinical relevance 0-1)

Can sort and filter results by citation metrics.

Args: pmids: PubMed IDs - accepts multiple formats: - "12345678,87654321" (comma-separated) - ["12345678", "87654321"] (list) - '["12345678", "87654321"]' (JSON array string) - "PMID:12345678" (with prefix) - "last" to use PMIDs from the last search Batches are fail-closed and limited to 1,000 items before deduplication. sort_by: Metric to sort by: - "citation_count": Raw citation count (default) - "relative_citation_ratio": Field-normalized (recommended) - "nih_percentile": Percentile ranking - "citations_per_year": Citation velocity min_citations: Filter out articles with fewer citations min_rcr: Filter out articles with RCR below threshold (e.g., 1.0 = average) min_percentile: Filter out articles below percentile (e.g., 50 = top half)

Returns: Articles with citation metrics, sorted and filtered as requested. iCite transport or response failures return an explicit retryable error and are never rendered as an empty/unindexed result.

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsYes
min_rcrNo
sort_byNocitation_count
min_citationsNo
output_formatNomarkdown
min_percentileNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so safety is covered. The description adds real behavior beyond that: batching is fail-closed and capped at 1,000 items before deduplication, and iCite transport/response failures surface as an explicit retryable error rather than an empty result. Rate limits and auth requirements are not mentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what the tool returns, then Args, then Returns, using headers and bullets so an agent can scan it. The metric glossary earns its space because those fields are non-obvious, but the duplicated sort_by listing (once under returns, once under args) adds some redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly spends space explaining the return fields and their normalization, and it also covers batch limits and failure behavior for a 6-parameter, open-world tool. The omission of output_format and of any statement about ordering direction or result caps keeps it short of fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is reported as 0%, so the description carries the burden and mostly does: it documents the multiple PMID input formats (comma-separated, list, JSON array string, 'PMID:' prefix, 'last'), the batch cap, every sort_by enum value with meaning, and the semantics of min_citations/min_rcr/min_percentile with example thresholds. The one gap is output_format, which is never mentioned in the prose despite being a real enum parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get citation metrics from NIH iCite for articles') and enumerates exactly which metrics come back, including the meaning of each (RCR, nih_percentile, apt). It is clear what the tool does, but it never names or contrasts itself against plausible siblings such as find_citing_articles or build_citation_tree, leaving the agent to infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: sorting/filtering is described, 'relative_citation_ratio' is marked recommended, and 'last' is noted as reusing PMIDs from the previous search. There is no explicit when-to-use/when-not guidance or named alternative for retrieving citation data by other means, so the agent must infer the context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_compound_detailsB
Read-onlyIdempotent

Get detailed information about a compound by PubChem CID.

Args: cid: PubChem Compound ID

Returns: JSON with compound details including formula, SMILES, properties

ParametersJSON Schema
NameRequiredDescriptionDefault
cidYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds value by stating the return payload contents (formula, SMILES, properties), but says nothing about error behavior for invalid CIDs or rate limits on the external PubChem service.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by short Args/Returns blocks. No filler, though the Args/Returns labels are slightly heavy for a single-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter read tool with no output schema, the description supplies enough: purpose, the parameter's meaning, and the shape of the return. The missing piece is routing guidance relative to search_compound.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load. It expands 'cid' into 'PubChem Compound ID', which is more than the bare string-typed schema property, but it omits the numeric-string format constraint captured only by the schema pattern.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get detailed information about a compound') and names the identifying key (PubChem CID). It does not distinguish itself from the sibling search_compound, but an agent can still tell what this tool does from the name and description alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this over search_compound or get_compound_literature, nor any prerequisite or CID-acquisition note (e.g., you must first call search_compound). The agent is left to infer the workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_compound_literatureA
Read-onlyIdempotent

Get PubMed articles linked to a compound.

Uses NCBI's curated compound-to-publication links.

Args: cid: PubChem Compound ID limit: Maximum PubMed IDs to return (1-100)

Returns: JSON with linked PubMed IDs

ParametersJSON Schema
NameRequiredDescriptionDefault
cidYes
limitNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety and idempotence profile is covered. The description adds useful provenance (data comes from NCBI curated links, not free-text mining) but says nothing about pagination, behavior on zero results, or rate limits, so it is a modest addition rather than rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose in one sentence, then adds a provenance line and Args/Returns sections that each carry information not present in the 0%-coverage schema. Structure is clear, though the Args/Returns block is formulaic rather than tightly integrated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, explaining the return value ('JSON with linked PubMed IDs') is genuinely necessary and present, as is the data source and both parameter meanings. For a simple two-parameter lookup this is close to complete; only edge-case behavior (no links found, ordering) is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it does: it identifies 'cid' as a PubChem Compound ID (the schema only gives a string pattern) and gives the 'limit' range of 1-100. It omits the default of 20 and any format/ordering semantics for the returned IDs, keeping it short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get PubMed articles linked to a compound') plus the mechanism ('NCBI's curated compound-to-publication links'). An agent can distinguish this from the analogous get_gene_literature and from general search tools like unified_search without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use, when-not-to-use, or alternative tool guidance. It never clarifies the relationship to siblings like find_related_articles, get_compound_details, or search_compound, leaving the agent to infer the boundary from purpose alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_fulltextA

🔥 Enhanced multi-source fulltext retrieval.

Automatically tries multiple sources to find the best fulltext:

  1. Europe PMC (if PMC ID available)

  2. Unpaywall (finds OA versions via DOI)

  3. Institutional direct/EZproxy fetch (when DOI-backed and enabled)

  4. CORE (open-access repository metadata and available text)

With extended_sources=True, also searches: 5. CrossRef (publisher links) 6. DOAJ (Gold OA journals) 7. Zenodo (research repository) 8. PubMed LinkOut (external providers) 9. Semantic Scholar, OpenAlex, arXiv, bioRxiv, medRxiv

source is a discriminated identifier object, so the schema itself requires exactly one explicit PMID, PMCID, or DOI kind.

Args: source: One object such as {"kind":"pmid","value":"12345678"}, {"kind":"pmcid","value":"PMC7096777"}, or {"kind":"doi","value":"10.1001/jama.2024.1234"}. sections: Filter body sections (e.g., "introduction,methods,results"). Missing titles are reported with available sections; abstracts are never substituted for missing body evidence. include_pdf_links: Include PDF download links (default: True). False skips link enrichment when structured fulltext is already available. include_figures: Include figure metadata with image URLs (default: False) extended_sources: Search the extended downloader chain after the standard policy (default: False) output_format: Response format - "markdown" (default), "json", or "toon" allow_browser_session: Control browser-session fallback. - True: force broker fallback when configured - False: disable broker fallback - None: use auto mode from broker configuration

Returns: Fulltext content with PDF links from all available sources.

Example: get_fulltext(source={"kind":"pmcid","value":"PMC7096777"}) get_fulltext(source={"kind":"doi","value":"10.1038/s41586-021-03819-2"})

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes
sectionsNo
output_formatNomarkdown
include_figuresNo
extended_sourcesNo
include_pdf_linksNo
allow_browser_sessionNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare openWorldHint=true, readOnlyHint=false and non-idempotent, and the description adds real behavioral context beyond them: the source fallback chain, the tri-state semantics of allow_browser_session, and the guarantee that abstracts are never substituted for missing body evidence. It omits rate limits, permissions, or failure behavior, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a one-line purpose, then a numbered source chain, then Args and examples. Slightly long because the extended source list and two near-duplicate examples consume space, but every section is scannable and earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no output schema and no annotation-specified return format, the description covers inputs thoroughly and briefly states the return (fulltext content with PDF links). A short note on failure modes when no source yields fulltext would complete it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does so: it defines the discriminated source object with three concrete examples, explains sections filtering and its missing-title reporting, and gives the default plus purpose of include_pdf_links, include_figures, extended_sources, output_format, and the allow_browser_session tri-state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (multi-source fulltext retrieval) and distinguishes itself from siblings like fetch_article_details or get_article_figures by describing the retrieval/fallback chain rather than metadata lookup. An agent can tell what it returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the standard retrieval order and exactly when to enable extended_sources (searching the extended downloader chain after standard policy) and when to disable include_pdf_links. It does not explicitly name sibling alternatives such as fetch_article_details, so routing between tools is left partly to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gene_detailsA
Read-onlyIdempotent

Get detailed information about a gene by NCBI Gene ID.

Args: gene_id: NCBI Gene ID (from search results or known)

Returns: JSON with gene details including symbol, name, summary, location

ParametersJSON Schema
NameRequiredDescriptionDefault
gene_idYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered without the text. The description adds the return shape (symbol, name, summary, location), but says nothing about behavior for invalid/unknown gene IDs, rate limits, or external NCBI dependency despite openWorldHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by Args and Returns sections; every line earns its place with no filler or repetition of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the Returns block usefully enumerates the JSON fields an agent can expect. Minor gap: no mention of error/missing-gene behavior, which matters for a single-required-param lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the schema only conveys the type and a regex pattern, not meaning. The description compensates by defining gene_id as an NCBI Gene ID and indicating where to obtain it, which is more than the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get detailed information') and resource ('a gene') keyed by NCBI Gene ID. It is clearly distinguishable from the search_gene sibling by the 'details vs search' distinction, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical '(from search results or known)' implies the ID comes from a prior search, which is a useful workflow hint. However, it does not state when to use this over search_gene or get_gene_literature, nor any prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gene_literatureA
Read-onlyIdempotent

Get PubMed articles linked to a gene.

This uses NCBI's curated gene-to-publication links, which are more precise than keyword searches.

Args: gene_id: NCBI Gene ID limit: Maximum PubMed IDs to return (1-100)

Returns: JSON with linked PubMed IDs

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
gene_idYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld). The description adds the data provenance (NCBI curated links over keyword search), which is useful for interpreting result trust, but says nothing about auth, rate limits, or truncation behavior. With annotations doing the heavy lifting, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose, then concise provenance note, then Args/Returns blocks. Every line earns its place and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly states the return shape ('JSON with linked PubMed IDs'), and annotations cover safety. Both parameters are documented, so an agent has what it needs; only edge-case behaviors remain unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden and mostly does: it clarifies gene_id is an NCBI Gene ID (not a symbol) and gives limit's meaning and 1-100 bound. It still doesn't explain the format constraint on gene_id beyond the schema pattern, so not a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get PubMed articles linked to a gene') and explicitly contrasts itself with keyword-based retrieval, so an agent can separate it from unified_search. It does not name or distinguish itself from other article-linking siblings like find_related_articles, so it falls just short of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when this tool is the right choice: when you want curated gene-to-publication links rather than keyword matches. No explicit when-not conditions or prerequisites are stated, which keeps it from a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pipeline_historyA
Read-onlyIdempotent

Get execution history for a saved pipeline.

Shows past execution results with diff analysis: which articles are new compared to the previous run.

Args: name: Name of the saved pipeline. limit: Maximum number of history entries to return (default: 5).

Returns: Execution history with date, article count, new/removed articles, status.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
limitNo

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds genuine behavioral value beyond that: it explains the diff-analysis semantics (new/removed articles vs. the previous run) and the shape of returned data, which is not derivable from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a one-line purpose, then Args and Returns sections. Every element earns its place; the only minor overhead is the conventional docstring scaffolding, which is still efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fills the gap by describing the return contents (date, article count, new/removed articles, status). Annotations cover the safety profile and both parameters are addressed, making it largely complete, though the name-pattern constraint and absence of pagination guidance are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load. It documents both parameters, including the limit default of 5, which the schema also encodes. However, it does not explain the name pattern (lowercase slug, max 64 chars) or the limit bounds (1-100), leaving format constraints undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Get execution history for a saved pipeline') and clarifies scope ('for a saved pipeline'), which distinguishes it from pipeline-management siblings like save_pipeline, list_pipelines, and delete_pipeline. It does not explicitly name any sibling, but the read-only history focus is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use guidance or alternatives are given. The phrase 'for a saved pipeline' implies the pipeline must already exist, but the description never says to use list_pipelines first, nor when this is preferred over any other tool. Usage is only weakly inferable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_text_mined_termsB
Read-onlyIdempotent

Get text-mined annotations from Europe PMC.

Returns entities extracted from the article text including genes, diseases, chemicals, organisms, and more. source is exactly one PMID or PMCID.

Args: source: {"kind":"pmid","value":"12345678"} or {"kind":"pmcid","value":"PMC7096777"}. semantic_type: Filter by entity type. Options: - "GENE_PROTEIN": Genes and proteins - "DISEASE": Diseases and conditions - "CHEMICAL": Drugs and chemicals - "ORGANISM": Species and organisms - "GO_TERM": Gene Ontology terms - None: Return all types (default)

Returns: List of text-mined entities with counts and sections.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes
output_formatNomarkdown
semantic_typeNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is fully covered. The description adds the useful constraint that source is 'exactly one PMID or PMCID' and sketches the return content ('counts and sections'), but says nothing about rate limits, coverage gaps, or failure behavior for non-indexed articles.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: the core purpose is the first sentence, followed by cleanly separated Args and Returns blocks. Slight redundancy between the prose list of entity types and the bulleted semantic_type options, but nothing egregious.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does sketch the return ('List of text-mined entities with counts and sections'), and annotations cover safety. However, one of three parameters (output_format) is undocumented and the semantic_type list is incomplete, leaving gaps an agent must guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the parameter burden. It documents the source discriminator shape and gives human-readable labels for semantic_type values, but it omits the enum member 'EFO' present in the schema and never mentions the output_format parameter (markdown/json/toon) at all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get text-mined annotations from Europe PMC') plus the scope of what is extracted (genes, diseases, chemicals, organisms). An agent can distinguish it from general article tools like fetch_article_details, though it never names a sibling alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the mechanics of the call (one PMID or PMCID, optional semantic_type filter) but never says when to reach for this tool versus fetch_article_details, search_gene, or get_gene_literature. No exclusions or prerequisites for the operation itself are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pipelinesA
Read-onlyIdempotent

List all saved pipeline configurations.

Args: tag: Filter by tag (e.g., "sedation"). Empty = show all. scope: Filter by scope: "workspace", "global", or "" (show all).

Returns: Table of saved pipelines with name, scope, description, tags.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNo
scopeNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so safety is covered. The description adds the return shape (table with name, scope, description, tags), which is useful behavioral context, but says nothing about ordering, pagination, or limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line purpose followed by a compact Args/Returns block. Every line earns its place; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the return shape, and both param semantics are documented. Only minor gaps remain (no ordering/pagination/limits, no sibling routing).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the params—and it does: tag (filter, empty=show all) and scope ('workspace'/'global'/''=show all). This fully maps to both parameters and clarifies the empty-string sentinel semantics the schema only implies via defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear specific verb+resource: 'List all saved pipeline configurations.' An agent immediately knows this is a read/list operation. However it does not distinguish itself from siblings like get_pipeline_history, load_pipeline, or list_resolver_presets.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the filtering args (tag/scope) but there is no explicit statement of when to use this vs load_pipeline, get_pipeline_history, or save_pipeline. No prerequisites noted (e.g., workspace context).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_resolver_presetsA
Read-onlyIdempotent

List available institutional link resolver presets.

═══════════════════════════════════════════════════════════════════════════════ 📚 AVAILABLE RESOLVER PRESETS ═══════════════════════════════════════════════════════════════════════════════

These presets contain pre-configured URLs for common institutions. Use them with configure_institutional_access(preset="name").

Returns: List of available presets with URLs

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, idempotent, non-destructive, closed-world listing tool. The description adds useful context about what the presets are and that the return value includes preset URLs, which matters because there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The substantive content is short and front-loaded, but the large ASCII banner and emoji add visual noise without conveying additional information. The core sentences earn their place, while the decorative formatting does not.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool with annotations covering safety and no output schema, the description adequately says what is returned: available presets with URLs. It could be slightly more precise about return structure, but it is complete enough to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

This tool takes zero parameters, so the baseline is 4. The description does not need to explain parameter semantics, and it does not introduce any confusion about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List available institutional link resolver presets.' It also names the related sibling configure_institutional_access, which helps an agent distinguish listing presets from configuring access.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by saying presets should be used with configure_institutional_access(preset="name"), but it does not explicitly say when to call this tool versus alternatives or when not to use it. The intended follow-up workflow is clear, but direct invocation guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

load_pipelineA
Read-onlyIdempotent

Load a pipeline configuration for review or editing.

Loads from either source:

  • Saved name: "weekly_remimazolam" or "saved:weekly_remimazolam"

  • Local-only file: "file:path/to/pipeline.yaml" (disabled for authenticated service callers)

The returned YAML can be reviewed, modified, and then:

  • Executed directly: unified_search(pipeline="")

  • Saved with changes: save_pipeline(name="...", config="")

Args: source: Pipeline source identifier (see above).

Returns: Full pipeline YAML content + metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as readOnly, idempotent, and non-destructive. The description adds useful behavioral details beyond those annotations, including the two supported source formats, the restriction on local-only files for authenticated service callers, and the fact that the returned YAML can be passed onward to unified_search or save_pipeline. This gives agents a clearer model of what happens after load.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose, followed by source formats, usage examples, and return behavior. It is slightly longer than strictly necessary because the Args/Returns formatting partially duplicates information already in the schema, but every section adds practical value for correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter), the description is nearly complete: it covers source variants, an important auth-related limitation, and the return value. It could arguably mention that list_pipelines can be used to discover valid saved names, but this is not essential for calling the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the schema only defines 'source' as a string with length constraints. The description fully compensates by explaining the accepted source formats with examples ('saved:weekly_remimazolam' and 'file:path/to/pipeline.yaml') and by clarifying the authentication restriction on file paths. This adds substantial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Load a pipeline configuration for review or editing.' It clearly differentiates the load action from sibling tools like save_pipeline, delete_pipeline, and list_pipelines, and explains the two source types. The purpose is immediately understandable and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when this tool is appropriate: when a pipeline configuration needs to be reviewed, edited, or prepared for execution or saving. It also provides an explicit exclusion: local-only file sources are disabled for authenticated service callers. It does not explicitly name alternatives to avoid, but the workflow notes referencing unified_search and save_pipeline provide strong situational guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

prepare_exportA

Export citations to reference manager formats.

╔═══════════════════════════════════════════════════════════════════╗ ║ RECOMMENDED: Use source="official" (default) for best quality ║ ╚═══════════════════════════════════════════════════════════════════╝

When to Use

  • Exporting references to EndNote, Zotero, Mendeley

  • Creating BibTeX for LaTeX documents

  • Generating citation lists for manuscripts

Source Options

Source

Formats

Quality

Speed

official

ris, medline, csl

★★★★★

Fast

local

ris, bibtex, csv, medline, json

★★★★

Fast

Format Selection Guide

  • ris: EndNote, Zotero, Mendeley (official recommended)

  • medline: NBIB format for PubMed tools

  • csl: JSON for programmatic citation styling

  • bibtex: LaTeX documents (local only)

  • csv: Data analysis, Excel (local only)

Args: pmids: Articles to export. Accepts: - "last" → results from previous search - "12345678,87654321" → comma-separated PMIDs - ["12345678", "87654321"] → list of PMIDs - '["12345678", "87654321"]' → JSON array string - "PMID:12345678" → with prefix format: Export format (default: "ris") - official API: ris, medline, csl - local only: bibtex, csv, json include_abstract: Include abstracts in output (default: True). False requires source="local"; official payloads are returned unmodified. source: Citation source (default: "official") - "official": NCBI Citation API (recommended, best quality) - "local": Local formatting (more formats, offline capable)

Returns: JSON with status and export_text containing formatted citations.

Examples: # Export last search results (recommended) prepare_export(pmids="last", format="ris")

# Export specific PMIDs to BibTeX
prepare_export(pmids="12345678,87654321", format="bibtex", source="local")

# Get CSL-JSON for programmatic use
prepare_export(pmids="last", format="csl", source="official")
ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsYes
formatNoris
sourceNoofficial
include_abstractNo

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare a non-read-only, open-world, non-idempotent operation, and the description adds real behavioral context beyond them: include_abstract=False requires source='local' because official payloads are returned unmodified, local is offline capable, and the return shape is status + export_text. It stops short of explaining latency, rate limits, or side effects that justify readOnlyHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded with the recommended-default callout, then organized into scannable sections (When to Use, Source Options, Format Selection) and ended with runnable examples. It is long, and the box-drawing banner is decorative overhead, but nearly every line carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter tool with no output schema, the description covers input formats, defaults, valid parameter combinations, offline vs API behavior, and the return payload shape. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is reported as 0%, so the description carries the full burden and does so thoroughly: accepted pmids encodings (last, comma-separated, list, JSON array string, PMID: prefix), the meaning of each format enum value, the include_abstract default and its source constraint, and the source trade-offs. This is exactly the compensation the low schema coverage requires.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Export citations to reference manager formats') up front, and the format/source tables make clear it produces formatted citation text rather than fetching or analyzing records. An agent can distinguish it from get_citation_metrics or fetch_article_details without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'When to Use' list names the concrete scenarios (EndNote/Zotero/Mendeley, BibTeX for LaTeX, manuscript citation lists), and the source/format tables give guidance on which option to pick and when. It also flags a hard constraint (bibtex/csv/json require source='local') so the agent can avoid invalid combinations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_research_chronicleA
Read-onlyIdempotent

Read stored Research Chronicles: load, list, diff, narrate, analyze, compare.

This is the read facade over chronicles created by build_research_chronicle. Chronicles persist across sessions, so you can revisit a topic weeks later and see precisely what moved. Because the evidence is already stored, analysis and comparison are instant and do not re-run any search.

Actions:

  • "load": read one revision (defaults to latest) in any output format

  • "list": list stored chronicles, most recently updated first

  • "diff": compare two revisions — added, not observed/removed from the later view, and updated entries, plus evidence churn, branch churn, and the audit status transition. Absence does not prove retirement.

  • "narrate": render evidence-backed Markdown where every claim carries its entry ID and article identifiers

  • "milestones": entry-type and status distribution, per-year activity, evidence quality, and landmark entries for one chronicle

  • "compare": compare 2-5 chronicles side by side, including the evidence articles they share

The required request discriminator makes invalid field combinations unrepresentable. compare takes one typed selection containing either 2-5 topic strings or 2-5 Chronicle IDs.

Returns: Markdown or JSON text depending on the action and output format.

Examples: read_research_chronicle(request={"action":"list"}) read_research_chronicle(request={"action":"load","chronicle_id":"remimazolam-9f2b1c4d","output":"tree"}) read_research_chronicle(request={"action":"diff","chronicle_id":"remimazolam-9f2b1c4d","from_revision":1}) read_research_chronicle(request={"action":"narrate","chronicle_id":"remimazolam-9f2b1c4d","mode":"full"}) read_research_chronicle(request={"action":"milestones","chronicle_id":"remimazolam-9f2b1c4d"}) read_research_chronicle(request={"action":"compare","selection":{"kind":"topics","values":["remimazolam","propofol"]}})

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuine context beyond that: chronicles persist across sessions, analysis/comparison are instant and re-run no search, and the diff caveat 'Absence does not prove retirement' warns against over-reading removal results. It omits any pagination or sizing detail for large chronicles.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then a scannable per-action list, then interface notes and examples — well organized and mostly waste-free. Minor deduction: the lead sentence advertises an 'analyze' action that does not exist in the discriminator (the real actions are load/list/diff/narrate/milestones/compare), a small internal inconsistency in an otherwise tight layout.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-action, heavily nested discriminated-union tool with no output schema, the description covers every action, the selection shape, the return medium ('Markdown or JSON text depending on the action and output format'), and provides a call example per action. Nothing essential to invoking it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is effectively 0% at the wrapper level (only fragments like 'Positive Chronicle revision' exist), so the description must compensate. It explains that the `request` discriminator makes invalid field combinations unrepresentable, that `compare` takes a typed `selection` of either 2-5 topics or 2-5 Chronicle IDs, and it points at output formats and narrate modes — meaningful semantics the schema alone does not spell out.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line names a specific verb (read) and resource (stored Research Chronicles) and enumerates the six actions, then names the sibling that creates them (`build_research_chronicle`). An agent can distinguish this read facade from the build tool and from the other read tools without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each action is paired with a condition that selects it (load = one revision, list = stored chronicles, diff = compare two revisions, compare = 2-5 chronicles side by side), and the text routes creation to `build_research_chronicle`. It stops short of explicit 'use X instead of Y' exclusions or prerequisites, but the per-action framing gives clear context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_sessionA
Read-onlyIdempotent

Read session data through one schema-exact discriminated request.

Actions:

  • pmids: return PMIDs for one recorded search

  • article: return one cached article payload

  • summary: return current session summary and optional history

  • list_artifacts: list persistent MCP output artifact manifests

  • artifact: read one persistent artifact by artifact_id or artifact_uri

  • search_runs: list durable unified_search run envelopes

  • search_run: read one run by stable run_id

  • replay_search: return credential-free unified_search replay arguments

Each action accepts only its own fields. For remote artifact reads, select an artifact_id or artifact_uri locator and use artifact_file plus offset/max_chars to page through large files. Local paths remain redacted unless both include_local_paths and the server setting allow them.

ParametersJSON Schema
NameRequiredDescriptionDefault
requestYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotent/non-destructive, so the bar is lower; the description still adds genuine value by disclosing the redaction policy for local paths (requires include_local_paths plus a server setting) and that replay_search returns credential-free arguments. It omits return-shape and pagination-bound behavior, but the security disclosure is substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose in one sentence, then a tight bulleted action index, then a short paragraph of edge-case rules. The bullets partly restate schema discriminants, but for a 9-way union the index earns its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, so the description carries return-shape burden, and it never says what each action returns beyond a phrase. Most critically, it omits the schema's 'log' action, leaving an agent that reads only the description blind to one valid mode of a highly complex discriminated union.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% at the top level, so the description must compensate — it does for only a handful of fields (locator, artifact_file, offset/max_chars, include_local_paths). Many discriminants (event_limit, history_limit, query_filter, search_index, status, run_id, kind, tool) get no semantic gloss.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The lead sentence names a specific verb+resource ('Read session data') and the bulleted action list concretely enumerates the read modes (pmids, article, summary, artifacts, search runs, replay). However the enumeration is incomplete — the schema's 'log' action is never mentioned — and nothing distinguishes this from siblings like read_research_chronicle or fetch_article_details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is implied usage ('Each action accepts only its own fields') and a conditional instruction for artifact reads (choose artifact_id vs artifact_uri, page with artifact_file/offset/max_chars), but no explicit statement of when to call read_session versus unified_search, fetch_article_details, or read_research_chronicle.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_literature_notesA
Destructive

Save searched articles as guided local wiki/Foam/Markdown notes.

When to Use

  • After unified_search, persist the selected literature into a local note library.

  • Give agents a structured alternative to generic write_file calls.

  • Create wiki notes with Foam-compatible wikilinks, MedPaper-like reference notes, and frontmatter.

  • Use stable wiki/Foam link targets and return wiki_validation for unresolved-link checks.

Local Directory Resolution

  1. output_dir argument, if provided

  2. PUBMED_NOTES_DIR environment variable

  3. PUBMED_WORKSPACE_DIR/references

  4. PUBMED_DATA_DIR/references

Authenticated Service Boundary

Remote authenticated callers cannot choose output_dir or template_file. Their notes always go to references/ under the current tenant's installed SessionManager data root; process-wide notes/workspace environment paths are intentionally ignored.

Args: pmids: Articles to save. Accepts "last", delimited PMID text, a string array, or a JSON array string. output_dir: Optional target folder for notes. note_format: "wiki" (default, Foam-compatible), "foam", "markdown", or "medpaper". include_abstract: Include abstracts in article notes. overwrite: Overwrite existing per-article notes when filenames collide. create_index: Create a collection index note linking saved articles. collection_name: Optional title/file stem for the index note. template_file: Optional Markdown template with placeholders like {title}, {pmid}, {citation_key}. include_csl_json: Write references.csl.json beside notes for citation-manager handoff.

Returns: JSON with written/skipped files, index information, and wiki_validation. Local callers receive filesystem paths. Authenticated callers receive tenant-relative logical locators and never receive server host paths.

Examples: save_literature_notes(pmids="last") save_literature_notes(pmids="last", note_format="medpaper", output_dir="./references") save_literature_notes(pmids="12345678,87654321", template_file="./ref-template.md")

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsNolast
overwriteNo
output_dirNo
note_formatNowiki
create_indexNo
template_fileNo
collection_nameNo
include_abstractNo
include_csl_jsonNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false and openWorldHint=true, and the description goes well beyond that: it discloses the four-step directory resolution order, the authenticated-service boundary where remote callers cannot set output_dir/template_file and env paths are ignored, and the filename-collision overwrite semantics. These are non-obvious behaviors an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Headings (When to Use, Local Directory Resolution, Authenticated Service Boundary, Args, Returns, Examples) make it easy to scan and the critical scoping info is front-loaded. It runs somewhat long and repeats the format list in both prose and Args, but nearly every line carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation tool with no output schema, the description covers destination resolution, tenant/auth constraints, overwrite behavior, and even the return shape (written/skipped files, index info, wiki_validation, path vs. logical locator). An agent has everything needed to call it correctly in both local and authenticated contexts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden and largely does: the Args block defines all nine parameters, explains note_format semantics ('wiki' default, Foam-compatible), and gives template placeholder examples ({title}, {pmid}, {citation_key}). A few entries remain thin (output_dir is only 'Optional target folder'), but overall it compensates well for the empty schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+output artifact: 'Save searched articles as guided local wiki/Foam/Markdown notes.' It immediately distinguishes itself from siblings like prepare_export and generic write_file, and the note_format vocabulary (wiki/foam/markdown/medpaper) tells an agent exactly what this produces.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'When to Use' block gives explicit sequencing ('After unified_search, persist the selected literature') and names the alternative it replaces ('a structured alternative to generic write_file calls'). It also states the specific capability (Foam wikilinks, wiki_validation) that selects this tool over a plain file write.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_pipelineA
Destructive

Save a pipeline configuration for later reuse.

The config format is identical to unified_search's pipeline parameter (YAML or JSON). Saved pipelines can be loaded later by name: unified_search(pipeline="saved:weekly_remimazolam")

Args: name: Unique identifier (alphanumeric + hyphens/underscores, max 64 chars). Overwrites if name already exists (upsert semantics). config: Pipeline YAML/JSON string. Same format as unified_search pipeline param. tags: Bounded array of canonical tags (e.g., ["anesthesia", "sedation"]). description: Human-readable description of the pipeline's purpose. scope: Storage scope - "workspace" (project-level, git-trackable), "global" (user-level, cross-project), or "auto" (workspace if available, otherwise global). Default: "auto".

Returns: Confirmation with pipeline metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
tagsNo
scopeNoauto
configYes
descriptionNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=true), the description explains that saving overwrites an existing name (upsert semantics) and details storage scope semantics — workspace is git-trackable, global is cross-project, auto resolves at runtime. It does not cover permissions/errors, and the upsert language sits in mild tension with idempotentHint=false, but the destructive behavior itself is disclosed clearly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose, then uses Args/Returns structure with a compact usage example. Mostly efficient; the inline example and the repeated 'same format as unified_search pipeline param' remark cost a little redundancy but each earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the 'Returns: Confirmation with pipeline metadata' line is a reasonable (if thin) return note, and the description covers format, naming, tags, scope, and overwrite behavior for a 5-parameter mutation tool. Only operational details like permission requirements or failure modes are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry all parameter meaning, and it does: name format/limits plus overwrite behavior, config format equivalence, tags as a bounded array of canonical tags with examples, description purpose, and all three scope values with defaults. This is a strong compensation for an undocumented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Save a pipeline configuration') plus scope ('for later reuse'), and it distinguishes itself from siblings by naming the load path (unified_search(pipeline="saved:...")) and implying the inverse of load_pipeline/delete_pipeline. An agent can tell instantly what this does and how saved data flows back into unified_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage context: the config format matches unified_search's pipeline parameter, pipelines are reusable by name, and the example shows the round trip. It stops short of explicit when-to-use/when-not rules against neighbors such as schedule_pipeline or list_pipelines, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

schedule_pipelineB
Destructive

Schedule a saved pipeline for periodic execution.

Args: name: Saved pipeline name. cron: Required 5-field cron expression. Example: "0 9 * * 1" (Mon 9am). diff_mode: When True, store diff-mode preference with the schedule. notify: When True, store notify preference with the schedule.

Returns: Schedule confirmation or removal result.

ParametersJSON Schema
NameRequiredDescriptionDefault
cronYes
nameYes
notifyNo
diff_modeNo

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, openWorldHint=true, and idempotentHint=false, so the safety profile is largely covered. The description adds useful behavioral detail about storing diff-mode and notify preferences and returning a confirmation, but it does not explain authorization needs, what exactly is destroyed or replaced, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a one-line summary followed by structured Args and Returns sections, with no wasted prose. The vague 'removal result' clause slightly weakens an otherwise efficient structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive scheduling tool with four parameters and no output schema, the description covers parameter meanings and a basic return type, and the annotations supply safety hints. However, it omits when to choose this tool over unschedule_pipeline and leaves the 'removal result' ambiguous, so an agent still lacks some routing and outcome clarity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden of explaining parameters. It successfully documents all four parameters, including a concrete cron example and the meaning of diff_mode/notify preference storage, though it does not elaborate on the name pattern or boolean-string nuance already present in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Schedule') and resource ('saved pipeline') with the scope 'periodic execution,' making the core action clear. However, the later phrase 'removal result' introduces ambiguity with the sibling tool unschedule_pipeline, preventing perfect clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by saying it schedules a saved pipeline, but it offers no explicit when-to-use guidance, no exclusions, and no mention of the alternative unschedule_pipeline for removing schedules. An agent must infer the routing from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_biomedical_imagesA
Read-onlyIdempotent

🖼️ Search biomedical images from NLM Open-i.

Searches medical/scientific images from Open-i and returns image URLs with metadata (caption, article info, MeSH terms).

═══════════════════════════════════════════════════════════════ ⚠️ CRITICAL - LANGUAGE REQUIREMENT: ═══════════════════════════════════════════════════════════ Open-i ONLY supports English queries. If the user queries in non-English (Chinese, Japanese, Korean, etc.), you MUST:

  1. Translate the query to English medical terminology first

  2. Then call this tool with the English query Example: "喉頭水腫" → "laryngeal edema" "胸部X光肺炎" → "chest X-ray pneumonia"

The tool has built-in translation hints for common CJK medical terms, but YOU should always verify the translation is correct.

═══════════════════════════════════════════════════════════ SOURCES: ═══════════════════════════════════════════════════════════════

  • Open-i (NLM): X-ray, microscopy, clinical images

═══════════════════════════════════════════════════════════════ EXAMPLES: ═══════════════════════════════════════════════════════════════

General image search: search_biomedical_images("chest pneumonia CT scan")

X-ray only: search_biomedical_images("fracture", image_type="x")

Microscopy images: search_biomedical_images("histology liver", image_type="mc")

Clinical teaching images (MedPix): search_biomedical_images("pneumothorax", collection="mpx")

Case reports with CC-BY license, sorted by date: search_biomedical_images( "lung cancer", article_type="cr", license_type="by", sort_by="d" )

Cardiology specialty images: search_biomedical_images("echocardiogram", specialty="c")

Video content only: search_biomedical_images("surgery technique", video_only=True)

═══════════════════════════════════════════════════════════════

Args: query: Search query (e.g., "chest X-ray pneumonia") image_type: Filter by image type (Open-i only): Positive filters: - "c": CT scan images - "g": Graphics / line art / diagrams - "m": MRI images - "mc": Microscopy / histology images - "p": PET scan images - "ph": Photographs / clinical photos - "u": Ultrasound images - "x": X-ray images Exclusion filters: - "xg": Exclude Graphics (removes graphic images from results) - "xm": Exclude Multipanel (removes multipanel images) - None: All types (default) collection: Filter by collection (Open-i only): - "pmc": PubMed Central articles - "mpx": MedPix clinical teaching images (high quality) - "cxr": Chest X-ray collection - "hmd": History of Medicine - "usc": USC collection - None: All collections (default) limit: Maximum number of images to return (default 10, max 50) sort_by: Sort results by (Open-i only): - "r": Relevance (default) - "d": Date (newest first) - "o": Oldest first - "t": Title - "e": Education relevance - "g": Graphics priority article_type: Filter by article type (Open-i only): - "cr": Case Report - "or": Original Research - "re": Review - "sr": Systematic Review - "ra": Research Article - "ed": Editorial - "lt": Letter - "bk": Book - and more... (see API docs) specialty: Filter by medical specialty (Open-i only): - "r": Radiology - "c": Cardiology - "ne": Neurology - "pu": Pulmonology - "d": Dermatology - "g": Gastroenterology - "or": Orthopedics - "o": Ophthalmology - "s": Surgery - "p": Pediatrics - "id": Infectious Disease - "i": Immunology - and more... (see API docs) license_type: Filter by Creative Commons license (Open-i only): - "by": CC-BY (Attribution) - "bync": CC-BY-NC (Attribution-NonCommercial) - "byncnd": CC-BY-NC-ND (Attribution-NonCommercial-NoDerivs) - "byncsa": CC-BY-NC-SA (Attribution-NonCommercial-ShareAlike) subset: Filter by subject subset (Open-i only): - "b": Behavioral Sciences - "c": Cancer - "e": Ethics - "s": Surgery - "x": Toxicology search_fields: Search in specific fields (Open-i only): - "t": Title only - "m": MeSH terms only - "ab": Abstract only - "msh": MeSH heading only - "c": Caption only - "a": Author only video_only: If True, only return video content (default False) hmp_type: History of Medicine publication type. Requires collection="hmd".

Returns: Formatted image results with URLs, captions, and article metadata

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
subsetNo
sort_byNo
hmp_typeNo
specialtyNo
collectionNo
image_typeNo
video_onlyNo
article_typeNo
license_typeNo
search_fieldsNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld, and the description adds genuine operational context on top: Open-i accepts English only, built-in CJK translation hints exist but must be verified, limit defaults to 10 with a max of 50, and hmp_type requires collection='hmd'. It does not cover rate limits or result pagination, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the critical language rule are front-loaded, which is good, but the repeated full-width ASCII rule lines and emoji consume substantial tokens without adding information, and the source list restates the opening sentence. The enum documentation earns its space; the decorative separators do not.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with no schema descriptions and no output schema, the description supplies nearly everything needed to call it correctly, including filter semantics and the return shape in prose. Gaps remain around pagination and behavior when zero images match.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it does: every parameter's enum codes are decoded (image_type, collection, sort_by, specialty, license_type, subset, search_fields), inclusion vs exclusion filters are separated, and the cross-parameter dependency on collection='hmd' is stated. Only a few enum members are deferred to "see API docs".

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line names the exact verb, resource, and source ("Search biomedical images from NLM Open-i") and the second states the return content (image URLs with caption, article info, MeSH terms). It is unambiguously distinguishable from article-oriented siblings like unified_search and fetch_article_details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides rich context for use: the mandatory English-query rule, a translation workflow, and seven worked examples mapping intent to filters (collection='mpx' for MedPix, video_only for video). However, it never routes the agent away from or toward the closest siblings such as get_article_figures or prepare_figure_search, so the when-not half is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_clinvarA
Read-onlyIdempotent

Search ClinVar for clinical variants.

═══════════════════════════════════════════════════════════════ USE CASES: ═══════════════════════════════════════════════════════════════

  • Look up clinical significance of genetic variants

  • Find variants associated with diseases

  • Research gene-disease associations

  • Get variant pathogenicity classifications

Args: query: Gene name, variant, or disease condition limit: Maximum results (1-50)

Returns: JSON with variant records including significance and conditions

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is fully covered. The description adds value beyond that by stating the return shape ('JSON with variant records including significance and conditions'), which is useful given there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is short and front-loaded: purpose first, then use cases, args, and returns. The heavy '═' divider lines are decorative noise, but they do not meaningfully bloat the semantic content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only search with no output schema, the description covers purpose, invocation contexts, both parameters, and the general return shape. Pagination or ranking details are absent, but they are not essential for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It explains that 'query' accepts a gene name, variant, or disease condition, and that 'limit' is a 1–50 maximum-result count, which meaningfully supplements the bare schema constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Search ClinVar for clinical variants') and the use cases make the domain explicit. It does not, however, distinguish itself from sibling tools such as search_gene, search_compound, or unified_search, so an agent cannot route between them from this text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USE CASES section gives clear contexts for when to call it (looking up clinical significance, disease associations, pathogenicity classifications). There are no explicit exclusions or alternatives named, but the positive guidance is strong enough to be actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_compoundB
Read-onlyIdempotent

Search PubChem for chemical compounds.

═══════════════════════════════════════════════════════════════ USE CASES: ═══════════════════════════════════════════════════════════════

  • Look up drug/compound information

  • Find molecular formula and structure

  • Get compound synonyms and identifiers

  • Research chemical properties

Args: query: Compound name or description limit: Maximum results (1-50)

Returns: JSON with compound records including names, formulas, properties

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered by structured data. The description adds only the return shape (JSON records with names, formulas, properties) and the 1-50 limit; nothing about upstream rate limits, match behavior (fuzzy vs. exact), or empty-result handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and use cases are front-loaded correctly, but the heavy box-drawing separator banners add visual noise without information, and the Args/Returns restatement pads the entry beyond what a two-parameter tool needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does supply a brief Returns line, and both parameters are named, so nothing critical is missing. It stops short of describing result ordering, result count behavior when limit is hit, or how queries are matched, which matters for an external open-world search.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden. It documents both parameters — query as 'compound name or description' and limit as 'maximum results (1-50)' — but the query hint is thin (no format/synonym guidance) and the limit note merely restates the schema bounds, leaving the default of 10 unmentioned.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line states a specific verb and resource: search PubChem for chemical compounds, which is unambiguous on its own. It does not, however, distinguish itself from nearby siblings such as get_compound_details or get_compound_literature, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USE CASES block enumerates good reasons to call it (drug lookups, molecular formula, synonyms, properties), which implies usage. But there is no when-not guidance and no explicit routing to get_compound_details (fetch details for a known compound) or get_compound_literature, which are the obvious alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_geneA
Read-onlyIdempotent

Search NCBI Gene database for gene information.

═══════════════════════════════════════════════════════════════ USE CASES: ═══════════════════════════════════════════════════════════════

  • Look up gene function and description

  • Find gene aliases and official symbols

  • Get chromosome location

  • Find genes by name or function

Args: query: Gene name, symbol, or function keyword organism: Filter by organism (e.g., "human", "Homo sapiens", "mouse") limit: Maximum results (1-50)

Returns: JSON with gene records including symbols, names, locations

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
organismNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the return shape ('JSON with gene records including symbols, names, locations') and the result-count range, which the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded (purpose first, then use cases, args, returns) and each content line is short and useful. The triple-line box-drawing banners are pure decoration that consume tokens without adding information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies a brief return summary, and annotations cover behavior for this read-only search. The remaining gap is routing relative to get_gene_details and get_gene_literature, plus any note on result ordering or pagination.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the param burden and largely does: query is described as 'Gene name, symbol, or function keyword', and organism includes concrete accepted values ('human', 'Homo sapiens', 'mouse'), which is genuinely useful for a taxonomy-filtered API. The limit line only restates the schema's 1-50 bound and adds no ranking or sorting semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb and resource: 'Search NCBI Gene database for gene information,' with a use-case list that scopes what it retrieves (function, aliases, symbols, location). It does not distinguish itself from siblings like get_gene_details or get_gene_literature, so an agent must infer search-vs-fetch from the name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The USE CASES block gives concrete retrieval scenarios (look up gene function, find aliases/symbols, get chromosome location, search by name or function keyword), which is clear usage context. It stops short of exclusions or naming the alternative tools to use when you already have a gene ID or want literature about a gene.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

test_institutional_accessA
Read-onlyIdempotent

Test your institutional link resolver configuration.

═══════════════════════════════════════════════════════════════════════════════ 🧪 TEST INSTITUTIONAL ACCESS ═══════════════════════════════════════════════════════════════════════════════

Tests if your configured link resolver is:

  1. Properly configured

  2. Reachable (network connection)

  3. Returns a valid response

NOTE: This only tests if the resolver endpoint is reachable. Actual full-text access depends on your institution's subscriptions.

═══════════════════════════════════════════════════════════════════════════════ FREE TEST OPTIONS: ═══════════════════════════════════════════════════════════════════════════════

If you don't have institutional access, you can test with:

  1. Use "test_free" preset (EBSCO public resolver): configure_institutional_access(preset="test_free") test_institutional_access()

  2. Most university resolvers will respond even without VPN, they just won't provide full-text (shows "Access options" page)

Args: pmid: PMID to use for testing (default: 38353755)

Returns: Test results including: - Configuration status - Network reachability - Generated OpenURL - Link to test manually

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidNoComplete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers.38353755

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful scope-limiting context beyond that: it only tests endpoint reachability, actual full-text depends on subscriptions, and a resolver may respond without VPN while still not serving full text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is useful, but it is wrapped in large ASCII banner blocks with repeated separators, producing substantial visual noise for what amounts to a few sentences. Front-loading is fine, but the decoration is not earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only test tool, the definition supplies purpose, scope caveats, a return-value outline, and setup guidance. That is complete enough for correct invocation; the only real omission is how it relates to the sibling diagnostic tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema description coverage is 100%, so the schema carries the semantic load (format, examples, length limits). The description merely restates the pmid default (38353755), adding essentially nothing beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (test) and resource (institutional link resolver configuration) and enumerates what is being checked: configuration, reachability, and response validity. It does not, however, distinguish itself from the sibling diagnose_institutional_access, which appears to cover very similar ground.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The FREE TEST OPTIONS section gives clear situational guidance: if you lack institutional access, call configure_institutional_access(preset="test_free") first, and it notes most university resolvers respond without VPN. That is real when-to-use context, though it never contrasts with the sibling diagnose_institutional_access tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unschedule_pipelineA
DestructiveIdempotent

Remove the active schedule for a saved pipeline.

Args: name: Saved pipeline name whose schedule will be removed.

Returns: Removed schedule metadata, or a native MCP error when none exists.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false. The description adds one useful behavioral detail beyond that: the response is removed schedule metadata, or an MCP error when no schedule exists (consistent with idempotentHint). It does not state auth/permission needs or whether other schedule config is affected.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, followed by concise Args/Returns sections. No filler; the one-line summary plus parameter and return notes earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter mutation with no output schema, the description covers the action, the parameter's meaning, and the return/error behavior, while annotations cover the safety profile. Only permission requirements and interaction with other schedule state are unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the schema's 'name' property carries no prose. The description compensates by clarifying the parameter means the 'Saved pipeline name whose schedule will be removed,' disambiguating it from a schedule ID or arbitrary string.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource: 'Remove the active schedule for a saved pipeline.' It is clearly distinct from delete_pipeline (removes the pipeline) and schedule_pipeline (adds a schedule), though it does not name those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the verb and the pipeline-scheduling sibling set, but the description never states when to use this versus schedule_pipeline, delete_pipeline, or what state the pipeline must be in. No alternatives or exclusions are offered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_pico_planA
Read-onlyIdempotent

Validate agent-provided P/I/C/O and return a runnable PICO pipeline.

question_type and profile are closed enums. sources is an explicit array of supported unified-search providers; malformed values fail instead of being silently replaced. When question_type is omitted, the application service infers it from the clinical question.

ParametersJSON Schema
NameRequiredDescriptionDefault
cNo
iNo
oNo
pNo
limitNo
c_queryNo
i_queryNo
o_queryNo
p_queryNo
profileNobalanced
sourcesNo
descriptionNo
question_typeNo

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/non-destructive/closed-world, so the bar is lower. The description adds real traits beyond them: malformed enum/array values fail hard rather than being silently replaced, and the service infers question_type on omission. Return-pipeline shape is still undefined, keeping it short of 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and output in one sentence, then adds enum/failure semantics tersely. Dense but every sentence carries information; no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the enum and sources semantics, but for a 13-parameter tool with no output schema the description never explains which parameters are required together, what the returned pipeline looks like, or how the *_query fields relate to the P/I/C/O fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 13 parameters, so the description must carry the load. It clarifies only three fields (closed enums for question_type/profile, explicit sources array) and leaves limit, description, and the *_query fields to name inference, well short of compensating for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('validate agent-provided P/I/C/O') plus the output ('return a runnable PICO pipeline'). This is clearly distinguishable from siblings like unified_search or generate_search_queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this vs. alternatives, and no prerequisites stated. The only usage-adjacent statement is the fallback when question_type is omitted, which is behavioral rather than when-to-use advice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_reference_listA
Read-onlyIdempotent

Verify a plain-text reference list against PubMed evidence.

First version scope: - Reference-list verification only - Client supplies the extracted reference list text - Backend parses entries and resolves them via PMID / DOI / ECitMatch

Second version scope: - Adds unresolved review workflow for partial_match and unresolved rows - Returns a manual-review queue with retry queries and review checklist - Supports human-in-the-loop acceptance/rejection in client-side workflows

Args: reference_text: Plain-text references, ideally one per line or a numbered reference list extracted from a file. Limited to 200,000 characters / 400,000 UTF-8 bytes; each entry is limited to 4,000 characters / 8,000 UTF-8 bytes. source_name: Optional single-line file label for reporting (up to 255 characters / 512 UTF-8 bytes). max_references: Hard input-entry limit from 1 through 200. Inputs above the selected limit are rejected instead of truncated.

Returns: JSON verification report with parsed fields, matched PubMed evidence, per-reference verification status, and explicit source_unavailable / not_checked rows when evidence could not be assessed.

ParametersJSON Schema
NameRequiredDescriptionDefault
source_nameNo
max_referencesNo
reference_textYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a read-only, idempotent, open-world, non-destructive operation, so the safety bar is low. The description still adds real behavioral content: hard size/entry limits, that over-limit input is rejected rather than truncated, and that unresolved evidence surfaces as explicit source_unavailable / not_checked rows. It stops short of describing performance or retry behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The Args/Returns structure is clear and front-loaded, but the "Second version scope" block describes future behavior that is not invocable today, consuming roughly a third of the text without helping an agent call the tool now. That section is the main argument for a mid score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly takes on return-value explanation (parsed fields, matched evidence, per-reference status, explicit unavailable rows), and it covers all limits and required inputs. Complete enough to invoke correctly; only the ambiguity about whether v2 behavior is currently active leaves a gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load and it does: reference_text limits (200,000 chars / 400,000 bytes, 4,000 per entry), source_name as an optional single-line reporting label with a stated length cap, and max_references bounds (1-200) plus the rejection-instead-of-truncation rule. All three parameters gain meaning the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: "Verify a plain-text reference list against PubMed evidence." No sibling performs reference-list verification, so an agent can route to it without ambiguity. The resolution mechanisms (PMID / DOI / ECitMatch) further pin down what the tool actually does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It establishes that the client must supply already-extracted reference text, which is useful pre-condition context, but it never states when to pick this over sibling tools that also surface references (e.g. get_article_references, build_citation_tree) or what inputs are unsuitable. The v1/v2 scope split is informative about roadmap rather than about invocation choices.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 34 tool updatesv0.7.7
    • Changedbuild_citation_tree18 fields changed
      • addedInput schema / properties / depth / anyOf
        Added value: +[
        +  {
        +    "default": 2,
        +    "maximum": 3,
        +    "minimum": 1,
        +    "title": "Depth",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / depth / maximum
        Removed value: -3
      • removedInput schema / properties / depth / minimum
        Removed value: -1
      • removedInput schema / properties / depth / type
        Removed value: -"integer"
      • addedInput schema / properties / direction / anyOf
        Added value: +[
        +  {
        +    "default": "both",
        +    "enum": [
        +      "forward",
        +      "backward",
        +      "both"
        +    ],
        +    "title": "Direction",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[fF][oO][rR][wW][aA][rR][dD]|[bB][aA][cC][kK][wW][aA][rR][dD]|[bB][oO][tT][hH])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / direction / enum
        Removed value: -[
        -  "forward",
        -  "backward",
        -  "both"
        -]
      • removedInput schema / properties / direction / type
        Removed value: -"string"
      • addedInput schema / properties / limit_per_level / anyOf
        Added value: +[
        +  {
        +    "default": 5,
        +    "maximum": 20,
        +    "minimum": 1,
        +    "title": "Limit Per Level",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit_per_level / maximum
        Removed value: -20
      • removedInput schema / properties / limit_per_level / minimum
        Removed value: -1
      • removedInput schema / properties / limit_per_level / type
        Removed value: -"integer"
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "cytoscape",
        +    "enum": [
        +      "cytoscape",
        +      "g6",
        +      "d3",
        +      "vis",
        +      "graphml",
        +      "mermaid"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][yY][tT][oO][sS][cC][aA][pP][eE]|[gG]6|[dD]3|[vV][iI][sS]|[gG][rR][aA][pP][hH][mM][lL]|[mM][eE][rR][mM][aA][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "cytoscape",
        -  "g6",
        -  "d3",
        -  "vis",
        -  "graphml",
        -  "mermaid"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • addedInput schema / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / properties / pmid / format
        Added value: +"pubmed-pmid"
      • addedInput schema / properties / pmid / x-pubmed-input
        Added value: +"pmid"
    • Changedbuild_research_chronicle7 fields changed
      • changedInput schema / properties / max_events / anyOf
        Previous value: -[
        -  {
        -    "description": "Maximum Chronicle events",
        -    "maximum": 200,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Maximum Chronicle events",
        +    "maximum": 200,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / max_year / anyOf
        Previous value: -[
        -  {
        -    "description": "Four-digit publication year",
        -    "maximum": 2100,
        -    "minimum": 1000,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Four-digit publication year",
        +    "maximum": 2100,
        +    "minimum": 1000,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / min_year / anyOf
        Previous value: -[
        -  {
        -    "description": "Four-digit publication year",
        -    "maximum": 2100,
        -    "minimum": 1000,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Four-digit publication year",
        +    "maximum": 2100,
        +    "minimum": 1000,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / output / anyOf
        Added value: +[
        +  {
        +    "default": "summary",
        +    "enum": [
        +      "summary",
        +      "json",
        +      "chronicle_map",
        +      "timeline",
        +      "tree",
        +      "graph",
        +      "evidence",
        +      "milestones",
        +      "mermaid",
        +      "narrative"
        +    ],
        +    "title": "Output",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[sS][uU][mM][mM][aA][rR][yY]|[jJ][sS][oO][nN]|[cC][hH][rR][oO][nN][iI][cC][lL][eE]_[mM][aA][pP]|[tT][iI][mM][eE][lL][iI][nN][eE]|[tT][rR][eE][eE]|[gG][rR][aA][pP][hH]|[eE][vV][iI][dD][eE][nN][cC][eE]|[mM][iI][lL][eE][sS][tT][oO][nN][eE][sS]|[mM][eE][rR][mM][aA][iI][dD]|[nN][aA][rR][rR][aA][tT][iI][vV][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output / enum
        Removed value: -[
        -  "summary",
        -  "json",
        -  "chronicle_map",
        -  "timeline",
        -  "tree",
        -  "graph",
        -  "evidence",
        -  "milestones",
        -  "mermaid",
        -  "narrative"
        -]
      • removedInput schema / properties / output / type
        Removed value: -"string"
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "maxLength": 10000,
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "description": "Complete PMID(s): delimited text, JSON string array, or Markdown list; optional JSON code fence. last only where supported.",
        +        "examples": [
        +          "33053718,36170657",
        +          "[\"33053718\",\"36170657\"]",
        +          "- 33053718\n- 36170657"
        +        ],
        +        "format": "pubmed-pmid-batch",
        +        "maxLength": 100000,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      {
        +        "items": {
        +          "description": "One PMID string, or last as the sole batch item for tools supporting session reuse.",
        +          "examples": [
        +            "33053718"
        +          ],
        +          "format": "pubmed-pmid",
        +          "maxLength": 512,
        +          "minLength": 1,
        +          "type": "string",
        +          "x-pubmed-input": "pmid"
        +        },
        +        "maxItems": 1000,
        +        "minItems": 1,
        +        "type": "array"
        +      }
        +    ],
        +    "x-pubmed-input": "pmid_batch"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedconfigure_institutional_access3 fields changed
      • addedInput schema / properties / enable / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Enable",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / enable / type
        Removed value: -"boolean"
      • changedInput schema / properties / preset / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "ntu",
        -      "ncku",
        -      "nthu",
        -      "nycu",
        -      "harvard",
        -      "stanford",
        -      "mit",
        -      "yale",
        -      "oxford",
        -      "cambridge",
        -      "sfx",
        -      "360link",
        -      "primo",
        -      "test_free"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "ntu",
        +          "ncku",
        +          "nthu",
        +          "nycu",
        +          "harvard",
        +          "stanford",
        +          "mit",
        +          "yale",
        +          "oxford",
        +          "cambridge",
        +          "sfx",
        +          "360link",
        +          "primo",
        +          "test_free"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[nN][tT][uU]|[nN][cC][kK][uU]|[nN][tT][hH][uU]|[nN][yY][cC][uU]|[hH][aA][rR][vV][aA][rR][dD]|[sS][tT][aA][nN][fF][oO][rR][dD]|[mM][iI][tT]|[yY][aA][lL][eE]|[oO][xX][fF][oO][rR][dD]|[cC][aA][mM][bB][rR][iI][dD][gG][eE]|[sS][fF][xX]|360[lL][iI][nN][kK]|[pP][rR][iI][mM][oO]|[tT][eE][sS][tT]_[fF][rR][eE][eE])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedconvert_icd_mesh3 fields changed
      • addedInput schema / properties / direction / anyOf
        Added value: +[
        +  {
        +    "enum": [
        +      "icd_to_mesh",
        +      "mesh_to_icd"
        +    ],
        +    "title": "Direction",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[iI][cC][dD]_[tT][oO]_[mM][eE][sS][hH]|[mM][eE][sS][hH]_[tT][oO]_[iI][cC][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / direction / enum
        Removed value: -[
        -  "icd_to_mesh",
        -  "mesh_to_icd"
        -]
      • removedInput schema / properties / direction / type
        Removed value: -"string"
    • Changeddiagnose_institutional_access26 fields changed
      • addedInput schema / $defs / DOISource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "doi",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[dD][oO][iI])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / DOISource / properties / kind / const
        Removed value: -"doi"
      • removedInput schema / $defs / DOISource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / DOISource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / DOISource / properties / value / examples
        Added value: +[
        +  "10.1000/example",
        +  "doi:10.1000/example",
        +  "https://doi.org/10.1000/example"
        +]
      • addedInput schema / $defs / DOISource / properties / value / format
        Added value: +"pubmed-doi"
      • changedInput schema / $defs / DOISource / properties / value / minLength
        Previous value: -7New value: +1
      • removedInput schema / $defs / DOISource / properties / value / pattern
        Removed value: -"^10\\.[0-9]{4,9}/"
      • addedInput schema / $defs / DOISource / properties / value / x-pubmed-input
        Added value: +"doi"
      • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMIDSource / properties / kind / const
        Removed value: -"pmid"
      • removedInput schema / $defs / PMIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMIDSource / properties / value / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / PMIDSource / properties / value / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / PMIDSource / properties / value / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / PMIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMIDSource / properties / value / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
        Added value: +"pmid"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "doi": "#/$defs/DOISource",
        +        "pmid": "#/$defs/PMIDSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/PMIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/DOISource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "doi": "#/$defs/DOISource",
        -    "pmid": "#/$defs/PMIDSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/PMIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/DOISource"
        -  }
        -]
      • addedInput schema / properties / try_direct / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Try Direct",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / try_direct / type
        Removed value: -"boolean"
      • addedInput schema / properties / try_ezproxy / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Try Ezproxy",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / try_ezproxy / type
        Removed value: -"boolean"
    • Changedfetch_article_details6 fields changed
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "maxLength": 100000,
        -    "minLength": 1,
        -    "type": "string"
        -  },
        -  {
        -    "items": {
        -      "maxLength": 512,
        -      "minLength": 1,
        -      "type": "string"
        -    },
        -    "maxItems": 1000,
        -    "minItems": 1,
        -    "type": "array"
        -  }
        -]New value: +[
        +  {
        +    "description": "Complete PMID(s): delimited text, JSON string array, or Markdown list; optional JSON code fence. last only where supported.",
        +    "examples": [
        +      "33053718,36170657",
        +      "[\"33053718\",\"36170657\"]",
        +      "- 33053718\n- 36170657"
        +    ],
        +    "format": "pubmed-pmid-batch",
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "description": "Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers.",
        +      "examples": [
        +        "33053718",
        +        "PMID:33053718",
        +        "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +      ],
        +      "format": "pubmed-pmid",
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string",
        +      "x-pubmed-input": "pmid"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / pmids / description
        Added value: +"Explicit PMIDs; last is not supported."
      • addedInput schema / properties / pmids / x-pubmed-input
        Added value: +"pmid_batch"
    • Changedfind_citing_articles8 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / properties / pmid / format
        Added value: +"pubmed-pmid"
      • addedInput schema / properties / pmid / x-pubmed-input
        Added value: +"pmid"
    • Changedfind_related_articles8 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 5,
        +    "maximum": 50,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -50
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / properties / pmid / format
        Added value: +"pubmed-pmid"
      • addedInput schema / properties / pmid / x-pubmed-input
        Added value: +"pmid"
    • Changedgenerate_search_queries7 fields changed
      • addedInput schema / properties / check_spelling / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Check Spelling",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / check_spelling / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_suggestions / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include Suggestions",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_suggestions / type
        Removed value: -"boolean"
      • addedInput schema / properties / strategy / anyOf
        Added value: +[
        +  {
        +    "default": "comprehensive",
        +    "enum": [
        +      "comprehensive",
        +      "focused",
        +      "exploratory"
        +    ],
        +    "title": "Strategy",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][oO][mM][pP][rR][eE][hH][eE][nN][sS][iI][vV][eE]|[fF][oO][cC][uU][sS][eE][dD]|[eE][xX][pP][lL][oO][rR][aA][tT][oO][rR][yY])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / strategy / enum
        Removed value: -[
        -  "comprehensive",
        -  "focused",
        -  "exploratory"
        -]
      • removedInput schema / properties / strategy / type
        Removed value: -"string"
    • Changedget_article_figures30 fields changed
      • addedInput schema / $defs / PMCIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmcid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][cC][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMCIDSource / properties / kind / const
        Removed value: -"pmcid"
      • removedInput schema / $defs / PMCIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMCIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMCIDSource / properties / value / examples
        Added value: +[
        +  "PMC12345",
        +  "https://pmc.ncbi.nlm.nih.gov/articles/PMC12345/"
        +]
      • addedInput schema / $defs / PMCIDSource / properties / value / format
        Added value: +"pubmed-pmcid"
      • changedInput schema / $defs / PMCIDSource / properties / value / maxLength
        Previous value: -23New value: +512
      • addedInput schema / $defs / PMCIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMCIDSource / properties / value / pattern
        Removed value: -"^PMC[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMCIDSource / properties / value / x-pubmed-input
        Added value: +"pmcid"
      • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMIDSource / properties / kind / const
        Removed value: -"pmid"
      • removedInput schema / $defs / PMIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMIDSource / properties / value / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / PMIDSource / properties / value / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / PMIDSource / properties / value / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / PMIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMIDSource / properties / value / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
        Added value: +"pmid"
      • addedInput schema / properties / include_subfigures / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include Subfigures",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_subfigures / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_tables / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include Tables",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_tables / type
        Removed value: -"boolean"
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "pmcid": "#/$defs/PMCIDSource",
        +        "pmid": "#/$defs/PMIDSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/PMIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/PMCIDSource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "pmcid": "#/$defs/PMCIDSource",
        -    "pmid": "#/$defs/PMIDSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/PMIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/PMCIDSource"
        -  }
        -]
    • Changedget_article_references8 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 20,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / properties / pmid / format
        Added value: +"pubmed-pmid"
      • addedInput schema / properties / pmid / x-pubmed-input
        Added value: +"pmid"
    • Changedget_citation_metrics11 fields changed
      • changedInput schema / properties / min_citations / anyOf
        Previous value: -[
        -  {
        -    "maximum": 2000000000,
        -    "minimum": 0,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 2000000000,
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / min_percentile / anyOf
        Previous value: -[
        -  {
        -    "maximum": 100,
        -    "minimum": 0,
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 100,
        +    "minimum": 0,
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "Finite decimal number; the numeric branch's bounds apply after conversion.",
        +    "maxLength": 64,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / min_rcr / anyOf
        Previous value: -[
        -  {
        -    "maximum": 1000000,
        -    "minimum": 0,
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 1000000,
        +    "minimum": 0,
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "Finite decimal number; the numeric branch's bounds apply after conversion.",
        +    "maxLength": 64,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "maxLength": 100000,
        -    "minLength": 1,
        -    "type": "string"
        -  },
        -  {
        -    "items": {
        -      "maxLength": 512,
        -      "minLength": 1,
        -      "type": "string"
        -    },
        -    "maxItems": 1000,
        -    "minItems": 1,
        -    "type": "array"
        -  }
        -]New value: +[
        +  {
        +    "description": "Complete PMID(s): delimited text, JSON string array, or Markdown list; optional JSON code fence. last only where supported.",
        +    "examples": [
        +      "33053718,36170657",
        +      "[\"33053718\",\"36170657\"]",
        +      "- 33053718\n- 36170657"
        +    ],
        +    "format": "pubmed-pmid-batch",
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "description": "One PMID string, or last as the sole batch item for tools supporting session reuse.",
        +      "examples": [
        +        "33053718"
        +      ],
        +      "format": "pubmed-pmid",
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string",
        +      "x-pubmed-input": "pmid"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / pmids / x-pubmed-input
        Added value: +"pmid_batch"
      • addedInput schema / properties / sort_by / anyOf
        Added value: +[
        +  {
        +    "default": "citation_count",
        +    "enum": [
        +      "citation_count",
        +      "relative_citation_ratio",
        +      "nih_percentile",
        +      "citations_per_year"
        +    ],
        +    "title": "Sort By",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][iI][tT][aA][tT][iI][oO][nN]_[cC][oO][uU][nN][tT]|[rR][eE][lL][aA][tT][iI][vV][eE]_[cC][iI][tT][aA][tT][iI][oO][nN]_[rR][aA][tT][iI][oO]|[nN][iI][hH]_[pP][eE][rR][cC][eE][nN][tT][iI][lL][eE]|[cC][iI][tT][aA][tT][iI][oO][nN][sS]_[pP][eE][rR]_[yY][eE][aA][rR])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / sort_by / enum
        Removed value: -[
        -  "citation_count",
        -  "relative_citation_ratio",
        -  "nih_percentile",
        -  "citations_per_year"
        -]
      • removedInput schema / properties / sort_by / type
        Removed value: -"string"
    • Changedget_compound_literature4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 20,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedget_fulltext42 fields changed
      • addedInput schema / $defs / DOISource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "doi",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[dD][oO][iI])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / DOISource / properties / kind / const
        Removed value: -"doi"
      • removedInput schema / $defs / DOISource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / DOISource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / DOISource / properties / value / examples
        Added value: +[
        +  "10.1000/example",
        +  "doi:10.1000/example",
        +  "https://doi.org/10.1000/example"
        +]
      • addedInput schema / $defs / DOISource / properties / value / format
        Added value: +"pubmed-doi"
      • changedInput schema / $defs / DOISource / properties / value / minLength
        Previous value: -7New value: +1
      • removedInput schema / $defs / DOISource / properties / value / pattern
        Removed value: -"^10\\.[0-9]{4,9}/"
      • addedInput schema / $defs / DOISource / properties / value / x-pubmed-input
        Added value: +"doi"
      • addedInput schema / $defs / PMCIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmcid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][cC][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMCIDSource / properties / kind / const
        Removed value: -"pmcid"
      • removedInput schema / $defs / PMCIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMCIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMCIDSource / properties / value / examples
        Added value: +[
        +  "PMC12345",
        +  "https://pmc.ncbi.nlm.nih.gov/articles/PMC12345/"
        +]
      • addedInput schema / $defs / PMCIDSource / properties / value / format
        Added value: +"pubmed-pmcid"
      • changedInput schema / $defs / PMCIDSource / properties / value / maxLength
        Previous value: -23New value: +512
      • addedInput schema / $defs / PMCIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMCIDSource / properties / value / pattern
        Removed value: -"^PMC[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMCIDSource / properties / value / x-pubmed-input
        Added value: +"pmcid"
      • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMIDSource / properties / kind / const
        Removed value: -"pmid"
      • removedInput schema / $defs / PMIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMIDSource / properties / value / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / PMIDSource / properties / value / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / PMIDSource / properties / value / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / PMIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMIDSource / properties / value / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
        Added value: +"pmid"
      • changedInput schema / properties / allow_browser_session / anyOf
        Previous value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / properties / extended_sources / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Extended Sources",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / extended_sources / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_figures / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include Figures",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_figures / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_pdf_links / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include Pdf Links",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_pdf_links / type
        Removed value: -"boolean"
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "doi": "#/$defs/DOISource",
        +        "pmcid": "#/$defs/PMCIDSource",
        +        "pmid": "#/$defs/PMIDSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/PMIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/PMCIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/DOISource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "doi": "#/$defs/DOISource",
        -    "pmcid": "#/$defs/PMCIDSource",
        -    "pmid": "#/$defs/PMIDSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/PMIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/PMCIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/DOISource"
        -  }
        -]
    • Changedget_gene_literature4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 20,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedget_institutional_link26 fields changed
      • addedInput schema / $defs / DOISource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "doi",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[dD][oO][iI])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / DOISource / properties / kind / const
        Removed value: -"doi"
      • removedInput schema / $defs / DOISource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / DOISource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / DOISource / properties / value / examples
        Added value: +[
        +  "10.1000/example",
        +  "doi:10.1000/example",
        +  "https://doi.org/10.1000/example"
        +]
      • addedInput schema / $defs / DOISource / properties / value / format
        Added value: +"pubmed-doi"
      • changedInput schema / $defs / DOISource / properties / value / minLength
        Previous value: -7New value: +1
      • removedInput schema / $defs / DOISource / properties / value / pattern
        Removed value: -"^10\\.[0-9]{4,9}/"
      • addedInput schema / $defs / DOISource / properties / value / x-pubmed-input
        Added value: +"doi"
      • addedInput schema / $defs / InstitutionalMetadataSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "metadata",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][eE][tT][aA][dD][aA][tT][aA])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / InstitutionalMetadataSource / properties / kind / const
        Removed value: -"metadata"
      • removedInput schema / $defs / InstitutionalMetadataSource / properties / kind / type
        Removed value: -"string"
      • changedInput schema / $defs / InstitutionalMetadataSource / properties / year / anyOf
        Previous value: -[
        -  {
        -    "maximum": 9999,
        -    "minimum": 1000,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 9999,
        +    "minimum": 1000,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMIDSource / properties / kind / const
        Removed value: -"pmid"
      • removedInput schema / $defs / PMIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMIDSource / properties / value / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / PMIDSource / properties / value / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / PMIDSource / properties / value / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / PMIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMIDSource / properties / value / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
        Added value: +"pmid"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "doi": "#/$defs/DOISource",
        +        "metadata": "#/$defs/InstitutionalMetadataSource",
        +        "pmid": "#/$defs/PMIDSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/PMIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/DOISource"
        +      },
        +      {
        +        "$ref": "#/$defs/InstitutionalMetadataSource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "metadata": "#/$defs/InstitutionalMetadataSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        },
        +        {
        +          "$ref": "#/$defs/InstitutionalMetadataSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "doi": "#/$defs/DOISource",
        +          "metadata": "#/$defs/InstitutionalMetadataSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/DOISource"
        +        },
        +        {
        +          "$ref": "#/$defs/InstitutionalMetadataSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "doi": "#/$defs/DOISource",
        -    "metadata": "#/$defs/InstitutionalMetadataSource",
        -    "pmid": "#/$defs/PMIDSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/PMIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/DOISource"
        -  },
        -  {
        -    "$ref": "#/$defs/InstitutionalMetadataSource"
        -  }
        -]
    • Changedget_pipeline_history4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 5,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedget_text_mined_terms27 fields changed
      • addedInput schema / $defs / PMCIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmcid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][cC][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMCIDSource / properties / kind / const
        Removed value: -"pmcid"
      • removedInput schema / $defs / PMCIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMCIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMCIDSource / properties / value / examples
        Added value: +[
        +  "PMC12345",
        +  "https://pmc.ncbi.nlm.nih.gov/articles/PMC12345/"
        +]
      • addedInput schema / $defs / PMCIDSource / properties / value / format
        Added value: +"pubmed-pmcid"
      • changedInput schema / $defs / PMCIDSource / properties / value / maxLength
        Previous value: -23New value: +512
      • addedInput schema / $defs / PMCIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMCIDSource / properties / value / pattern
        Removed value: -"^PMC[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMCIDSource / properties / value / x-pubmed-input
        Added value: +"pmcid"
      • addedInput schema / $defs / PMIDSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "pmid",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / PMIDSource / properties / kind / const
        Removed value: -"pmid"
      • removedInput schema / $defs / PMIDSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / PMIDSource / properties / value / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / PMIDSource / properties / value / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / PMIDSource / properties / value / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / PMIDSource / properties / value / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / PMIDSource / properties / value / minLength
        Added value: +1
      • removedInput schema / $defs / PMIDSource / properties / value / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / PMIDSource / properties / value / x-pubmed-input
        Added value: +"pmid"
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • changedInput schema / properties / semantic_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "GENE_PROTEIN",
        -      "DISEASE",
        -      "CHEMICAL",
        -      "ORGANISM",
        -      "GO_TERM",
        -      "EFO"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "GENE_PROTEIN",
        +          "DISEASE",
        +          "CHEMICAL",
        +          "ORGANISM",
        +          "GO_TERM",
        +          "EFO"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[gG][eE][nN][eE]_[pP][rR][oO][tT][eE][iI][nN]|[dD][iI][sS][eE][aA][sS][eE]|[cC][hH][eE][mM][iI][cC][aA][lL]|[oO][rR][gG][aA][nN][iI][sS][mM]|[gG][oO]_[tT][eE][rR][mM]|[eE][fF][oO])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "pmcid": "#/$defs/PMCIDSource",
        +        "pmid": "#/$defs/PMIDSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/PMIDSource"
        +      },
        +      {
        +        "$ref": "#/$defs/PMCIDSource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "pmcid": "#/$defs/PMCIDSource",
        +          "pmid": "#/$defs/PMIDSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/PMIDSource"
        +        },
        +        {
        +          "$ref": "#/$defs/PMCIDSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "pmcid": "#/$defs/PMCIDSource",
        -    "pmid": "#/$defs/PMIDSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/PMIDSource"
        -  },
        -  {
        -    "$ref": "#/$defs/PMCIDSource"
        -  }
        -]
    • Changedlist_pipelines3 fields changed
      • addedInput schema / properties / scope / anyOf
        Added value: +[
        +  {
        +    "default": "",
        +    "enum": [
        +      "",
        +      "workspace",
        +      "global"
        +    ],
        +    "title": "Scope",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:|[wW][oO][rR][kK][sS][pP][aA][cC][eE]|[gG][lL][oO][bB][aA][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / scope / enum
        Removed value: -[
        -  "",
        -  "workspace",
        -  "global"
        -]
      • removedInput schema / properties / scope / type
        Removed value: -"string"
    • Changedprepare_export10 fields changed
      • addedInput schema / properties / format / anyOf
        Added value: +[
        +  {
        +    "default": "ris",
        +    "enum": [
        +      "ris",
        +      "medline",
        +      "csl",
        +      "bibtex",
        +      "csv",
        +      "json"
        +    ],
        +    "title": "Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[rR][iI][sS]|[mM][eE][dD][lL][iI][nN][eE]|[cC][sS][lL]|[bB][iI][bB][tT][eE][xX]|[cC][sS][vV]|[jJ][sS][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / format / enum
        Removed value: -[
        -  "ris",
        -  "medline",
        -  "csl",
        -  "bibtex",
        -  "csv",
        -  "json"
        -]
      • removedInput schema / properties / format / type
        Removed value: -"string"
      • addedInput schema / properties / include_abstract / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include Abstract",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_abstract / type
        Removed value: -"boolean"
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "maxLength": 100000,
        -    "minLength": 1,
        -    "type": "string"
        -  },
        -  {
        -    "items": {
        -      "maxLength": 512,
        -      "minLength": 1,
        -      "type": "string"
        -    },
        -    "maxItems": 1000,
        -    "minItems": 1,
        -    "type": "array"
        -  }
        -]New value: +[
        +  {
        +    "description": "Complete PMID(s): delimited text, JSON string array, or Markdown list; optional JSON code fence. last only where supported.",
        +    "examples": [
        +      "33053718,36170657",
        +      "[\"33053718\",\"36170657\"]",
        +      "- 33053718\n- 36170657"
        +    ],
        +    "format": "pubmed-pmid-batch",
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "description": "One PMID string, or last as the sole batch item for tools supporting session reuse.",
        +      "examples": [
        +        "33053718"
        +      ],
        +      "format": "pubmed-pmid",
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string",
        +      "x-pubmed-input": "pmid"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / pmids / x-pubmed-input
        Added value: +"pmid_batch"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "default": "official",
        +    "enum": [
        +      "official",
        +      "local"
        +    ],
        +    "title": "Source",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[oO][fF][fF][iI][cC][iI][aA][lL]|[lL][oO][cC][aA][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / source / enum
        Removed value: -[
        -  "official",
        -  "local"
        -]
      • removedInput schema / properties / source / type
        Removed value: -"string"
    • Changedprepare_figure_search12 fields changed
      • addedInput schema / $defs / InlineImageSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "base64",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[bB][aA][sS][eE]64)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / InlineImageSource / properties / kind / const
        Removed value: -"base64"
      • removedInput schema / $defs / InlineImageSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / URLImageSource / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "url",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[uU][rR][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / URLImageSource / properties / kind / const
        Removed value: -"url"
      • removedInput schema / $defs / URLImageSource / properties / kind / type
        Removed value: -"string"
      • addedInput schema / properties / search_type / anyOf
        Added value: +[
        +  {
        +    "default": "comprehensive",
        +    "enum": [
        +      "comprehensive",
        +      "methodology",
        +      "results",
        +      "structure",
        +      "medical"
        +    ],
        +    "title": "Search Type",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][oO][mM][pP][rR][eE][hH][eE][nN][sS][iI][vV][eE]|[mM][eE][tT][hH][oO][dD][oO][lL][oO][gG][yY]|[rR][eE][sS][uU][lL][tT][sS]|[sS][tT][rR][uU][cC][tT][uU][rR][eE]|[mM][eE][dD][iI][cC][aA][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / search_type / enum
        Removed value: -[
        -  "comprehensive",
        -  "methodology",
        -  "results",
        -  "structure",
        -  "medical"
        -]
      • removedInput schema / properties / search_type / type
        Removed value: -"string"
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "base64": "#/$defs/InlineImageSource",
        +        "url": "#/$defs/URLImageSource"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/InlineImageSource"
        +      },
        +      {
        +        "$ref": "#/$defs/URLImageSource"
        +      }
        +    ],
        +    "title": "Source"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "base64": "#/$defs/InlineImageSource",
        +          "url": "#/$defs/URLImageSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/InlineImageSource"
        +        },
        +        {
        +          "$ref": "#/$defs/URLImageSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "base64": "#/$defs/InlineImageSource",
        +          "url": "#/$defs/URLImageSource"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/InlineImageSource"
        +        },
        +        {
        +          "$ref": "#/$defs/URLImageSource"
        +        }
        +      ],
        +      "title": "Source"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / source / discriminator
        Removed value: -{
        -  "mapping": {
        -    "base64": "#/$defs/InlineImageSource",
        -    "url": "#/$defs/URLImageSource"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / properties / source / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/InlineImageSource"
        -  },
        -  {
        -    "$ref": "#/$defs/URLImageSource"
        -  }
        -]
    • Changedread_research_chronicle58 fields changed
      • addedInput schema / $defs / ChronicleCompareRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "compare",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][oO][mM][pP][aA][rR][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleCompareRequest / properties / action / const
        Removed value: -"compare"
      • removedInput schema / $defs / ChronicleCompareRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleCompareRequest / properties / selection / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "chronicle_ids": "#/$defs/ChronicleIdsSelection",
        +        "topics": "#/$defs/ChronicleTopicsSelection"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/ChronicleTopicsSelection"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleIdsSelection"
        +      }
        +    ],
        +    "title": "Selection"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "chronicle_ids": "#/$defs/ChronicleIdsSelection",
        +          "topics": "#/$defs/ChronicleTopicsSelection"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ChronicleTopicsSelection"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleIdsSelection"
        +        }
        +      ],
        +      "title": "Selection"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "chronicle_ids": "#/$defs/ChronicleIdsSelection",
        +          "topics": "#/$defs/ChronicleTopicsSelection"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ChronicleTopicsSelection"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleIdsSelection"
        +        }
        +      ],
        +      "title": "Selection"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / $defs / ChronicleCompareRequest / properties / selection / discriminator
        Removed value: -{
        -  "mapping": {
        -    "chronicle_ids": "#/$defs/ChronicleIdsSelection",
        -    "topics": "#/$defs/ChronicleTopicsSelection"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / $defs / ChronicleCompareRequest / properties / selection / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/ChronicleTopicsSelection"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleIdsSelection"
        -  }
        -]
      • addedInput schema / $defs / ChronicleDiffRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "diff",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[dD][iI][fF][fF])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleDiffRequest / properties / action / const
        Removed value: -"diff"
      • removedInput schema / $defs / ChronicleDiffRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleDiffRequest / properties / from_revision / anyOf
        Added value: +[
        +  {
        +    "description": "Positive Chronicle revision",
        +    "maximum": 2000000000,
        +    "minimum": 1,
        +    "title": "From Revision",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleDiffRequest / properties / from_revision / maximum
        Removed value: -2000000000
      • removedInput schema / $defs / ChronicleDiffRequest / properties / from_revision / minimum
        Removed value: -1
      • removedInput schema / $defs / ChronicleDiffRequest / properties / from_revision / type
        Removed value: -"integer"
      • changedInput schema / $defs / ChronicleDiffRequest / properties / to_revision / anyOf
        Previous value: -[
        -  {
        -    "description": "Positive Chronicle revision",
        -    "maximum": 2000000000,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Positive Chronicle revision",
        +    "maximum": 2000000000,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / $defs / ChronicleIdsSelection / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "chronicle_ids",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[cC][hH][rR][oO][nN][iI][cC][lL][eE]_[iI][dD][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleIdsSelection / properties / kind / const
        Removed value: -"chronicle_ids"
      • removedInput schema / $defs / ChronicleIdsSelection / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleIdsSelection / properties / values / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "maxLength": 200,
        +      "minLength": 1,
        +      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$",
        +      "type": "string"
        +    },
        +    "maxItems": 5,
        +    "minItems": 2,
        +    "title": "Values",
        +    "type": "array"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "items": {
        +        "maxLength": 200,
        +        "minLength": 1,
        +        "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$",
        +        "type": "string"
        +      },
        +      "maxItems": 5,
        +      "minItems": 2,
        +      "title": "Values",
        +      "type": "array"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "items": {
        +        "maxLength": 200,
        +        "minLength": 1,
        +        "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$",
        +        "type": "string"
        +      },
        +      "maxItems": 5,
        +      "minItems": 2,
        +      "title": "Values",
        +      "type": "array"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / $defs / ChronicleIdsSelection / properties / values / items
        Removed value: -{
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$",
        -  "type": "string"
        -}
      • removedInput schema / $defs / ChronicleIdsSelection / properties / values / maxItems
        Removed value: -5
      • removedInput schema / $defs / ChronicleIdsSelection / properties / values / minItems
        Removed value: -2
      • removedInput schema / $defs / ChronicleIdsSelection / properties / values / type
        Removed value: -"array"
      • addedInput schema / $defs / ChronicleListRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "list",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[lL][iI][sS][tT])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleListRequest / properties / action / const
        Removed value: -"list"
      • removedInput schema / $defs / ChronicleListRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleListRequest / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 20,
        +    "description": "Maximum Chronicle records",
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleListRequest / properties / limit / maximum
        Removed value: -100
      • removedInput schema / $defs / ChronicleListRequest / properties / limit / minimum
        Removed value: -1
      • removedInput schema / $defs / ChronicleListRequest / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / $defs / ChronicleLoadRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "load",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[lL][oO][aA][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleLoadRequest / properties / action / const
        Removed value: -"load"
      • removedInput schema / $defs / ChronicleLoadRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleLoadRequest / properties / output / anyOf
        Added value: +[
        +  {
        +    "default": "summary",
        +    "enum": [
        +      "summary",
        +      "json",
        +      "chronicle_map",
        +      "timeline",
        +      "tree",
        +      "graph",
        +      "evidence",
        +      "milestones",
        +      "mermaid",
        +      "narrative"
        +    ],
        +    "title": "Output",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[sS][uU][mM][mM][aA][rR][yY]|[jJ][sS][oO][nN]|[cC][hH][rR][oO][nN][iI][cC][lL][eE]_[mM][aA][pP]|[tT][iI][mM][eE][lL][iI][nN][eE]|[tT][rR][eE][eE]|[gG][rR][aA][pP][hH]|[eE][vV][iI][dD][eE][nN][cC][eE]|[mM][iI][lL][eE][sS][tT][oO][nN][eE][sS]|[mM][eE][rR][mM][aA][iI][dD]|[nN][aA][rR][rR][aA][tT][iI][vV][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleLoadRequest / properties / output / enum
        Removed value: -[
        -  "summary",
        -  "json",
        -  "chronicle_map",
        -  "timeline",
        -  "tree",
        -  "graph",
        -  "evidence",
        -  "milestones",
        -  "mermaid",
        -  "narrative"
        -]
      • removedInput schema / $defs / ChronicleLoadRequest / properties / output / type
        Removed value: -"string"
      • changedInput schema / $defs / ChronicleLoadRequest / properties / revision / anyOf
        Previous value: -[
        -  {
        -    "description": "Positive Chronicle revision",
        -    "maximum": 2000000000,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Positive Chronicle revision",
        +    "maximum": 2000000000,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / $defs / ChronicleMilestonesRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "milestones",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][iI][lL][eE][sS][tT][oO][nN][eE][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleMilestonesRequest / properties / action / const
        Removed value: -"milestones"
      • removedInput schema / $defs / ChronicleMilestonesRequest / properties / action / type
        Removed value: -"string"
      • changedInput schema / $defs / ChronicleMilestonesRequest / properties / revision / anyOf
        Previous value: -[
        -  {
        -    "description": "Positive Chronicle revision",
        -    "maximum": 2000000000,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Positive Chronicle revision",
        +    "maximum": 2000000000,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / $defs / ChronicleNarrateRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "narrate",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[nN][aA][rR][rR][aA][tT][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleNarrateRequest / properties / action / const
        Removed value: -"narrate"
      • removedInput schema / $defs / ChronicleNarrateRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleNarrateRequest / properties / mode / anyOf
        Added value: +[
        +  {
        +    "default": "brief",
        +    "enum": [
        +      "brief",
        +      "full"
        +    ],
        +    "title": "Mode",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[bB][rR][iI][eE][fF]|[fF][uU][lL][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleNarrateRequest / properties / mode / enum
        Removed value: -[
        -  "brief",
        -  "full"
        -]
      • removedInput schema / $defs / ChronicleNarrateRequest / properties / mode / type
        Removed value: -"string"
      • changedInput schema / $defs / ChronicleNarrateRequest / properties / revision / anyOf
        Previous value: -[
        -  {
        -    "description": "Positive Chronicle revision",
        -    "maximum": 2000000000,
        -    "minimum": 1,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Positive Chronicle revision",
        +    "maximum": 2000000000,
        +    "minimum": 1,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • addedInput schema / $defs / ChronicleTopicsSelection / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "topics",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][oO][pP][iI][cC][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / kind / const
        Removed value: -"topics"
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / ChronicleTopicsSelection / properties / values / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "maxLength": 500,
        +      "minLength": 1,
        +      "pattern": ".*\\S.*",
        +      "type": "string"
        +    },
        +    "maxItems": 5,
        +    "minItems": 2,
        +    "title": "Values",
        +    "type": "array"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "items": {
        +        "maxLength": 500,
        +        "minLength": 1,
        +        "pattern": ".*\\S.*",
        +        "type": "string"
        +      },
        +      "maxItems": 5,
        +      "minItems": 2,
        +      "title": "Values",
        +      "type": "array"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "items": {
        +        "maxLength": 500,
        +        "minLength": 1,
        +        "pattern": ".*\\S.*",
        +        "type": "string"
        +      },
        +      "maxItems": 5,
        +      "minItems": 2,
        +      "title": "Values",
        +      "type": "array"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / values / items
        Removed value: -{
        -  "maxLength": 500,
        -  "minLength": 1,
        -  "pattern": ".*\\S.*",
        -  "type": "string"
        -}
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / values / maxItems
        Removed value: -5
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / values / minItems
        Removed value: -2
      • removedInput schema / $defs / ChronicleTopicsSelection / properties / values / type
        Removed value: -"array"
      • addedInput schema / properties / request / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "compare": "#/$defs/ChronicleCompareRequest",
        +        "diff": "#/$defs/ChronicleDiffRequest",
        +        "list": "#/$defs/ChronicleListRequest",
        +        "load": "#/$defs/ChronicleLoadRequest",
        +        "milestones": "#/$defs/ChronicleMilestonesRequest",
        +        "narrate": "#/$defs/ChronicleNarrateRequest"
        +      },
        +      "propertyName": "action"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/ChronicleLoadRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleListRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleDiffRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleNarrateRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleMilestonesRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/ChronicleCompareRequest"
        +      }
        +    ],
        +    "title": "Request"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "compare": "#/$defs/ChronicleCompareRequest",
        +          "diff": "#/$defs/ChronicleDiffRequest",
        +          "list": "#/$defs/ChronicleListRequest",
        +          "load": "#/$defs/ChronicleLoadRequest",
        +          "milestones": "#/$defs/ChronicleMilestonesRequest",
        +          "narrate": "#/$defs/ChronicleNarrateRequest"
        +        },
        +        "propertyName": "action"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ChronicleLoadRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleListRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleDiffRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleNarrateRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleMilestonesRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleCompareRequest"
        +        }
        +      ],
        +      "title": "Request"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "compare": "#/$defs/ChronicleCompareRequest",
        +          "diff": "#/$defs/ChronicleDiffRequest",
        +          "list": "#/$defs/ChronicleListRequest",
        +          "load": "#/$defs/ChronicleLoadRequest",
        +          "milestones": "#/$defs/ChronicleMilestonesRequest",
        +          "narrate": "#/$defs/ChronicleNarrateRequest"
        +        },
        +        "propertyName": "action"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ChronicleLoadRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleListRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleDiffRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleNarrateRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleMilestonesRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/ChronicleCompareRequest"
        +        }
        +      ],
        +      "title": "Request"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / request / discriminator
        Removed value: -{
        -  "mapping": {
        -    "compare": "#/$defs/ChronicleCompareRequest",
        -    "diff": "#/$defs/ChronicleDiffRequest",
        -    "list": "#/$defs/ChronicleListRequest",
        -    "load": "#/$defs/ChronicleLoadRequest",
        -    "milestones": "#/$defs/ChronicleMilestonesRequest",
        -    "narrate": "#/$defs/ChronicleNarrateRequest"
        -  },
        -  "propertyName": "action"
        -}
      • removedInput schema / properties / request / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/ChronicleLoadRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleListRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleDiffRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleNarrateRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleMilestonesRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/ChronicleCompareRequest"
        -  }
        -]
    • Changedread_session87 fields changed
      • addedInput schema / $defs / ArtifactIdLocator / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "artifact_id",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[aA][rR][tT][iI][fF][aA][cC][tT]_[iI][dD])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ArtifactIdLocator / properties / kind / const
        Removed value: -"artifact_id"
      • removedInput schema / $defs / ArtifactIdLocator / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / ArtifactUriLocator / properties / kind / anyOf
        Added value: +[
        +  {
        +    "const": "artifact_uri",
        +    "title": "Kind",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[aA][rR][tT][iI][fF][aA][cC][tT]_[uU][rR][iI])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / ArtifactUriLocator / properties / kind / const
        Removed value: -"artifact_uri"
      • removedInput schema / $defs / ArtifactUriLocator / properties / kind / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionArticleRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "article",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[aA][rR][tT][iI][cC][lL][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionArticleRequest / properties / action / const
        Removed value: -"article"
      • removedInput schema / $defs / SessionArticleRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionArticleRequest / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / $defs / SessionArticleRequest / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / $defs / SessionArticleRequest / properties / pmid / format
        Added value: +"pubmed-pmid"
      • changedInput schema / $defs / SessionArticleRequest / properties / pmid / maxLength
        Previous value: -20New value: +512
      • addedInput schema / $defs / SessionArticleRequest / properties / pmid / minLength
        Added value: +1
      • removedInput schema / $defs / SessionArticleRequest / properties / pmid / pattern
        Removed value: -"^[1-9][0-9]{0,19}$"
      • addedInput schema / $defs / SessionArticleRequest / properties / pmid / x-pubmed-input
        Added value: +"pmid"
      • addedInput schema / $defs / SessionArtifactRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "artifact",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[aA][rR][tT][iI][fF][aA][cC][tT])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionArtifactRequest / properties / action / const
        Removed value: -"artifact"
      • removedInput schema / $defs / SessionArtifactRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionArtifactRequest / properties / include_local_paths / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include Local Paths",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionArtifactRequest / properties / include_local_paths / type
        Removed value: -"boolean"
      • addedInput schema / $defs / SessionArtifactRequest / properties / locator / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "artifact_id": "#/$defs/ArtifactIdLocator",
        +        "artifact_uri": "#/$defs/ArtifactUriLocator"
        +      },
        +      "propertyName": "kind"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/ArtifactIdLocator"
        +      },
        +      {
        +        "$ref": "#/$defs/ArtifactUriLocator"
        +      }
        +    ],
        +    "title": "Locator"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "artifact_id": "#/$defs/ArtifactIdLocator",
        +          "artifact_uri": "#/$defs/ArtifactUriLocator"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ArtifactIdLocator"
        +        },
        +        {
        +          "$ref": "#/$defs/ArtifactUriLocator"
        +        }
        +      ],
        +      "title": "Locator"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "artifact_id": "#/$defs/ArtifactIdLocator",
        +          "artifact_uri": "#/$defs/ArtifactUriLocator"
        +        },
        +        "propertyName": "kind"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/ArtifactIdLocator"
        +        },
        +        {
        +          "$ref": "#/$defs/ArtifactUriLocator"
        +        }
        +      ],
        +      "title": "Locator"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / $defs / SessionArtifactRequest / properties / locator / discriminator
        Removed value: -{
        -  "mapping": {
        -    "artifact_id": "#/$defs/ArtifactIdLocator",
        -    "artifact_uri": "#/$defs/ArtifactUriLocator"
        -  },
        -  "propertyName": "kind"
        -}
      • removedInput schema / $defs / SessionArtifactRequest / properties / locator / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/ArtifactIdLocator"
        -  },
        -  {
        -    "$ref": "#/$defs/ArtifactUriLocator"
        -  }
        -]
      • addedInput schema / $defs / SessionArtifactRequest / properties / max_chars / anyOf
        Added value: +[
        +  {
        +    "default": 200000,
        +    "maximum": 200000,
        +    "minimum": 1,
        +    "title": "Max Chars",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionArtifactRequest / properties / max_chars / maximum
        Removed value: -200000
      • removedInput schema / $defs / SessionArtifactRequest / properties / max_chars / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionArtifactRequest / properties / max_chars / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionArtifactRequest / properties / offset / anyOf
        Added value: +[
        +  {
        +    "default": 0,
        +    "maximum": 2000000000,
        +    "minimum": 0,
        +    "title": "Offset",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionArtifactRequest / properties / offset / maximum
        Removed value: -2000000000
      • removedInput schema / $defs / SessionArtifactRequest / properties / offset / minimum
        Removed value: -0
      • removedInput schema / $defs / SessionArtifactRequest / properties / offset / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionListArtifactsRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "list_artifacts",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[lL][iI][sS][tT]_[aA][rR][tT][iI][fF][aA][cC][tT][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / action / const
        Removed value: -"list_artifacts"
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionListArtifactsRequest / properties / include_local_paths / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include Local Paths",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / include_local_paths / type
        Removed value: -"boolean"
      • addedInput schema / $defs / SessionListArtifactsRequest / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / limit / maximum
        Removed value: -100
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / limit / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionListArtifactsRequest / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionLogRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "log",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[lL][oO][gG])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionLogRequest / properties / action / const
        Removed value: -"log"
      • removedInput schema / $defs / SessionLogRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionLogRequest / properties / event_limit / anyOf
        Added value: +[
        +  {
        +    "default": 50,
        +    "maximum": 500,
        +    "minimum": 1,
        +    "title": "Event Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionLogRequest / properties / event_limit / maximum
        Removed value: -500
      • removedInput schema / $defs / SessionLogRequest / properties / event_limit / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionLogRequest / properties / event_limit / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionLogRequest / properties / history_limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "History Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionLogRequest / properties / history_limit / maximum
        Removed value: -100
      • removedInput schema / $defs / SessionLogRequest / properties / history_limit / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionLogRequest / properties / history_limit / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionLogRequest / properties / include_history / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include History",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionLogRequest / properties / include_history / type
        Removed value: -"boolean"
      • addedInput schema / $defs / SessionPmidsRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "pmids",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][iI][dD][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionPmidsRequest / properties / action / const
        Removed value: -"pmids"
      • removedInput schema / $defs / SessionPmidsRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionPmidsRequest / properties / search_index / anyOf
        Added value: +[
        +  {
        +    "default": -1,
        +    "maximum": 100000,
        +    "minimum": -100000,
        +    "title": "Search Index",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionPmidsRequest / properties / search_index / maximum
        Removed value: -100000
      • removedInput schema / $defs / SessionPmidsRequest / properties / search_index / minimum
        Removed value: --100000
      • removedInput schema / $defs / SessionPmidsRequest / properties / search_index / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionReplaySearchRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "replay_search",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[rR][eE][pP][lL][aA][yY]_[sS][eE][aA][rR][cC][hH])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionReplaySearchRequest / properties / action / const
        Removed value: -"replay_search"
      • removedInput schema / $defs / SessionReplaySearchRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionSearchRunRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "search_run",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[sS][eE][aA][rR][cC][hH]_[rR][uU][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSearchRunRequest / properties / action / const
        Removed value: -"search_run"
      • removedInput schema / $defs / SessionSearchRunRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionSearchRunsRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "search_runs",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[sS][eE][aA][rR][cC][hH]_[rR][uU][nN][sS])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSearchRunsRequest / properties / action / const
        Removed value: -"search_runs"
      • removedInput schema / $defs / SessionSearchRunsRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionSearchRunsRequest / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSearchRunsRequest / properties / limit / maximum
        Removed value: -100
      • removedInput schema / $defs / SessionSearchRunsRequest / properties / limit / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionSearchRunsRequest / properties / limit / type
        Removed value: -"integer"
      • changedInput schema / $defs / SessionSearchRunsRequest / properties / status / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "started",
        -      "planned",
        -      "running",
        -      "completed",
        -      "partial",
        -      "failed",
        -      "cancelled",
        -      "interrupted"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "started",
        +          "planned",
        +          "running",
        +          "completed",
        +          "partial",
        +          "failed",
        +          "cancelled",
        +          "interrupted"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[sS][tT][aA][rR][tT][eE][dD]|[pP][lL][aA][nN][nN][eE][dD]|[rR][uU][nN][nN][iI][nN][gG]|[cC][oO][mM][pP][lL][eE][tT][eE][dD]|[pP][aA][rR][tT][iI][aA][lL]|[fF][aA][iI][lL][eE][dD]|[cC][aA][nN][cC][eE][lL][lL][eE][dD]|[iI][nN][tT][eE][rR][rR][uU][pP][tT][eE][dD])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / $defs / SessionSummaryRequest / properties / action / anyOf
        Added value: +[
        +  {
        +    "const": "summary",
        +    "title": "Action",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[sS][uU][mM][mM][aA][rR][yY])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSummaryRequest / properties / action / const
        Removed value: -"summary"
      • removedInput schema / $defs / SessionSummaryRequest / properties / action / type
        Removed value: -"string"
      • addedInput schema / $defs / SessionSummaryRequest / properties / history_limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "History Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSummaryRequest / properties / history_limit / maximum
        Removed value: -100
      • removedInput schema / $defs / SessionSummaryRequest / properties / history_limit / minimum
        Removed value: -1
      • removedInput schema / $defs / SessionSummaryRequest / properties / history_limit / type
        Removed value: -"integer"
      • addedInput schema / $defs / SessionSummaryRequest / properties / include_history / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Include History",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / $defs / SessionSummaryRequest / properties / include_history / type
        Removed value: -"boolean"
      • addedInput schema / properties / request / anyOf
        Added value: +[
        +  {
        +    "discriminator": {
        +      "mapping": {
        +        "article": "#/$defs/SessionArticleRequest",
        +        "artifact": "#/$defs/SessionArtifactRequest",
        +        "list_artifacts": "#/$defs/SessionListArtifactsRequest",
        +        "log": "#/$defs/SessionLogRequest",
        +        "pmids": "#/$defs/SessionPmidsRequest",
        +        "replay_search": "#/$defs/SessionReplaySearchRequest",
        +        "search_run": "#/$defs/SessionSearchRunRequest",
        +        "search_runs": "#/$defs/SessionSearchRunsRequest",
        +        "summary": "#/$defs/SessionSummaryRequest"
        +      },
        +      "propertyName": "action"
        +    },
        +    "oneOf": [
        +      {
        +        "$ref": "#/$defs/SessionPmidsRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionArticleRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionSummaryRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionLogRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionListArtifactsRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionArtifactRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionSearchRunsRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionSearchRunRequest"
        +      },
        +      {
        +        "$ref": "#/$defs/SessionReplaySearchRequest"
        +      }
        +    ],
        +    "title": "Request"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "article": "#/$defs/SessionArticleRequest",
        +          "artifact": "#/$defs/SessionArtifactRequest",
        +          "list_artifacts": "#/$defs/SessionListArtifactsRequest",
        +          "log": "#/$defs/SessionLogRequest",
        +          "pmids": "#/$defs/SessionPmidsRequest",
        +          "replay_search": "#/$defs/SessionReplaySearchRequest",
        +          "search_run": "#/$defs/SessionSearchRunRequest",
        +          "search_runs": "#/$defs/SessionSearchRunsRequest",
        +          "summary": "#/$defs/SessionSummaryRequest"
        +        },
        +        "propertyName": "action"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/SessionPmidsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionArticleRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSummaryRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionLogRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionListArtifactsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionArtifactRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSearchRunsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSearchRunRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionReplaySearchRequest"
        +        }
        +      ],
        +      "title": "Request"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "discriminator": {
        +        "mapping": {
        +          "article": "#/$defs/SessionArticleRequest",
        +          "artifact": "#/$defs/SessionArtifactRequest",
        +          "list_artifacts": "#/$defs/SessionListArtifactsRequest",
        +          "log": "#/$defs/SessionLogRequest",
        +          "pmids": "#/$defs/SessionPmidsRequest",
        +          "replay_search": "#/$defs/SessionReplaySearchRequest",
        +          "search_run": "#/$defs/SessionSearchRunRequest",
        +          "search_runs": "#/$defs/SessionSearchRunsRequest",
        +          "summary": "#/$defs/SessionSummaryRequest"
        +        },
        +        "propertyName": "action"
        +      },
        +      "oneOf": [
        +        {
        +          "$ref": "#/$defs/SessionPmidsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionArticleRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSummaryRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionLogRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionListArtifactsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionArtifactRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSearchRunsRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionSearchRunRequest"
        +        },
        +        {
        +          "$ref": "#/$defs/SessionReplaySearchRequest"
        +        }
        +      ],
        +      "title": "Request"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
      • removedInput schema / properties / request / discriminator
        Removed value: -{
        -  "mapping": {
        -    "article": "#/$defs/SessionArticleRequest",
        -    "artifact": "#/$defs/SessionArtifactRequest",
        -    "list_artifacts": "#/$defs/SessionListArtifactsRequest",
        -    "log": "#/$defs/SessionLogRequest",
        -    "pmids": "#/$defs/SessionPmidsRequest",
        -    "replay_search": "#/$defs/SessionReplaySearchRequest",
        -    "search_run": "#/$defs/SessionSearchRunRequest",
        -    "search_runs": "#/$defs/SessionSearchRunsRequest",
        -    "summary": "#/$defs/SessionSummaryRequest"
        -  },
        -  "propertyName": "action"
        -}
      • removedInput schema / properties / request / oneOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/SessionPmidsRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionArticleRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionSummaryRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionLogRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionListArtifactsRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionArtifactRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionSearchRunsRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionSearchRunRequest"
        -  },
        -  {
        -    "$ref": "#/$defs/SessionReplaySearchRequest"
        -  }
        -]
    • Changedsave_literature_notes13 fields changed
      • addedInput schema / properties / create_index / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Create Index",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / create_index / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_abstract / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include Abstract",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_abstract / type
        Removed value: -"boolean"
      • addedInput schema / properties / include_csl_json / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Include Csl Json",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / include_csl_json / type
        Removed value: -"boolean"
      • addedInput schema / properties / note_format / anyOf
        Added value: +[
        +  {
        +    "default": "wiki",
        +    "enum": [
        +      "wiki",
        +      "foam",
        +      "markdown",
        +      "medpaper"
        +    ],
        +    "title": "Note Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[wW][iI][kK][iI]|[fF][oO][aA][mM]|[mM][aA][rR][kK][dD][oO][wW][nN]|[mM][eE][dD][pP][aA][pP][eE][rR])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / note_format / enum
        Removed value: -[
        -  "wiki",
        -  "foam",
        -  "markdown",
        -  "medpaper"
        -]
      • removedInput schema / properties / note_format / type
        Removed value: -"string"
      • addedInput schema / properties / overwrite / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Overwrite",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / overwrite / type
        Removed value: -"boolean"
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "maxLength": 100000,
        -    "minLength": 1,
        -    "type": "string"
        -  },
        -  {
        -    "items": {
        -      "maxLength": 512,
        -      "minLength": 1,
        -      "type": "string"
        -    },
        -    "maxItems": 1000,
        -    "minItems": 1,
        -    "type": "array"
        -  }
        -]New value: +[
        +  {
        +    "description": "Complete PMID(s): delimited text, JSON string array, or Markdown list; optional JSON code fence. last only where supported.",
        +    "examples": [
        +      "33053718,36170657",
        +      "[\"33053718\",\"36170657\"]",
        +      "- 33053718\n- 36170657"
        +    ],
        +    "format": "pubmed-pmid-batch",
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "description": "One PMID string, or last as the sole batch item for tools supporting session reuse.",
        +      "examples": [
        +        "33053718"
        +      ],
        +      "format": "pubmed-pmid",
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string",
        +      "x-pubmed-input": "pmid"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / pmids / x-pubmed-input
        Added value: +"pmid_batch"
    • Changedsave_pipeline4 fields changed
      • addedInput schema / properties / scope / anyOf
        Added value: +[
        +  {
        +    "default": "auto",
        +    "enum": [
        +      "auto",
        +      "workspace",
        +      "global"
        +    ],
        +    "title": "Scope",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[aA][uU][tT][oO]|[wW][oO][rR][kK][sS][pP][aA][cC][eE]|[gG][lL][oO][bB][aA][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / scope / enum
        Removed value: -[
        -  "auto",
        -  "workspace",
        -  "global"
        -]
      • removedInput schema / properties / scope / type
        Removed value: -"string"
      • changedInput schema / properties / tags / anyOf
        Previous value: -[
        -  {
        -    "items": {
        -      "maxLength": 64,
        -      "minLength": 1,
        -      "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,63})$",
        -      "type": "string"
        -    },
        -    "maxItems": 20,
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "items": {
        +      "maxLength": 64,
        +      "minLength": 1,
        +      "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,63})$",
        +      "type": "string"
        +    },
        +    "maxItems": 20,
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "maxLength": 64,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,63})$",
        +            "type": "string"
        +          },
        +          "maxItems": 20,
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Tags"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "maxLength": 64,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,63})$",
        +            "type": "string"
        +          },
        +          "maxItems": 20,
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Tags"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
    • Changedschedule_pipeline4 fields changed
      • addedInput schema / properties / diff_mode / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Diff Mode",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / diff_mode / type
        Removed value: -"boolean"
      • addedInput schema / properties / notify / anyOf
        Added value: +[
        +  {
        +    "default": true,
        +    "title": "Notify",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / notify / type
        Removed value: -"boolean"
    • Changedsearch_biomedical_images15 fields changed
      • changedInput schema / properties / article_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "ab",
        -      "bk",
        -      "bf",
        -      "cr",
        -      "dp",
        -      "di",
        -      "ed",
        -      "ib",
        -      "in",
        -      "lt",
        -      "mr",
        -      "ma",
        -      "ne",
        -      "ob",
        -      "pr",
        -      "or",
        -      "re",
        -      "ra",
        -      "rw",
        -      "sr",
        -      "rr",
        -      "os",
        -      "hs",
        -      "ot"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "ab",
        +          "bk",
        +          "bf",
        +          "cr",
        +          "dp",
        +          "di",
        +          "ed",
        +          "ib",
        +          "in",
        +          "lt",
        +          "mr",
        +          "ma",
        +          "ne",
        +          "ob",
        +          "pr",
        +          "or",
        +          "re",
        +          "ra",
        +          "rw",
        +          "sr",
        +          "rr",
        +          "os",
        +          "hs",
        +          "ot"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[aA][bB]|[bB][kK]|[bB][fF]|[cC][rR]|[dD][pP]|[dD][iI]|[eE][dD]|[iI][bB]|[iI][nN]|[lL][tT]|[mM][rR]|[mM][aA]|[nN][eE]|[oO][bB]|[pP][rR]|[oO][rR]|[rR][eE]|[rR][aA]|[rR][wW]|[sS][rR]|[rR][rR]|[oO][sS]|[hH][sS]|[oO][tT])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / collection / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "pmc",
        -      "cxr",
        -      "usc",
        -      "hmd",
        -      "mpx"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "pmc",
        +          "cxr",
        +          "usc",
        +          "hmd",
        +          "mpx"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[pP][mM][cC]|[cC][xX][rR]|[uU][sS][cC]|[hH][mM][dD]|[mM][pP][xX])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / hmp_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "ad",
        -      "ar",
        -      "at",
        -      "bi",
        -      "br",
        -      "cr",
        -      "ca",
        -      "ch",
        -      "cg",
        -      "cd",
        -      "dr",
        -      "ep",
        -      "ex",
        -      "hr",
        -      "hu",
        -      "lt",
        -      "mp",
        -      "nw",
        -      "pn",
        -      "ph",
        -      "pi",
        -      "po",
        -      "pt",
        -      "pc",
        -      "ps"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "ad",
        +          "ar",
        +          "at",
        +          "bi",
        +          "br",
        +          "cr",
        +          "ca",
        +          "ch",
        +          "cg",
        +          "cd",
        +          "dr",
        +          "ep",
        +          "ex",
        +          "hr",
        +          "hu",
        +          "lt",
        +          "mp",
        +          "nw",
        +          "pn",
        +          "ph",
        +          "pi",
        +          "po",
        +          "pt",
        +          "pc",
        +          "ps"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[aA][dD]|[aA][rR]|[aA][tT]|[bB][iI]|[bB][rR]|[cC][rR]|[cC][aA]|[cC][hH]|[cC][gG]|[cC][dD]|[dD][rR]|[eE][pP]|[eE][xX]|[hH][rR]|[hH][uU]|[lL][tT]|[mM][pP]|[nN][wW]|[pP][nN]|[pP][hH]|[pP][iI]|[pP][oO]|[pP][tT]|[pP][cC]|[pP][sS])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / image_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "xg",
        -      "xm",
        -      "x",
        -      "u",
        -      "ph",
        -      "p",
        -      "mc",
        -      "m",
        -      "g",
        -      "c"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "xg",
        +          "xm",
        +          "x",
        +          "u",
        +          "ph",
        +          "p",
        +          "mc",
        +          "m",
        +          "g",
        +          "c"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[xX][gG]|[xX][mM]|[xX]|[uU]|[pP][hH]|[pP]|[mM][cC]|[mM]|[gG]|[cC])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / license_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "by",
        -      "bync",
        -      "byncnd",
        -      "byncsa"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "by",
        +          "bync",
        +          "byncnd",
        +          "byncsa"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[bB][yY]|[bB][yY][nN][cC]|[bB][yY][nN][cC][nN][dD]|[bB][yY][nN][cC][sS][aA])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 50,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -50
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • changedInput schema / properties / search_fields / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "t",
        -      "m",
        -      "ab",
        -      "msh",
        -      "c",
        -      "a"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "t",
        +          "m",
        +          "ab",
        +          "msh",
        +          "c",
        +          "a"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[tT]|[mM]|[aA][bB]|[mM][sS][hH]|[cC]|[aA])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / sort_by / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "r",
        -      "o",
        -      "d",
        -      "e",
        -      "g",
        -      "oc",
        -      "pr",
        -      "pg",
        -      "t"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "r",
        +          "o",
        +          "d",
        +          "e",
        +          "g",
        +          "oc",
        +          "pr",
        +          "pg",
        +          "t"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[rR]|[oO]|[dD]|[eE]|[gG]|[oO][cC]|[pP][rR]|[pP][gG]|[tT])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / specialty / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "b",
        -      "bc",
        -      "c",
        -      "ca",
        -      "cc",
        -      "d",
        -      "de",
        -      "dt",
        -      "e",
        -      "en",
        -      "f",
        -      "eh",
        -      "g",
        -      "ge",
        -      "gr",
        -      "gy",
        -      "h",
        -      "i",
        -      "id",
        -      "im",
        -      "n",
        -      "ne",
        -      "nu",
        -      "o",
        -      "or",
        -      "ot",
        -      "p",
        -      "py",
        -      "pu",
        -      "r",
        -      "s",
        -      "t",
        -      "u",
        -      "v",
        -      "vi"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "b",
        +          "bc",
        +          "c",
        +          "ca",
        +          "cc",
        +          "d",
        +          "de",
        +          "dt",
        +          "e",
        +          "en",
        +          "f",
        +          "eh",
        +          "g",
        +          "ge",
        +          "gr",
        +          "gy",
        +          "h",
        +          "i",
        +          "id",
        +          "im",
        +          "n",
        +          "ne",
        +          "nu",
        +          "o",
        +          "or",
        +          "ot",
        +          "p",
        +          "py",
        +          "pu",
        +          "r",
        +          "s",
        +          "t",
        +          "u",
        +          "v",
        +          "vi"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[bB]|[bB][cC]|[cC]|[cC][aA]|[cC][cC]|[dD]|[dD][eE]|[dD][tT]|[eE]|[eE][nN]|[fF]|[eE][hH]|[gG]|[gG][eE]|[gG][rR]|[gG][yY]|[hH]|[iI]|[iI][dD]|[iI][mM]|[nN]|[nN][eE]|[nN][uU]|[oO]|[oO][rR]|[oO][tT]|[pP]|[pP][yY]|[pP][uU]|[rR]|[sS]|[tT]|[uU]|[vV]|[vV][iI])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / subset / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "b",
        -      "c",
        -      "e",
        -      "s",
        -      "x"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "b",
        +          "c",
        +          "e",
        +          "s",
        +          "x"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[bB]|[cC]|[eE]|[sS]|[xX])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / video_only / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Video Only",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / video_only / type
        Removed value: -"boolean"
    • Changedsearch_clinvar4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 50,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -50
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedsearch_compound4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 50,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -50
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedsearch_gene4 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 50,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -50
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
    • Changedtest_institutional_access5 fields changed
      • addedInput schema / properties / pmid / description
        Added value: +"Complete identifier string; optional identifier prefix, official article URL, or inline backticks. No numbers, foreign hosts, URL queries/fragments or partial identifiers."
      • addedInput schema / properties / pmid / examples
        Added value: +[
        +  "33053718",
        +  "PMID:33053718",
        +  "https://pubmed.ncbi.nlm.nih.gov/33053718/"
        +]
      • addedInput schema / properties / pmid / format
        Added value: +"pubmed-pmid"
      • changedInput schema / properties / pmid / maxLength
        Previous value: -32New value: +512
      • addedInput schema / properties / pmid / x-pubmed-input
        Added value: +"pmid"
    • Changedunified_search13 fields changed
      • addedInput schema / properties / dry_run / anyOf
        Added value: +[
        +  {
        +    "default": false,
        +    "title": "Dry Run",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "Explicit true/false text, ignoring ASCII case and surrounding whitespace.",
        +    "pattern": "^[ \\t\\r\\n]*(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / dry_run / type
        Removed value: -"boolean"
      • addedInput schema / properties / fulltext
        Added value: +{
        +  "anyOf": [
        +    {
        +      "default": "off",
        +      "enum": [
        +        "off",
        +        "prefetch"
        +      ],
        +      "title": "Fulltext",
        +      "type": "string"
        +    },
        +    {
        +      "pattern": "^[ \\t\\r\\n]*(?:[oO][fF][fF]|[pP][rR][eE][fF][eE][tT][cC][hH])[ \\t\\r\\n]*$",
        +      "type": "string"
        +    }
        +  ],
        +  "default": "off",
        +  "title": "Fulltext"
        +}
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 10,
        +    "maximum": 100,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -100
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / properties / output_format / anyOf
        Added value: +[
        +  {
        +    "default": "markdown",
        +    "enum": [
        +      "markdown",
        +      "json",
        +      "toon"
        +    ],
        +    "title": "Output Format",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[mM][aA][rR][kK][dD][oO][wW][nN]|[jJ][sS][oO][nN]|[tT][oO][oO][nN])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / output_format / enum
        Removed value: -[
        -  "markdown",
        -  "json",
        -  "toon"
        -]
      • removedInput schema / properties / output_format / type
        Removed value: -"string"
      • addedInput schema / properties / ranking / anyOf
        Added value: +[
        +  {
        +    "default": "balanced",
        +    "enum": [
        +      "balanced",
        +      "impact",
        +      "recency",
        +      "quality"
        +    ],
        +    "title": "Ranking",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[bB][aA][lL][aA][nN][cC][eE][dD]|[iI][mM][pP][aA][cC][tT]|[rR][eE][cC][eE][nN][cC][yY]|[qQ][uU][aA][lL][iI][tT][yY])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / ranking / enum
        Removed value: -[
        -  "balanced",
        -  "impact",
        -  "recency",
        -  "quality"
        -]
      • removedInput schema / properties / ranking / type
        Removed value: -"string"
    • Changedvalidate_pico_plan9 fields changed
      • addedInput schema / properties / limit / anyOf
        Added value: +[
        +  {
        +    "default": 20,
        +    "maximum": 33,
        +    "minimum": 1,
        +    "title": "Limit",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / limit / maximum
        Removed value: -33
      • removedInput schema / properties / limit / minimum
        Removed value: -1
      • removedInput schema / properties / limit / type
        Removed value: -"integer"
      • addedInput schema / properties / profile / anyOf
        Added value: +[
        +  {
        +    "default": "balanced",
        +    "enum": [
        +      "precision",
        +      "balanced",
        +      "recall"
        +    ],
        +    "title": "Profile",
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^[ \\t\\r\\n]*(?:[pP][rR][eE][cC][iI][sS][iI][oO][nN]|[bB][aA][lL][aA][nN][cC][eE][dD]|[rR][eE][cC][aA][lL][lL])[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / profile / enum
        Removed value: -[
        -  "precision",
        -  "balanced",
        -  "recall"
        -]
      • removedInput schema / properties / profile / type
        Removed value: -"string"
      • changedInput schema / properties / question_type / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "therapy",
        -      "diagnosis",
        -      "prognosis",
        -      "etiology"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "therapy",
        +          "diagnosis",
        +          "prognosis",
        +          "etiology"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "pattern": "^[ \\t\\r\\n]*(?:[tT][hH][eE][rR][aA][pP][yY]|[dD][iI][aA][gG][nN][oO][sS][iI][sS]|[pP][rR][oO][gG][nN][oO][sS][iI][sS]|[eE][tT][iI][oO][lL][oO][gG][yY])[ \\t\\r\\n]*$",
        +        "type": "string"
        +      }
        +    ]
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / sources / anyOf
        Previous value: -[
        -  {
        -    "items": {
        -      "enum": [
        -        "pubmed",
        -        "europe_pmc",
        -        "openalex",
        -        "semantic_scholar",
        -        "core"
        -      ],
        -      "type": "string"
        -    },
        -    "maxItems": 5,
        -    "minItems": 1,
        -    "type": "array"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "items": {
        +      "anyOf": [
        +        {
        +          "enum": [
        +            "pubmed",
        +            "europe_pmc",
        +            "openalex",
        +            "semantic_scholar",
        +            "core"
        +          ],
        +          "type": "string"
        +        },
        +        {
        +          "pattern": "^[ \\t\\r\\n]*(?:[pP][uU][bB][mM][eE][dD]|[eE][uU][rR][oO][pP][eE]_[pP][mM][cC]|[oO][pP][eE][nN][aA][lL][eE][xX]|[sS][eE][mM][aA][nN][tT][iI][cC]_[sS][cC][hH][oO][lL][aA][rR]|[cC][oO][rR][eE])[ \\t\\r\\n]*$",
        +          "type": "string"
        +        }
        +      ]
        +    },
        +    "maxItems": 5,
        +    "minItems": 1,
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  },
        +  {
        +    "contentMediaType": "application/json",
        +    "contentSchema": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "pubmed",
        +                  "europe_pmc",
        +                  "openalex",
        +                  "semantic_scholar",
        +                  "core"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "pattern": "^[ \\t\\r\\n]*(?:[pP][uU][bB][mM][eE][dD]|[eE][uU][rR][oO][pP][eE]_[pP][mM][cC]|[oO][pP][eE][nN][aA][lL][eE][xX]|[sS][eE][mM][aA][nN][tT][iI][cC]_[sS][cC][hH][oO][lL][aA][rR]|[cC][oO][rR][eE])[ \\t\\r\\n]*$",
        +                "type": "string"
        +              }
        +            ]
        +          },
        +          "maxItems": 5,
        +          "minItems": 1,
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Sources"
        +    },
        +    "description": "One JSON-encoded container; the decoded value must satisfy contentSchema.",
        +    "maxLength": 1000000,
        +    "type": "string"
        +  },
        +  {
        +    "description": "One JSON code fence; after removing the fence, decode JSON and validate against x-pubmed-decodedSchema.",
        +    "maxLength": 1000000,
        +    "pattern": "^\\s*```(?:[jJ][sS][oO][nN])?[ \\t]*\\r?\\n[\\s\\S]*\\r?\\n```\\s*$",
        +    "type": "string",
        +    "x-pubmed-decodedSchema": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "pubmed",
        +                  "europe_pmc",
        +                  "openalex",
        +                  "semantic_scholar",
        +                  "core"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "pattern": "^[ \\t\\r\\n]*(?:[pP][uU][bB][mM][eE][dD]|[eE][uU][rR][oO][pP][eE]_[pP][mM][cC]|[oO][pP][eE][nN][aA][lL][eE][xX]|[sS][eE][mM][aA][nN][tT][iI][cC]_[sS][cC][hH][oO][lL][aA][rR]|[cC][oO][rR][eE])[ \\t\\r\\n]*$",
        +                "type": "string"
        +              }
        +            ]
        +          },
        +          "maxItems": 5,
        +          "minItems": 1,
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Sources"
        +    },
        +    "x-pubmed-encoding": "fenced-json"
        +  }
        +]
    • Changedverify_reference_list4 fields changed
      • addedInput schema / properties / max_references / anyOf
        Added value: +[
        +  {
        +    "default": 100,
        +    "maximum": 200,
        +    "minimum": 1,
        +    "title": "Max References",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "ASCII decimal integer; the integer branch's bounds apply after conversion.",
        +    "maxLength": 32,
        +    "pattern": "^[ \\t\\r\\n]*-?(?:0|[1-9][0-9]*)[ \\t\\r\\n]*$",
        +    "type": "string"
        +  }
        +]
      • removedInput schema / properties / max_references / maximum
        Removed value: -200
      • removedInput schema / properties / max_references / minimum
        Removed value: -1
      • removedInput schema / properties / max_references / type
        Removed value: -"integer"
  2. 1 tool updatev0.7.3
    • Changedfetch_article_details1 field changed
      • changedInput schema / properties / output_format / enum
        Previous value: -[
        -  "markdown",
        -  "json"
        -]New value: +[
        +  "markdown",
        +  "json",
        +  "toon"
        +]
  3. 51 tool updatesv0.7.2
    • Removedanalyze_figure_for_search
    • Changedanalyze_search_query4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / query / maxLength
        Added value: +4096
      • addedInput schema / properties / query / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "analyze_search_queryOutput",
        -  "type": "object"
        -}New value: +null
    • Removedanalyze_timeline_milestones
    • Changedbuild_citation_tree17 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / depth / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / depth / maximum
        Added value: +3
      • addedInput schema / properties / depth / minimum
        Added value: +1
      • addedInput schema / properties / depth / type
        Added value: +"integer"
      • addedInput schema / properties / direction / enum
        Added value: +[
        +  "forward",
        +  "backward",
        +  "both"
        +]
      • removedInput schema / properties / include_details
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "boolean"
        -    },
        -    {
        -      "type": "string"
        -    }
        -  ],
        -  "default": true,
        -  "title": "Include Details"
        -}
      • removedInput schema / properties / limit_per_level / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit_per_level / maximum
        Added value: +20
      • addedInput schema / properties / limit_per_level / minimum
        Added value: +1
      • addedInput schema / properties / limit_per_level / type
        Added value: +"integer"
      • addedInput schema / properties / output_format / enum
        Added value: +[
        +  "cytoscape",
        +  "g6",
        +  "d3",
        +  "vis",
        +  "graphml",
        +  "mermaid"
        +]
      • removedInput schema / properties / pmid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / pmid / maxLength
        Added value: +512
      • addedInput schema / properties / pmid / minLength
        Added value: +1
      • addedInput schema / properties / pmid / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "build_citation_treeOutput",
        -  "type": "object"
        -}New value: +null
    • Addedbuild_research_chronicle
    • Removedbuild_research_timeline
    • Removedcompare_timelines
    • Changedconfigure_institutional_access5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / preset / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "ntu",
        +      "ncku",
        +      "nthu",
        +      "nycu",
        +      "harvard",
        +      "stanford",
        +      "mit",
        +      "yale",
        +      "oxford",
        +      "cambridge",
        +      "sfx",
        +      "360link",
        +      "primo",
        +      "test_free"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / resolver_url / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 8192,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / test
        Removed value: -{
        -  "default": true,
        -  "title": "Test",
        -  "type": "boolean"
        -}
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "configure_institutional_accessOutput",
        -  "type": "object"
        -}New value: +null
    • Changedconvert_icd_mesh7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / code
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Code"
        -}
      • addedInput schema / properties / direction
        Added value: +{
        +  "enum": [
        +    "icd_to_mesh",
        +    "mesh_to_icd"
        +  ],
        +  "title": "Direction",
        +  "type": "string"
        +}
      • removedInput schema / properties / mesh_term
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Mesh Term"
        -}
      • addedInput schema / properties / value
        Added value: +{
        +  "maxLength": 500,
        +  "minLength": 1,
        +  "title": "Value",
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "direction",
        +  "value"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "convert_icd_meshOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddelete_pipeline5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / name / maxLength
        Added value: +64
      • addedInput schema / properties / name / minLength
        Added value: +1
      • addedInput schema / properties / name / pattern
        Added value: +"^[a-z0-9](?:[a-z0-9_-]{0,63})$"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "delete_pipelineOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddiagnose_institutional_access7 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "DOISource": {
        +    "additionalProperties": false,
        +    "description": "An explicit DOI.",
        +    "properties": {
        +      "kind": {
        +        "const": "doi",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 512,
        +        "minLength": 7,
        +        "pattern": "^10\\.[0-9]{4,9}/",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "DOISource",
        +    "type": "object"
        +  },
        +  "PMIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMIDSource",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / doi
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Doi"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmid"
        -}
      • addedInput schema / properties / source
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "doi": "#/$defs/DOISource",
        +      "pmid": "#/$defs/PMIDSource"
        +    },
        +    "propertyName": "kind"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/PMIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/DOISource"
        +    }
        +  ],
        +  "title": "Source"
        +}
      • addedInput schema / required
        Added value: +[
        +  "source"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "diagnose_institutional_accessOutput",
        -  "type": "object"
        -}New value: +null
    • Changedfetch_article_details3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "fetch_article_detailsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedfind_citing_articles8 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • removedInput schema / properties / pmid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / pmid / maxLength
        Added value: +512
      • addedInput schema / properties / pmid / minLength
        Added value: +1
      • addedInput schema / properties / pmid / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "find_citing_articlesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedfind_related_articles8 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • removedInput schema / properties / pmid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / pmid / maxLength
        Added value: +512
      • addedInput schema / properties / pmid / minLength
        Added value: +1
      • addedInput schema / properties / pmid / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "find_related_articlesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedgenerate_search_queries9 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / check_spelling / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / check_spelling / type
        Added value: +"boolean"
      • removedInput schema / properties / include_suggestions / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / include_suggestions / type
        Added value: +"boolean"
      • addedInput schema / properties / strategy / enum
        Added value: +[
        +  "comprehensive",
        +  "focused",
        +  "exploratory"
        +]
      • addedInput schema / properties / topic / maxLength
        Added value: +2000
      • addedInput schema / properties / topic / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "generate_search_queriesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_article_figures8 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "PMCIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed Central identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmcid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 23,
        +        "pattern": "^PMC[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMCIDSource",
        +    "type": "object"
        +  },
        +  "PMIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMIDSource",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / identifier
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Identifier"
        -}
      • removedInput schema / properties / pmcid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmcid"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmid"
        -}
      • addedInput schema / properties / source
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "pmcid": "#/$defs/PMCIDSource",
        +      "pmid": "#/$defs/PMIDSource"
        +    },
        +    "propertyName": "kind"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/PMIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/PMCIDSource"
        +    }
        +  ],
        +  "title": "Source"
        +}
      • addedInput schema / required
        Added value: +[
        +  "source"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_article_figuresOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_article_references8 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • removedInput schema / properties / pmid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / pmid / maxLength
        Added value: +512
      • addedInput schema / properties / pmid / minLength
        Added value: +1
      • addedInput schema / properties / pmid / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_article_referencesOutput",
        -  "type": "object"
        -}New value: +null
    • Removedget_cached_article
    • Changedget_citation_metrics7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / min_citations / anyOf
        Previous value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 2000000000,
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / min_percentile / anyOf
        Previous value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 100,
        +    "minimum": 0,
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / min_rcr / anyOf
        Previous value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 1000000,
        +    "minimum": 0,
        +    "type": "number"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / sort_by / enum
        Added value: +[
        +  "citation_count",
        +  "relative_citation_ratio",
        +  "nih_percentile",
        +  "citations_per_year"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_citation_metricsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_compound_details7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / cid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / cid / maxLength
        Added value: +20
      • addedInput schema / properties / cid / minLength
        Added value: +1
      • addedInput schema / properties / cid / pattern
        Added value: +"^[1-9][0-9]{0,19}$"
      • addedInput schema / properties / cid / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_compound_detailsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_compound_literature11 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / cid / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / cid / maxLength
        Added value: +20
      • addedInput schema / properties / cid / minLength
        Added value: +1
      • addedInput schema / properties / cid / pattern
        Added value: +"^[1-9][0-9]{0,19}$"
      • addedInput schema / properties / cid / type
        Added value: +"string"
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_compound_literatureOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_fulltext10 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "DOISource": {
        +    "additionalProperties": false,
        +    "description": "An explicit DOI.",
        +    "properties": {
        +      "kind": {
        +        "const": "doi",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 512,
        +        "minLength": 7,
        +        "pattern": "^10\\.[0-9]{4,9}/",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "DOISource",
        +    "type": "object"
        +  },
        +  "PMCIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed Central identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmcid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 23,
        +        "pattern": "^PMC[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMCIDSource",
        +    "type": "object"
        +  },
        +  "PMIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMIDSource",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / doi
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Doi"
        -}
      • removedInput schema / properties / identifier
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Identifier"
        -}
      • removedInput schema / properties / pmcid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmcid"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmid"
        -}
      • changedInput schema / properties / sections / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 500,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / source
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "doi": "#/$defs/DOISource",
        +      "pmcid": "#/$defs/PMCIDSource",
        +      "pmid": "#/$defs/PMIDSource"
        +    },
        +    "propertyName": "kind"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/PMIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/PMCIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/DOISource"
        +    }
        +  ],
        +  "title": "Source"
        +}
      • addedInput schema / required
        Added value: +[
        +  "source"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_fulltextOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_gene_details7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / gene_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / gene_id / maxLength
        Added value: +20
      • addedInput schema / properties / gene_id / minLength
        Added value: +1
      • addedInput schema / properties / gene_id / pattern
        Added value: +"^[1-9][0-9]{0,19}$"
      • addedInput schema / properties / gene_id / type
        Added value: +"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_gene_detailsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_gene_literature11 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / gene_id / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]
      • addedInput schema / properties / gene_id / maxLength
        Added value: +20
      • addedInput schema / properties / gene_id / minLength
        Added value: +1
      • addedInput schema / properties / gene_id / pattern
        Added value: +"^[1-9][0-9]{0,19}$"
      • addedInput schema / properties / gene_id / type
        Added value: +"string"
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_gene_literatureOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_institutional_link13 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "DOISource": {
        +    "additionalProperties": false,
        +    "description": "An explicit DOI.",
        +    "properties": {
        +      "kind": {
        +        "const": "doi",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 512,
        +        "minLength": 7,
        +        "pattern": "^10\\.[0-9]{4,9}/",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "DOISource",
        +    "type": "object"
        +  },
        +  "InstitutionalMetadataSource": {
        +    "additionalProperties": false,
        +    "description": "Bounded journal metadata used to construct an OpenURL.",
        +    "properties": {
        +      "issue": {
        +        "anyOf": [
        +          {
        +            "maxLength": 50,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Issue"
        +      },
        +      "journal": {
        +        "anyOf": [
        +          {
        +            "maxLength": 300,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Journal"
        +      },
        +      "kind": {
        +        "const": "metadata",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "pages": {
        +        "anyOf": [
        +          {
        +            "maxLength": 100,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Pages"
        +      },
        +      "title": {
        +        "maxLength": 1000,
        +        "minLength": 1,
        +        "title": "Title",
        +        "type": "string"
        +      },
        +      "volume": {
        +        "anyOf": [
        +          {
        +            "maxLength": 50,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Volume"
        +      },
        +      "year": {
        +        "anyOf": [
        +          {
        +            "maximum": 9999,
        +            "minimum": 1000,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Year"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "title"
        +    ],
        +    "title": "InstitutionalMetadataSource",
        +    "type": "object"
        +  },
        +  "PMIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMIDSource",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / doi
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Doi"
        -}
      • removedInput schema / properties / issue
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Issue"
        -}
      • removedInput schema / properties / journal
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Journal"
        -}
      • removedInput schema / properties / pages
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pages"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmid"
        -}
      • addedInput schema / properties / source
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "doi": "#/$defs/DOISource",
        +      "metadata": "#/$defs/InstitutionalMetadataSource",
        +      "pmid": "#/$defs/PMIDSource"
        +    },
        +    "propertyName": "kind"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/PMIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/DOISource"
        +    },
        +    {
        +      "$ref": "#/$defs/InstitutionalMetadataSource"
        +    }
        +  ],
        +  "title": "Source"
        +}
      • removedInput schema / properties / title
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Title"
        -}
      • removedInput schema / properties / volume
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Volume"
        -}
      • removedInput schema / properties / year
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Year"
        -}
      • addedInput schema / required
        Added value: +[
        +  "source"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_institutional_linkOutput",
        -  "type": "object"
        -}New value: +null
    • Changedget_pipeline_history7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / name / maxLength
        Added value: +64
      • addedInput schema / properties / name / minLength
        Added value: +1
      • addedInput schema / properties / name / pattern
        Added value: +"^[a-z0-9](?:[a-z0-9_-]{0,63})$"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_pipeline_historyOutput",
        -  "type": "object"
        -}New value: +null
    • Removedget_session_log
    • Removedget_session_pmids
    • Removedget_session_summary
    • Changedget_text_mined_terms8 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "PMCIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed Central identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmcid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 23,
        +        "pattern": "^PMC[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMCIDSource",
        +    "type": "object"
        +  },
        +  "PMIDSource": {
        +    "additionalProperties": false,
        +    "description": "An explicit PubMed identifier.",
        +    "properties": {
        +      "kind": {
        +        "const": "pmid",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "PMIDSource",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / pmcid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmcid"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "integer"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Pmid"
        -}
      • changedInput schema / properties / semantic_type / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "GENE_PROTEIN",
        +      "DISEASE",
        +      "CHEMICAL",
        +      "ORGANISM",
        +      "GO_TERM",
        +      "EFO"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / source
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "pmcid": "#/$defs/PMCIDSource",
        +      "pmid": "#/$defs/PMIDSource"
        +    },
        +    "propertyName": "kind"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/PMIDSource"
        +    },
        +    {
        +      "$ref": "#/$defs/PMCIDSource"
        +    }
        +  ],
        +  "title": "Source"
        +}
      • addedInput schema / required
        Added value: +[
        +  "source"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "get_text_mined_termsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedlist_pipelines4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / scope / enum
        Added value: +[
        +  "",
        +  "workspace",
        +  "global"
        +]
      • addedInput schema / properties / tag / maxLength
        Added value: +100
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "list_pipelinesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedlist_resolver_presets2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "list_resolver_presetsOutput",
        -  "type": "object"
        -}New value: +null
    • Changedload_pipeline4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / source / maxLength
        Added value: +4096
      • addedInput schema / properties / source / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "load_pipelineOutput",
        -  "type": "object"
        -}New value: +null
    • Removedmanage_pipeline
    • Removedparse_pico
    • Changedprepare_export5 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / format / enum
        Added value: +[
        +  "ris",
        +  "medline",
        +  "csl",
        +  "bibtex",
        +  "csv",
        +  "json"
        +]
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • addedInput schema / properties / source / enum
        Added value: +[
        +  "official",
        +  "local"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "prepare_exportOutput",
        -  "type": "object"
        -}New value: +null
    • Addedprepare_figure_search
    • Addedread_research_chronicle
    • Changedread_session21 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "ArtifactIdLocator": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "kind": {
        +        "const": "artifact_id",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "session_id": {
        +        "anyOf": [
        +          {
        +            "maxLength": 80,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Session Id"
        +      },
        +      "value": {
        +        "maxLength": 512,
        +        "minLength": 1,
        +        "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,511}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "ArtifactIdLocator",
        +    "type": "object"
        +  },
        +  "ArtifactUriLocator": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "kind": {
        +        "const": "artifact_uri",
        +        "title": "Kind",
        +        "type": "string"
        +      },
        +      "value": {
        +        "maxLength": 605,
        +        "minLength": 13,
        +        "pattern": "^artifact://[A-Za-z0-9][A-Za-z0-9_.-]{0,79}/[A-Za-z0-9][A-Za-z0-9_.-]{0,511}$",
        +        "title": "Value",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "value"
        +    ],
        +    "title": "ArtifactUriLocator",
        +    "type": "object"
        +  },
        +  "SessionArticleRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "article",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "pmid": {
        +        "maxLength": 20,
        +        "pattern": "^[1-9][0-9]{0,19}$",
        +        "title": "Pmid",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "action",
        +      "pmid"
        +    ],
        +    "title": "SessionArticleRequest",
        +    "type": "object"
        +  },
        +  "SessionArtifactRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "artifact",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "artifact_file": {
        +        "anyOf": [
        +          {
        +            "maxLength": 512,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,511}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Artifact File"
        +      },
        +      "include_local_paths": {
        +        "default": false,
        +        "title": "Include Local Paths",
        +        "type": "boolean"
        +      },
        +      "locator": {
        +        "discriminator": {
        +          "mapping": {
        +            "artifact_id": "#/$defs/ArtifactIdLocator",
        +            "artifact_uri": "#/$defs/ArtifactUriLocator"
        +          },
        +          "propertyName": "kind"
        +        },
        +        "oneOf": [
        +          {
        +            "$ref": "#/$defs/ArtifactIdLocator"
        +          },
        +          {
        +            "$ref": "#/$defs/ArtifactUriLocator"
        +          }
        +        ],
        +        "title": "Locator"
        +      },
        +      "max_chars": {
        +        "default": 200000,
        +        "maximum": 200000,
        +        "minimum": 1,
        +        "title": "Max Chars",
        +        "type": "integer"
        +      },
        +      "offset": {
        +        "default": 0,
        +        "maximum": 2000000000,
        +        "minimum": 0,
        +        "title": "Offset",
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "action",
        +      "locator"
        +    ],
        +    "title": "SessionArtifactRequest",
        +    "type": "object"
        +  },
        +  "SessionListArtifactsRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "list_artifacts",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "include_local_paths": {
        +        "default": false,
        +        "title": "Include Local Paths",
        +        "type": "boolean"
        +      },
        +      "kind": {
        +        "anyOf": [
        +          {
        +            "maxLength": 500,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Kind"
        +      },
        +      "limit": {
        +        "default": 10,
        +        "maximum": 100,
        +        "minimum": 1,
        +        "title": "Limit",
        +        "type": "integer"
        +      },
        +      "session_id": {
        +        "anyOf": [
        +          {
        +            "maxLength": 80,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Session Id"
        +      },
        +      "tool": {
        +        "anyOf": [
        +          {
        +            "maxLength": 500,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Tool"
        +      }
        +    },
        +    "required": [
        +      "action"
        +    ],
        +    "title": "SessionListArtifactsRequest",
        +    "type": "object"
        +  },
        +  "SessionLogRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "log",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "event_limit": {
        +        "default": 50,
        +        "maximum": 500,
        +        "minimum": 1,
        +        "title": "Event Limit",
        +        "type": "integer"
        +      },
        +      "history_limit": {
        +        "default": 10,
        +        "maximum": 100,
        +        "minimum": 1,
        +        "title": "History Limit",
        +        "type": "integer"
        +      },
        +      "include_history": {
        +        "default": true,
        +        "title": "Include History",
        +        "type": "boolean"
        +      },
        +      "kind": {
        +        "anyOf": [
        +          {
        +            "maxLength": 500,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Kind"
        +      }
        +    },
        +    "required": [
        +      "action"
        +    ],
        +    "title": "SessionLogRequest",
        +    "type": "object"
        +  },
        +  "SessionPmidsRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "pmids",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "query_filter": {
        +        "anyOf": [
        +          {
        +            "maxLength": 500,
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Query Filter"
        +      },
        +      "search_index": {
        +        "default": -1,
        +        "maximum": 100000,
        +        "minimum": -100000,
        +        "title": "Search Index",
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "action"
        +    ],
        +    "title": "SessionPmidsRequest",
        +    "type": "object"
        +  },
        +  "SessionReplaySearchRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "replay_search",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "run_id": {
        +        "maxLength": 512,
        +        "minLength": 1,
        +        "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,511}$",
        +        "title": "Run Id",
        +        "type": "string"
        +      },
        +      "session_id": {
        +        "anyOf": [
        +          {
        +            "maxLength": 80,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Session Id"
        +      }
        +    },
        +    "required": [
        +      "action",
        +      "run_id"
        +    ],
        +    "title": "SessionReplaySearchRequest",
        +    "type": "object"
        +  },
        +  "SessionSearchRunRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "search_run",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "run_id": {
        +        "maxLength": 512,
        +        "minLength": 1,
        +        "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,511}$",
        +        "title": "Run Id",
        +        "type": "string"
        +      },
        +      "session_id": {
        +        "anyOf": [
        +          {
        +            "maxLength": 80,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Session Id"
        +      }
        +    },
        +    "required": [
        +      "action",
        +      "run_id"
        +    ],
        +    "title": "SessionSearchRunRequest",
        +    "type": "object"
        +  },
        +  "SessionSearchRunsRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "search_runs",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "limit": {
        +        "default": 10,
        +        "maximum": 100,
        +        "minimum": 1,
        +        "title": "Limit",
        +        "type": "integer"
        +      },
        +      "session_id": {
        +        "anyOf": [
        +          {
        +            "maxLength": 80,
        +            "minLength": 1,
        +            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}$",
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Session Id"
        +      },
        +      "status": {
        +        "anyOf": [
        +          {
        +            "enum": [
        +              "started",
        +              "planned",
        +              "running",
        +              "completed",
        +              "partial",
        +              "failed",
        +              "cancelled",
        +              "interrupted"
        +            ],
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "default": null,
        +        "title": "Status"
        +      }
        +    },
        +    "required": [
        +      "action"
        +    ],
        +    "title": "SessionSearchRunsRequest",
        +    "type": "object"
        +  },
        +  "SessionSummaryRequest": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "action": {
        +        "const": "summary",
        +        "title": "Action",
        +        "type": "string"
        +      },
        +      "history_limit": {
        +        "default": 10,
        +        "maximum": 100,
        +        "minimum": 1,
        +        "title": "History Limit",
        +        "type": "integer"
        +      },
        +      "include_history": {
        +        "default": false,
        +        "title": "Include History",
        +        "type": "boolean"
        +      }
        +    },
        +    "required": [
        +      "action"
        +    ],
        +    "title": "SessionSummaryRequest",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / action
        Removed value: -{
        -  "default": "summary",
        -  "title": "Action",
        -  "type": "string"
        -}
      • removedInput schema / properties / artifact_file
        Removed value: -{
        -  "default": "",
        -  "title": "Artifact File",
        -  "type": "string"
        -}
      • removedInput schema / properties / artifact_id
        Removed value: -{
        -  "default": "",
        -  "title": "Artifact Id",
        -  "type": "string"
        -}
      • removedInput schema / properties / artifact_kind
        Removed value: -{
        -  "default": "",
        -  "title": "Artifact Kind",
        -  "type": "string"
        -}
      • removedInput schema / properties / artifact_tool
        Removed value: -{
        -  "default": "",
        -  "title": "Artifact Tool",
        -  "type": "string"
        -}
      • removedInput schema / properties / artifact_uri
        Removed value: -{
        -  "default": "",
        -  "title": "Artifact Uri",
        -  "type": "string"
        -}
      • removedInput schema / properties / event_limit
        Removed value: -{
        -  "default": 50,
        -  "title": "Event Limit",
        -  "type": "integer"
        -}
      • removedInput schema / properties / history_limit
        Removed value: -{
        -  "default": 10,
        -  "title": "History Limit",
        -  "type": "integer"
        -}
      • removedInput schema / properties / include_history
        Removed value: -{
        -  "default": false,
        -  "title": "Include History",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / include_local_paths
        Removed value: -{
        -  "default": false,
        -  "title": "Include Local Paths",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / max_chars
        Removed value: -{
        -  "default": 200000,
        -  "title": "Max Chars",
        -  "type": "integer"
        -}
      • removedInput schema / properties / offset
        Removed value: -{
        -  "default": 0,
        -  "title": "Offset",
        -  "type": "integer"
        -}
      • removedInput schema / properties / pmid
        Removed value: -{
        -  "default": "",
        -  "title": "Pmid",
        -  "type": "string"
        -}
      • removedInput schema / properties / query_filter
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": null,
        -  "title": "Query Filter"
        -}
      • addedInput schema / properties / request
        Added value: +{
        +  "discriminator": {
        +    "mapping": {
        +      "article": "#/$defs/SessionArticleRequest",
        +      "artifact": "#/$defs/SessionArtifactRequest",
        +      "list_artifacts": "#/$defs/SessionListArtifactsRequest",
        +      "log": "#/$defs/SessionLogRequest",
        +      "pmids": "#/$defs/SessionPmidsRequest",
        +      "replay_search": "#/$defs/SessionReplaySearchRequest",
        +      "search_run": "#/$defs/SessionSearchRunRequest",
        +      "search_runs": "#/$defs/SessionSearchRunsRequest",
        +      "summary": "#/$defs/SessionSummaryRequest"
        +    },
        +    "propertyName": "action"
        +  },
        +  "oneOf": [
        +    {
        +      "$ref": "#/$defs/SessionPmidsRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionArticleRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionSummaryRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionLogRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionListArtifactsRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionArtifactRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionSearchRunsRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionSearchRunRequest"
        +    },
        +    {
        +      "$ref": "#/$defs/SessionReplaySearchRequest"
        +    }
        +  ],
        +  "title": "Request"
        +}
      • removedInput schema / properties / search_index
        Removed value: -{
        -  "default": -1,
        -  "title": "Search Index",
        -  "type": "integer"
        -}
      • removedInput schema / properties / session_id
        Removed value: -{
        -  "default": "",
        -  "title": "Session Id",
        -  "type": "string"
        -}
      • addedInput schema / required
        Added value: +[
        +  "request"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "read_sessionOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsave_literature_notes7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / collection_name / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 200,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / note_format / enum
        Added value: +[
        +  "wiki",
        +  "foam",
        +  "markdown",
        +  "medpaper"
        +]
      • changedInput schema / properties / output_dir / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 4096,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / pmids / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "items": {},
        -    "type": "array"
        -  },
        -  {
        -    "type": "integer"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 100000,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "maxLength": 512,
        +      "minLength": 1,
        +      "type": "string"
        +    },
        +    "maxItems": 1000,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • changedInput schema / properties / template_file / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 4096,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "save_literature_notesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsave_pipeline12 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / config / maxLength
        Added value: +100000
      • addedInput schema / properties / config / minLength
        Added value: +1
      • addedInput schema / properties / description / maxLength
        Added value: +2000
      • addedInput schema / properties / name / maxLength
        Added value: +64
      • addedInput schema / properties / name / minLength
        Added value: +1
      • addedInput schema / properties / name / pattern
        Added value: +"^[a-z0-9](?:[a-z0-9_-]{0,63})$"
      • addedInput schema / properties / scope / enum
        Added value: +[
        +  "auto",
        +  "workspace",
        +  "global"
        +]
      • addedInput schema / properties / tags / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "maxLength": 64,
        +      "minLength": 1,
        +      "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9_.-]{0,63})$",
        +      "type": "string"
        +    },
        +    "maxItems": 20,
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / tags / default
        Previous value: -""New value: +null
      • removedInput schema / properties / tags / type
        Removed value: -"string"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "save_pipelineOutput",
        -  "type": "object"
        -}New value: +null
    • Changedschedule_pipeline9 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / cron / default
        Removed value: -""
      • addedInput schema / properties / cron / maxLength
        Added value: +200
      • addedInput schema / properties / cron / minLength
        Added value: +1
      • addedInput schema / properties / name / maxLength
        Added value: +64
      • addedInput schema / properties / name / minLength
        Added value: +1
      • addedInput schema / properties / name / pattern
        Added value: +"^[a-z0-9](?:[a-z0-9_-]{0,63})$"
      • changedInput schema / required
        Previous value: -[
        -  "name"
        -]New value: +[
        +  "name",
        +  "cron"
        +]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "schedule_pipelineOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsearch_biomedical_images21 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / article_type / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "ab",
        +      "bk",
        +      "bf",
        +      "cr",
        +      "dp",
        +      "di",
        +      "ed",
        +      "ib",
        +      "in",
        +      "lt",
        +      "mr",
        +      "ma",
        +      "ne",
        +      "ob",
        +      "pr",
        +      "or",
        +      "re",
        +      "ra",
        +      "rw",
        +      "sr",
        +      "rr",
        +      "os",
        +      "hs",
        +      "ot"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / collection / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "pmc",
        +      "cxr",
        +      "usc",
        +      "hmd",
        +      "mpx"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / hmp_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "ad",
        +        "ar",
        +        "at",
        +        "bi",
        +        "br",
        +        "cr",
        +        "ca",
        +        "ch",
        +        "cg",
        +        "cd",
        +        "dr",
        +        "ep",
        +        "ex",
        +        "hr",
        +        "hu",
        +        "lt",
        +        "mp",
        +        "nw",
        +        "pn",
        +        "ph",
        +        "pi",
        +        "po",
        +        "pt",
        +        "pc",
        +        "ps"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Hmp Type"
        +}
      • changedInput schema / properties / image_type / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "xg",
        +      "xm",
        +      "x",
        +      "u",
        +      "ph",
        +      "p",
        +      "mc",
        +      "m",
        +      "g",
        +      "c"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / license_type / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "by",
        +      "bync",
        +      "byncnd",
        +      "byncsa"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • removedInput schema / properties / open_access_only
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "boolean"
        -    },
        -    {
        -      "type": "string"
        -    }
        -  ],
        -  "default": true,
        -  "title": "Open Access Only"
        -}
      • addedInput schema / properties / query / maxLength
        Added value: +500
      • addedInput schema / properties / query / minLength
        Added value: +1
      • changedInput schema / properties / search_fields / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "t",
        +      "m",
        +      "ab",
        +      "msh",
        +      "c",
        +      "a"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / sort_by / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "r",
        +      "o",
        +      "d",
        +      "e",
        +      "g",
        +      "oc",
        +      "pr",
        +      "pg",
        +      "t"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / sources
        Removed value: -{
        -  "default": "auto",
        -  "title": "Sources",
        -  "type": "string"
        -}
      • changedInput schema / properties / specialty / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "b",
        +      "bc",
        +      "c",
        +      "ca",
        +      "cc",
        +      "d",
        +      "de",
        +      "dt",
        +      "e",
        +      "en",
        +      "f",
        +      "eh",
        +      "g",
        +      "ge",
        +      "gr",
        +      "gy",
        +      "h",
        +      "i",
        +      "id",
        +      "im",
        +      "n",
        +      "ne",
        +      "nu",
        +      "o",
        +      "or",
        +      "ot",
        +      "p",
        +      "py",
        +      "pu",
        +      "r",
        +      "s",
        +      "t",
        +      "u",
        +      "v",
        +      "vi"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / subset / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "b",
        +      "c",
        +      "e",
        +      "s",
        +      "x"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / video_only / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / video_only / type
        Added value: +"boolean"
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "search_biomedical_imagesOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsearch_clinvar8 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • addedInput schema / properties / query / maxLength
        Added value: +500
      • addedInput schema / properties / query / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "search_clinvarOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsearch_compound8 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • addedInput schema / properties / query / maxLength
        Added value: +500
      • addedInput schema / properties / query / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "search_compoundOutput",
        -  "type": "object"
        -}New value: +null
    • Changedsearch_gene9 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +50
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • changedInput schema / properties / organism / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 200,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / query / maxLength
        Added value: +500
      • addedInput schema / properties / query / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "search_geneOutput",
        -  "type": "object"
        -}New value: +null
    • Changedtest_institutional_access4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / pmid / maxLength
        Added value: +32
      • addedInput schema / properties / pmid / minLength
        Added value: +1
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "test_institutional_accessOutput",
        -  "type": "object"
        -}New value: +null
    • Changedunified_search14 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • changedInput schema / properties / filters / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 4096,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / limit / anyOf
        Removed value: -[
        -  {
        -    "type": "integer"
        -  },
        -  {
        -    "type": "string"
        -  }
        -]
      • addedInput schema / properties / limit / maximum
        Added value: +100
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / limit / type
        Added value: +"integer"
      • changedInput schema / properties / options / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 2048,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / pipeline / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 100000,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / query / default
        Added value: +""
      • addedInput schema / properties / query / maxLength
        Added value: +4096
      • changedInput schema / properties / sources / anyOf
        Previous value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "maxLength": 1024,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / stop_at / maxLength
        Added value: +200
      • removedInput schema / required
        Removed value: -[
        -  "query"
        -]
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "unified_searchOutput",
        -  "type": "object"
        -}New value: +null
    • Addedunschedule_pipeline
    • Addedvalidate_pico_plan
    • Changedverify_reference_list7 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_references / maximum
        Added value: +200
      • addedInput schema / properties / max_references / minimum
        Added value: +1
      • addedInput schema / properties / reference_text / maxLength
        Added value: +200000
      • addedInput schema / properties / reference_text / minLength
        Added value: +1
      • addedInput schema / properties / source_name / maxLength
        Added value: +255
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "result": {
        -      "title": "Result",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "result"
        -  ],
        -  "title": "verify_reference_listOutput",
        -  "type": "object"
        -}New value: +null
  4. 46 tool updatesv0.5.16
    • First observedanalyze_figure_for_search
    • First observedanalyze_search_query
    • First observedanalyze_timeline_milestones
    • First observedbuild_citation_tree
    • First observedbuild_research_timeline
    • First observedcompare_timelines
    • First observedconfigure_institutional_access
    • First observedconvert_icd_mesh
    • First observeddelete_pipeline
    • First observeddiagnose_institutional_access
    • First observedfetch_article_details
    • First observedfind_citing_articles
    • First observedfind_related_articles
    • First observedgenerate_search_queries
    • First observedget_article_figures
    • First observedget_article_references
    • First observedget_cached_article
    • First observedget_citation_metrics
    • First observedget_compound_details
    • First observedget_compound_literature
    • First observedget_fulltext
    • First observedget_gene_details
    • First observedget_gene_literature
    • First observedget_institutional_link
    • First observedget_pipeline_history
    • First observedget_session_log
    • First observedget_session_pmids
    • First observedget_session_summary
    • First observedget_text_mined_terms
    • First observedlist_pipelines
    • First observedlist_resolver_presets
    • First observedload_pipeline
    • First observedmanage_pipeline
    • First observedparse_pico
    • First observedprepare_export
    • First observedread_session
    • First observedsave_literature_notes
    • First observedsave_pipeline
    • First observedschedule_pipeline
    • First observedsearch_biomedical_images
    • First observedsearch_clinvar
    • First observedsearch_compound
    • First observedsearch_gene
    • First observedtest_institutional_access
    • First observedunified_search
    • First observedverify_reference_list

TDQS

A3.7/5.0

Scored across 41 tools

Disambiguation3/5

The set contains several overlapping clusters: unified_search vs generate_search_queries/analyze_search_query, four citation-exploration tools (find_related_articles, find_citing_articles, get_article_references, build_citation_tree), and multiple fulltext/institutional-access tools (get_fulltext, diagnose_institutional_access, get_institutional_link, configure_institutional_access, test_institutional_access). Descriptions are unusually detailed and cross-reference each other, which mitigates confusion, but an agent must still inspect descriptions carefully to avoid misselection.

Naming Consistency5/5

All 41 tools use snake_case with a consistent verb_noun or verb_phrase pattern (search_gene, get_fulltext, build_citation_tree, save_literature_notes, etc.). There is no camelCase or mixed casing, and the single adjective-first tool unified_search does not meaningfully break the predictable convention.

Tool Count2/5

With 41 tools, this server is far beyond the 3-15 sweet spot and includes many specialized helpers (seven pipeline tools, five institutional-access tools, three gene tools, three compound tools, session/artifact readers, and image/chronicle tools). Each may have a distinct purpose, but the sheer count makes the surface heavy and raises selection cost for an agent.

Completeness5/5

The surface covers search and discovery, citation networks, fulltext retrieval, export, note-saving, pipeline lifecycle (save/list/load/delete/schedule/unschedule/history), persistent research chronicles, gene/compound lookup, biomedical image search, and institutional access. No obvious lifecycle gaps are present, and overwrite/upsert semantics handle missing update operations.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server that enables coding agents to search academic papers, ingest full-text PDFs, extract structured details, and manage citations in literature research workflows.
    31
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    AI-powered research assistant MCP server for searching academic papers and answering research questions with DOI citations.
    3
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    An advanced scholarly research MCP server that enables AI assistants to discover, fetch, process, and manage academic papers across multiple sources like arXiv, PubMed, and Semantic Scholar, with capabilities for summarization, citation analysis, and concept relationship extraction.
    2
    -