""" gene_hub – resolve_gene() tries three sources in order of speed & richness. 1. MyGene.info (v3) – 500 QPS key tier :contentReference[oaicite:3]{index=3} 2. Ensembl REST – key-less, species-agnostic :contentReference[oaicite:4]{index=4} 3. Open Targets GQL – tractability & constraint :contentReference[oaicite:5]{index=5} """ from mcp.mygene import fetch_gene_info from mcp.ensembl import fetch_ensembl from mcp.opentargets import fetch_ot async def resolve_gene(symbol: str) -> dict: """Return first non-empty gene record; never raises.""" for fn in (fetch_gene_info, fetch_ensembl, fetch_ot): try: data = await fn(symbol) if data: return data except Exception: # network hiccup / 429 etc. pass return {}