Skip to main content
Glama

build_citation_tree

Read-onlyIdempotent

Build a visual citation network from one PubMed article to explore its references, citing papers, and research lineage in formats like Cytoscape, G6, D3, or GraphML.

Instructions

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")

Input Schema

TableJSON 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

Schema Changelog

Changes observed during successful MCP inspections.

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

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.