get_mesh_record
Retrieve detailed cataloging information for confirmed MeSH headings, including scope notes, tree structures, parent descriptors, and cross-references to support medical subject analysis.
Instructions
Retrieve a full MeSH descriptor record including scope note (annotation), tree numbers with their top-level category letters, broader descriptors, and see-also cross-references.
Use this after search_mesh to obtain cataloging details for a confirmed MeSH heading.
Parameters
descriptor : str The MeSH UI code (e.g. "D003920") or full URI returned by search_mesh.
Returns
dict A structured record containing: - ui : MeSH unique identifier (e.g. "D003920") - uri : Full RDF URI - label : Preferred heading label - annotation : Scope note / indexing annotation (if present) - dateIntroduced : Year the heading was introduced - lastUpdated : Date the record was last updated - treeNumbers : List of tree number strings (e.g. "C18.452.394.750") - treeCategories : Top-level category letters derived from tree numbers - broader : List of {label, ui} dicts for parent descriptors - seeAlso : List of {label, ui} dicts for cross-references - qualifierCount : Number of allowable qualifiers (full list via get_mesh_qualifiers)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| descriptor | Yes |
Implementation Reference
- src/mesh_mcp/server.py:154-261 (handler)The get_mesh_record tool definition and handler implementation which retrieves detailed MeSH record data from the NLM API.
@mcp.tool() def get_mesh_record(descriptor: str) -> dict: """ Retrieve a full MeSH descriptor record including scope note (annotation), tree numbers with their top-level category letters, broader descriptors, and see-also cross-references. Use this after search_mesh to obtain cataloging details for a confirmed MeSH heading. Parameters ---------- descriptor : str The MeSH UI code (e.g. "D003920") or full URI returned by search_mesh. Returns ------- dict A structured record containing: - ui : MeSH unique identifier (e.g. "D003920") - uri : Full RDF URI - label : Preferred heading label - annotation : Scope note / indexing annotation (if present) - dateIntroduced : Year the heading was introduced - lastUpdated : Date the record was last updated - treeNumbers : List of tree number strings (e.g. "C18.452.394.750") - treeCategories : Top-level category letters derived from tree numbers - broader : List of {label, ui} dicts for parent descriptors - seeAlso : List of {label, ui} dicts for cross-references - qualifierCount : Number of allowable qualifiers (full list via get_mesh_qualifiers) """ ui = _normalise_id(descriptor) result = _get(f"{_BASE}/{ui}.json") if "error" in result: return result data = result["data"] if not isinstance(data, dict): return {"error": f"Unexpected response format for descriptor {ui}", "data": data} out = { "ui": ui, "uri": data.get("@id", f"http://id.nlm.nih.gov/mesh/{ui}"), } # ── Label ──────────────────────────────────────────────────────────────── out["label"] = _text(data.get("label", ui)) # ── Annotation (scope note / indexing guidance) ─────────────────────── annotation = _text(data.get("annotation", "")) if annotation: out["annotation"] = annotation # ── Dates ───────────────────────────────────────────────────────────── if data.get("dateIntroduced"): out["dateIntroduced"] = str(data["dateIntroduced"])[:4] # year only if data.get("lastUpdated"): out["lastUpdated"] = str(data["lastUpdated"]) # ── Tree numbers ────────────────────────────────────────────────────── # treeNumber is a list of full URIs like # "http://id.nlm.nih.gov/mesh/C18.452.394.750" # The tree number string itself is the last path segment. raw_trees = data.get("treeNumber", []) if isinstance(raw_trees, str): raw_trees = [raw_trees] tree_numbers = [_uri_to_id(t) for t in raw_trees if t] if tree_numbers: out["treeNumbers"] = sorted(tree_numbers) categories = sorted(set(tn[0] for tn in tree_numbers if tn)) out["treeCategories"] = categories # ── Broader descriptors ─────────────────────────────────────────────── # broaderDescriptor is a list of URI strings; resolve each to a label. raw_broader = data.get("broaderDescriptor", []) if isinstance(raw_broader, str): raw_broader = [raw_broader] broader = [] for uri in raw_broader: b_ui = _uri_to_id(uri) b_lbl = _resolve_label(b_ui) broader.append({"label": b_lbl, "ui": b_ui}) if broader: out["broader"] = broader # ── See also ───────────────────────────────────────────────────────── raw_see = data.get("seeAlso", []) if isinstance(raw_see, str): raw_see = [raw_see] see_also = [] for uri in raw_see: s_ui = _uri_to_id(uri) s_lbl = _resolve_label(s_ui) see_also.append({"label": s_lbl, "ui": s_ui}) if see_also: out["seeAlso"] = see_also # ── Qualifier count (hint to call get_mesh_qualifiers) ──────────────── raw_quals = data.get("allowableQualifier", []) if isinstance(raw_quals, str): raw_quals = [raw_quals] out["qualifierCount"] = len(raw_quals) return out