Skip to main content
Glama

unified_search

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

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 exclude_seen → omit prior session results by PMID/DOI (not supported with pipeline) 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

           template: snowball
           template_params:
             query: CRISPR gene therapy
             seed_limit: 5
             limit: 20

         **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 OR seed_limit, limit)
           citing      — find citing articles (params: pmid OR seed_limit, limit)
           references  — get article references (params: pmid OR seed_limit, 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)
         seed_limit (1-10) snowballs from the first unique input PMIDs;
         it needs inputs, is exclusive with pmid, and excludes seeds.

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

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.6/5.0
Behavior5/5

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

The description goes well beyond the annotations: it discloses auto source selection by query complexity, dedup/merge, auto-relaxation on zero results with a no_relax opt-out, background prefetch that never blocks the search and needs no polling, env-gated source disabling, mutual exclusivity of native_semantic and systematic, and the 50-result cap for native_semantic. These are exactly the operational traits the readOnlyHint/openWorldHint 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.

Conciseness3/5

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

It is front-loaded well with WHAT IT DOES and EXAMPLES before the arg list, and the length is partly justified by 11 undocumented parameters. However, the examples are largely redundant with the Args section, and there are structural defects, e.g. the dangling sentence 'and automatically disable multi-strategy query expansion.' stranded after the native_semantic/systematic note.

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?

There is no output schema, and the description supplies a Returns section covering query analysis, ICD expansions, statistics, ranked records, OA links, preprints, relaxation info and pipeline step summary. Given the tool's complexity, the combination of behavior, parameters, returns and constraints leaves nothing an agent needs to call it 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 description coverage is 0% and all 11 parameters are undocumented in the schema, so the description carries the full burden and does: it defines every parameter, enumerates canonical source keys, all filter keys with value vocabularies, all option flags with their effects, the ranking strategies, output_format values, and pipeline YAML/JSON structure with actions, globals, variables, dry_run and stop_at. It also states exact-spelling requirements and pipeline parameter-ignoring behavior.

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 ('Unified Search - Single entry point for multi-source academic search') and enumerates the eight-step pipeline it performs. It explicitly positions itself against the concrete alternatives ('No need to choose between PubMed, OpenAlex, CrossRef, etc.'), so an agent can distinguish it from the sibling search tools without opening any 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?

Nine worked examples cover simple queries, source selection with 'auto'/'all' exclusions, filters, preprints, native semantic, systematic retrieval, and full control, which makes the intended call patterns clear. It falls short of a 5 because it never states when to prefer a sibling instead (e.g. analyze_search_query, find_related_articles, get_article_references); routing is left implicit in 'single entry point'.

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