Skip to main content
Glama

unified_search

Search PubMed, OpenAlex, CrossRef and other academic sources in one query; automatically analyzes intent, selects sources, deduplicates and ranks results.

Instructions

šŸ” Unified Search - Single entry point for multi-source academic search.

Automatically analyzes your query and searches the best sources. No need to choose between PubMed, OpenAlex, CrossRef, etc.

═══════════════════════════════════════════════════════════════════ WHAT IT DOES: ═══════════════════════════════════════════════════════════════════

  1. Analyzes your query (complexity, intent, PICO elements)

  2. Automatically selects best sources based on query type

  3. Searches multiple sources in parallel

  4. Deduplicates and merges results

  5. Ranks by configurable criteria

  6. Enriches with OA links (Unpaywall)

  7. Auto-detects ICD-9/10 codes and expands to MeSH terms

  8. Optionally searches preprints (arXiv, medRxiv, bioRxiv)

═══════════════════════════════════════════════════════════════════ EXAMPLES (most calls only need 1-2 params): ═══════════════════════════════════════════════════════════════════

Simple (1 param): unified_search("remimazolam ICU sedation")

With limit (2 params): unified_search("machine learning in anesthesia", limit=20)

Specify sources: unified_search("CRISPR gene therapy", sources="pubmed,openalex")

Auto minus one source: unified_search("sepsis biomarkers", sources="auto,-semantic_scholar")

Search all enabled sources except enrichment-only CrossRef: unified_search("icu sedation", sources="all,-crossref")

Clinical filters: unified_search("diabetes treatment", filters="year:2020-2025,age_group:aged,clinical_query:therapy")

Include preprints + shallow search: unified_search("COVID-19 vaccine", options="preprints,shallow")

Provider-native semantic retrieval (OpenAlex capability): unified_search("mechanisms of treatment resistance", sources="openalex", options="native_semantic")

Reproducible systematic retrieval (bulk/cursor where supported): unified_search("melanoma AND immunotherapy", sources="openalex,semantic_scholar", options="systematic")

Full control: unified_search("propofol vs remimazolam", sources="pubmed,semantic_scholar,europe_pmc", ranking="impact", filters="year:2020-,sex:female,species:humans", options="preprints,no_relax")

ICD Code Auto-Detection: unified_search("E11 complications") → Auto-expands E11 to "Diabetes Mellitus, Type 2"[MeSH]

Args: query: Search query (natural language, ICD codes, or structured). Required unless pipeline is provided. limit: Maximum results per source (default 10, max 100) sources: Comma-separated list of sources to search. Available: "pubmed", "openalex", "semantic_scholar", "europe_pmc", "crossref", "core". Commercial connectors may also appear when enabled via env, e.g. "scopus" when SCOPUS_ENABLED=true and SCOPUS_API_KEY are configured, or "web_of_science" when WEB_OF_SCIENCE_ENABLED=true and WEB_OF_SCIENCE_API_KEY are configured. Default: auto-select based on query complexity. Supports "auto" and "all" with exclusions. Source keys are exact and canonical; legacy hyphenated, spaced, abbreviated, or case-folded aliases are rejected. Examples: "pubmed,openalex", "auto,-semantic_scholar", or "all,-crossref" Global disable env: PUBMED_SEARCH_DISABLED_SOURCES Example: PUBMED_SEARCH_DISABLED_SOURCES=semantic_scholar,core ranking: Ranking strategy: - "balanced": Default, considers all factors - "impact": Prioritize high-citation papers - "recency": Prioritize recent publications - "quality": Prioritize publication-type heuristics (RCTs, meta-analyses); not a quality assessment output_format: "markdown" (human-readable), "json", or "toon" (programmatic) fulltext: "off" (default) or "prefetch" for normal searches. Prefetch prepares open-access XML for up to three top-ranked articles with known PMCIDs in the background. Search does not wait. Later get_fulltext calls reuse ready or in-flight XML; no polling is needed. No speculative PDF, browser or institutional access. Not supported with pipeline; use "off" for pipeline calls. filters: Comma-separated key:value pairs for filtering results. Supported keys: year:2020-2025 → publication year range year:2020- → from 2020 onwards year:-2025 → up to 2025 year:2024 → from 2024 onwards age_group: → age group filter (PubMed). Values: newborn, infant, preschool, child, adolescent, young_adult, adult, middle_aged, aged, aged_80 sex: → sex filter: male, female species: → species filter: humans, animals language: → language filter: english, chinese, etc. clinical_query: → clinical query filter (PubMed EBM). Values: therapy, therapy_narrow, diagnosis, diagnosis_narrow, prognosis, prognosis_narrow, etiology, etiology_narrow, clinical_prediction, clinical_prediction_narrow Tokens, keys, and values use exact canonical spelling with no surrounding whitespace. Example: "year:2020-2025,age_group:aged,sex:female,clinical_query:therapy" options: Comma-separated flags to toggle behaviors. Supported flags: preprints → also search arXiv, medRxiv, bioRxiv include_detected_preprints → retain records identified by the preprint heuristic in otherwise selected sources; this does not establish peer-review status clinical_trials → add a bounded ClinicalTrials.gov adjunct section to Markdown output (explicit opt-in) no_oa → skip Unpaywall OA link enrichment no_analysis → hide query analysis section in output no_scores → hide ranking scores and rank percentiles compact → compact structured JSON/TOON output no_next → hide next-tool suggestions in structured output no_provenance → hide section provenance in structured output no_relax → disable auto-relaxation on 0 results native_semantic → use provider-native semantic retrieval; currently OpenAlex, max 50 results systematic → use deterministic bulk/cursor retrieval where supported (for example S2 and OpenAlex) shallow → disable deep search (faster, keyword-only) native_semantic and systematic are mutually exclusive Option tokens use exact canonical spelling with no surrounding whitespace. and automatically disable multi-strategy query expansion. Tokens use exact canonical spelling without surrounding whitespace or duplicates. Example: "preprints,shallow" or "no_analysis,no_scores" pipeline: YAML/JSON string defining a multi-step search pipeline. When provided, other parameters (except output_format) are ignored and the pipeline DAG is executed instead.

         Accepts **YAML** (recommended, human-friendly) or **JSON** format.

         **Template mode — YAML** (shortcut for common workflows):
           template: pico
           template_params:
             P: ICU patients
             I: remimazolam
             C: propofol
             O: sedation

         Other templates:
           template: comprehensive
           template_params:
             query: CRISPR gene therapy

           template: exploration
           template_params:
             pmid: "12345678"

           template: gene_drug
           template_params:
             term: BRCA1

         **Custom pipeline — YAML** (full DAG control, max 20 steps):
           name: My Custom Search
           steps:
             - id: s1
               action: search
               params:
                 query: remimazolam ICU
                 sources: [pubmed, europe_pmc]
                 limit: 50
             - id: s2
               action: search
               params:
                 query: propofol ICU
                 sources: [pubmed]
                 limit: 50
             - id: merged
               action: merge
               inputs: [s1, s2]
               params:
                 method: rrf
             - id: enriched
               action: metrics
               inputs: [merged]
           output:
             format: markdown
             limit: 20
             ranking: impact

         Shared params:
           globals: default params inherited only by actions that
                    declare the same canonical parameter key
           variables: typed values available as ${name} placeholders;
                      embedded replacements must be strings

         Debugging controls:
           dry_run: validate/preview the pipeline without searches
           stop_at: execute through one step id, e.g. "merged"

         **JSON also supported** (for programmatic use):
           {"template": "pico", "template_params": {"P": "ICU patients", "I": "remimazolam"}}

         Available actions:
           search      — literature search (params: query, sources, limit, min_year, max_year)
           pico        — PICO elements (params: P, I, C, O)
           expand      — MeSH/synonym expansion (params: topic)
           details     — fetch article details (params: pmids)
           related     — find related articles (params: pmid, limit)
           citing      — find citing articles (params: pmid, limit)
           references  — get article references (params: pmid, limit)
           metrics     — enrich with iCite citation metrics (inputs only)
           merge       — combine results (params: method=union|intersection|rrf)
           filter      — post-filter (params: min_year, max_year, article_types, min_citations, has_abstract)

Returns: Formatted search results with: - Query analysis (complexity, intent, PICO) - ICD code expansions (if detected) - Search statistics (sources, dedup count) - Ranked articles with metadata - Open access links where available - Preprints (if options includes "preprints") - Relaxation info (if auto_relax triggered) - Pipeline step summary (if pipeline mode)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
dry_runNo
filtersNo
optionsNo
rankingNobalanced
sourcesNo
stop_atNo
fulltextNooff
pipelineNo
output_formatNomarkdown

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed13 schema fields changedv0.7.7
    • 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"
  2. Changed14 schema fields changedv0.7.2
    • 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
  3. First observedv0.5.16

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (openWorldHint, readOnlyHint=false), the description discloses substantial behavioral detail: parallel multi-source search, dedup/merge, auto-relaxation on zero results, background fulltext prefetch that requires no polling, and env-gated commercial connectors (SCOPUS_API_KEY, etc.). This is far more than the structured annotations 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?

Headers and front-loading make it navigable despite its length, and the length is defensible for an 11-parameter tool with a pipeline DSL. However, there is visible redundancy (the 'exact canonical spelling' rule is repeated) and at least one garbled sentence around the native_semantic/systematic flags, plus decorative box-drawing that adds noise.

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, the description correctly supplies a Returns section covering query analysis, ICD expansions, statistics, ranked articles, OA links, preprints, relaxation info, and pipeline summaries. Combined with full parameter documentation, nothing needed to invoke 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 0%, so the description carries the full burden, and it does so thoroughly: every parameter (query, limit, sources, ranking, output_format, fulltext, filters, options, pipeline, dry_run, stop_at) is documented with accepted values, defaults, syntax rules, and interactions (e.g. native_semantic/systematic mutual exclusivity, canonical-token requirement).

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 title line plus the numbered WHAT IT DOES list state a specific verb (search) and resource (multi-source academic literature), and the framing as the 'single entry point' distinguishes it from sibling helpers like find_related_articles or analyze_search_query. An agent can immediately tell this is the primary retrieval tool.

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 context ('no need to choose between PubMed, OpenAlex, CrossRef') and a rich set of worked examples showing when to add sources, filters, options, or a pipeline. It stops short of explicitly naming sibling alternatives or stating when NOT to use this tool, so it is strong but not fully routing-aware.

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