{"id":"a97b4a0c-7ffa-4006-83fc-3ed19554c8e9","slug":"aronow-lab-bond","kind":"mcp","name":"BOND","summary":"Biomedical Ontology Normalization and Disambiguation","owner":"Aronow-Lab","repoUrl":"https://github.com/Aronow-Lab/BOND","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-01-20T15:22:01.000Z","addedAt":"2026-10-21T20:26:57.303Z","logoUrl":"https://avatars.githubusercontent.com/u/255988294?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["utilities"],"tags":[],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T04:12:09.074Z","sample":false,"url":"https://conduits.dev/tools/aronow-lab-bond","language":"Python","transports":["stdio"],"install":{"pypi":"bond-ai"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# BOND: Biomedical Ontology Normalization and Disambiguation\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![GitHub](https://img.shields.io/github/stars/Aronow-Lab/BOND?style=social)](https://github.com/Aronow-Lab/BOND)\n[![HuggingFace Dataset](https://img.shields.io/badge/dataset-huggingface-blue)](https://huggingface.co/datasets/AronowLab/bond-czi-benchmark)\n[![HuggingFace Model](https://img.shields.io/badge/model-huggingface-blue)](https://huggingface.co/pankajrajdeo/bond-embed-v1-fp16)\n[![HuggingFace Reranker](https://img.shields.io/badge/reranker-huggingface-blue)](https://huggingface.co/AronowLab/BOND-reranker)\n\nBOND is a system for mapping free-text biological terms to standardized ontology identifiers. It combines hybrid retrieval (exact matching, BM25, dense embeddings), reciprocal rank fusion, cross-encoder reranker, graph-based expansion, and LLM-powered disambiguation to achieve high-accuracy ontology normalization for biomedical metadata.\n\n## 📓 Example Notebooks\n\n- **Reranker Trained Notebook**: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1USKLEtyWmbvzOM3ZlkUYDg3EUcMRC1MQ#scrollTo=QRdu0nhobRLA) - Fine-tuned BOND reranker model\n- **Train Your Own Reranker**: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1Qq0FolMY8GfLdxXnfvgdPJnx1rCzUgUy?usp=sharing) - Complete guide with dataset structure, configuration, and training instructions\n\n## 🎯 Overview\n\nBOND addresses the critical challenge of harmonizing diverse biological terminology across research studies and datasets. When researchers submit data to public repositories like GEO, ArrayExpress, or CELLxGENE, they often use inconsistent or non-standard terminology. BOND automatically maps these \"author terms\" to standardized ontology identifiers, enabling:\n\n- **Metadata harmonization** across datasets\n- **Semantic interoperability** for cross-study analysis\n- **FAIR compliance** through ontology-linked metadata\n- **Scalable curation** of large biomedical repositories\n\n## ✨ Key Features\n\n- **Hybrid Search Architecture**: Combines exact matching, BM25 keyword search, and dense semantic search (FAISS) for comprehensive retrieval\n- **Reciprocal Rank Fusion (RRF)**: Intelligently combines results from multiple retrieval methods\n- **Cross-Encoder Reranker**: Fine-tuned biomedical reranker model improves accuracy by 10-15% by re-ranking candidates\n- **LLM-Powered Expansion**: Uses large language models to generate query expansions and context-aware synonyms\n- **Graph-Based Expansion**: Leverages ontology hierarchies to discover related terms\n- **Context-Aware Disambiguation**: LLM reasoning to select the correct ontology ID from candidate matches\n- **Multi-Ontology Support**: Works with Cell Ontology (CL), UBERON, MONDO, EFO, PATO, HANCESTRO, and more\n- **Organism-Aware Routing**: Automatically selects appropriate ontologies based on organism and field type\n- **RESTful API**: FastAPI-based service for easy integration\n- **BOND MCP**: Model Context Protocol server for agentic normalization workflows\n- **CLI Tool**: Command-line interface for batch processing\n\n## 📊 Supported Fields and Ontologies\n\n### Supported Fields\n\n- `cell_type`: Cell types and classifications (Cell Ontology)\n- `tissue`: Anatomical structures (UBERON)\n- `disease`: Disease conditions (MONDO)\n- `development_stage`: Developmental stages (organism-specific)\n- `sex`: Biological sex (PATO)\n- `self_reported_ethnicity`: Ethnicity/ancestry (HANCESTRO)\n- `assay`: Experimental methods (EFO)\n- `organism`: Taxonomic classification (NCBI Taxonomy)\n\n### Supported Organisms\n\n- `Homo sapiens`\n- `Mus musculus`\n- `Danio rerio` (zebrafish)\n- `Drosophila melanogaster` (fruit fly)\n- `Caenorhabditis elegans` (C. elegans)\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/Aronow-Lab/BOND.git\ncd BOND\n\n# Create and activate virtual environment\npython3.11 -m venv bond_venv\nsource bond_venv/bin/activate  # On Windows: bond_venv\\Scripts\\activate\n\n# Install dependencies\npip install --upgrade pip\npip install -e .\n```\n\n### Prerequisites\n\n1. **Ontology Database**: You need an SQLite database containing ontology terms. See [Installation Guide](INSTALLATION.md) for details.\n2. **FAISS Index**: Build a FAISS index for dense semantic search:\n   ```bash\n   bond-build-faiss \\\n     --sqlite_path assets/snapshots/bond-ontology-current/ontologies.sqlite \\\n     --assets_path assets/snapshots/bond-ontology-current\n   ```\n3. **Environment Variables**: Configure LLM providers and embedding models (see Configuration below)\n\n### Basic Usage\n\n#### CLI Example\n\n```bash\nbond-query \\\n  --query \"T-cell\" \\\n  --field cell_type \\\n  --organism \"Homo sapiens\" \\\n  --tissue \"blood\" \\\n  --verbose\n```\n\n#### Python API Example\n\n```python\nfrom bond import BondMatcher\nfrom bond.config import BondSettings\n\n# Initialize matcher\nsettings = BondSettings()\nmatcher = BondMatcher(settings)\n\n# Query\nresult = matcher.query(\n    query=\"T-cell\",\n    field_name=\"cell_type\",\n    organism=\"Homo sapiens\",\n    tissue=\"blood\"\n)\n\nprint(f\"Matched: {result['chosen']['label']}\")\nprint(f\"Ontology ID: {result['chosen']['id']}\")\nprint(f\"Confidence: {result['chosen']['llm_confidence']}\")\n```\n\n#### API Server\n\n```bash\n# Start server (with anonymous access for development)\nBOND_ALLOW_ANON=1 bond-serve\n\n# Or with API key authentication\nexport BOND_API_KEY=your-secret-key\nbond-serve\n```\n\nThen query the API:\n\n```bash\ncurl -X POST \"http://localhost:8000/query\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer your-secret-key\" \\\n  -d '{\n    \"query\": \"T-cell\",\n    \"field_name\": \"cell_type\",\n    \"organism\": \"Homo sapiens\",\n    \"tissue\": \"blood\"\n  }'\n```\n\n#### BOND MCP\n\nUse BOND as a local MCP server for agentic metadata normalization:\n\n```bash\nbond-mcp\n```\n\nFor Streamable HTTP:\n\n```bash\nbond-mcp --transport streamable-http --host 127.0.0.1 --port 8001\n```\n\nBOND MCP exposes three tools:\n\n- `bond_normalize_term`: normalize one biomedical metadata term with biological context\n- `bond_validate_mapping`: audit a proposed CURIE against a term and context\n- `bond_lookup_term`: inspect ontology term metadata, synonyms, parents, and optional ancestors\n\nIt also exposes resources for ontology catalog, field mappings, supported organisms, examples, and server status, plus prompts for column harmonization and mapping review.\n\n## 🔧 Configuration\n\nBOND uses environment variables for configuration. Create a `.env` file:\n\n```bash\n# Embedding Model (choose ONE of the options below)\n\n# Option A: Use your Ollama encoder (recommended for local)\n# Make sure the model is available in Ollama first:\n#   ollama pull rajdeopankaj/bond-embed-v1-fp16\nBOND_EMBED_MODEL=ollama:rajdeopankaj/bond-embed-v1-fp16\n# If running remote Ollama, set the API base (default: http://localhost:11434)\n# OLLAMA_API_BASE=http://your-ollama-host:11434\n\n# Option B: Use a LiteLLM-compatible hosted embedding endpoint\n# Example: OpenAI, Azure OpenAI, Together, Groq, etc.\n# BOND_EMBED_MODEL=litellm:text-embedding-3-small\n\n# Option C: Use Hugging Face TEI (Text Embeddings Inference)\n# Deploy your HF model (pankajrajdeo/bond-embed-v1-fp16) behind a LiteLLM-compatible endpoint,\n# then set the model name accordingly.\n# Example if exposed as huggingface/teimodel (via LiteLLM routing):\n# BOND_EMBED_MODEL=litellm:huggingface/teimodel\n\n# LLM Providers (for expansion and disambiguation)\nBOND_EXPANSION_LLM=anthropic/claude-3-5-sonnet-20241022\nBOND_DISAMBIGUATION_LLM=anthropic/claude-3-5-sonnet-20241022\n\n\n# Or use OpenAI\n# BOND_EXPANSION_LLM=openai/gpt-4o\n# BOND_DISAMBIGUATION_LLM=openai/gpt-4o\n\n# API Keys (set as environment variables or in .env)\nANTHROPIC_API_KEY=your-key\nOPENAI_API_KEY=your-key\n\n# Paths\nBOND_ASSETS_PATH=assets/snapshots/bond-ontology-current\n\n# Reranker Configuration\n# Path to trained reranker model (cross-encoder)\n# Set this only when a trained reranker directory is available.\n# BOND_RERANKER_PATH=/path/to/local/reranker\n\n# Retrieval Parameters\nBOND_TOPK_EXACT=5\nBOND_TOPK_BM25=20\nBOND_TOPK_DENSE=50\nBOND_TOPK_FINAL=20\n\n# Optional: Disable LLM stages for retrieval-only mode\n# BOND_RETRIEVAL_ONLY=1\n```\n\n### Using Published Encoders\n\n- Hugging Face model: `pankajrajdeo/bond-embed-v1-fp16`See model card and direct usage: https://huggingface.co/pankajrajdeo/bond-embed-v1-fp16\n- Ollama model: `rajdeopankaj/bond-embed-v1-fp16`\n  Pull first, then set `BOND_EMBED_MODEL=ollama:rajdeopankaj/bond-embed-v1-fp16` and (optionally) `OLLAMA_API_BASE`.\n\n> Note: BOND’s embedding provider currently supports LiteLLM-style endpoints and Ollama natively. If you prefer running the Hugging Face model locally with SentenceTransformers, use it to precompute embeddings for your own pipelines; for BOND’s FAISS build and runtime embedding, route the HF model via a LiteLLM-compatible endpoint (e.g., TEI behind a gateway) or use the Ollama variant.\n\n## 📖 Documentation\n\n- [Installation Guide](INSTALLATION.md) - Detailed setup instructions\n- [Roadmap](RoadMap/README.md) - Active project, benchmark, and publication planning\n- [CELLxGENE Benchmark Workspace](benchmarks/cellxgene/README.md) - Rebuild scripts and example inputs\n- [Benchmark Dataset](https://huggingface.co/datasets/AronowLab/bond-czi-benchmark) - Context-aware benchmark for biomedical entity normalization\n\n## 🏗️ Architecture\n\n### Pipeline Overview\n\n```\n┌─────────────────────────────────────────────────┐\n│ STAGE 1: QUERY EXPANSION                        │\n├─────────────────────────────────────────────────┤\n│ LLM generates synonyms, abbreviations,         │\n│ and context-aware expansions                   │\n└─────────────────────────────────────────────────┘\n                     ↓\n┌─────────────────────────────────────────────────┐\n│ STAGE 2: HYBRID RETRIEVAL                      │\n├─────────────────────────────────────────────────┤\n│ • Exact Match (SQLite FTS) → Top-K             │\n│ • BM25 Search (SQLite FTS) → Top-K             │\n│ • Dense Search (FAISS) → Top-K                │\n└─────────────────────────────────────────────────┘\n                     ↓\n┌─────────────────────────────────────────────────┐\n│ STAGE 3: RECIPROCAL RANK FUSION                │\n├─────────────────────────────────────────────────┤\n│ Combine rankings from all methods using RRF    │\n│ with field-aware weighting                     │\n└─────────────────────────────────────────────────┘\n                     ↓\n┌─────────────────────────────────────────────────┐\n│ STAGE 4: CROSS-ENCODER RERANKER                │\n├─────────────────────────────────────────────────┤\n│ Re-rank top candidates using fine-tuned        │\n│ biomedical reranker model (bioformer-16L)      │\n│ Improves accuracy by 10-15%                    │\n└─────────────────────────────────────────────────┘\n                     ↓\n┌─────────────────────────────────────────────────┐\n│ STAGE 5: GRAPH EXPANSION (Optional)            │\n├─────────────────────────────────────────────────┤\n│ Expand ontology neighbors if confidence low    │\n└─────────────────────────────────────────────────┘\n                     ↓\n┌─────────────────────────────────────────────────┐\n│ STAGE 6: LLM DISAMBIGUATION                    │\n├─────────────────────────────────────────────────┤\n│ LLM selects best match from candidates with    │\n│ reasoning and confidence scoring                │\n└─────────────────────────────────────────────────┘\n```\n\n### Key Components\n\n- **`bond/pipeline.py`**: Core `BondMatcher` class implementing the full pipeline\n- **`bond/retrieval/`**: Retrieval modules (BM25, FAISS)\n- **`bond/fusion.py`**: Reciprocal rank fusion implementation\n- **`bond/rerank.py`**: Cross-encoder reranker integration (loads and applies fine-tuned reranker model)\n- **`bond/graph_utils.py`**: Ontology graph traversal\n- **`bond/server.py`**: FastAPI REST service\n- **`bond/cli.py`**: Command-line interface\n- **`bond/service.py`**: Shared service layer for API, CLI, and MCP-style workflows\n- **`bond/mcp_server.py`**: BOND MCP server\n\n## 📊 Benchmark Dataset\n\nBOND includes a comprehensive, context-aware benchmark dataset derived from CELLxGENE metadata:\n\n- **25,416 normalization pairs** across 7 field types (cell_type, tissue, disease, assay, sex, development_stage, self_reported_ethnicity)\n- **85 high-quality datasets** from CELLxGENE Census (72 single-cell, 13 spatial)\n- **186 unique tissues** across _Homo sapiens_ and _Mus musculus_\n- **Dataset-level grouped splits with zero dataset_id overlap**: 20,342 train / 2,233 validation / 2,841 test\n\nUnlike traditional string-matching benchmarks, BOND requires **reasoning over biological context**—including tissue, disease, organism, and development stage information—to accurately map author-provided annotations to standardized ontology labels.\n\n**Dataset**: [AronowLab/bond-czi-benchmark](https://huggingface.co/datasets/AronowLab/bond-czi-benchmark)\n\nThe canonical local release is generated under `BOND_Paper/Benchmark/Release/` by:\n\n```bash\npython BOND_Paper/Benchmark/prepare_release.py --force\n```\n\nThe release includes `leakage_audit.md` and `leakage_audit.json`, which report dataset, author term, ontology ID, and field distribution overlap. The required leakage criterion is zero `dataset_id` overlap across train, validation, and test.\n\n### Usage\n\n```python\nfrom datasets import load_dataset\n\ndataset = load_dataset(\"AronowLab/bond-czi-benchmark\")\n\n# Access splits\ntrain = dataset[\"train\"]\nval = dataset[\"validation\"]\ntest = dataset[\"test\"]\n\n# Example\nsample = train[0]\nprint(f\"Input: {sample['author_term']}\")\nprint(f\"Context: {sample['tissue']}, {sample['disease']}\")\nprint(f\"Target: {sample['ontology_label']} ({sample['ontology_id']})\")\n```\n\n## 🔬 Evaluation\n\nBOND has been evaluated on the BOND-CZI benchmark dataset (25,416 pairs from 85 datasets). Existing submitted metrics were generated before the canonical dataset-level grouped release and should be rerun before making final revision claims. Performance highlights from the original evaluation include:\n\n- **Embedding Model**: Custom fine-tuned encoder (`bond-embed-v1-fp16`) achieves **92.7% accuracy@10** on ontology evaluation\n- **Hybrid Retrieval**: Combines exact match, BM25, and dense semantic search with Reciprocal Rank Fusion\n- **Cross-Encoder Reranker**: Fine-tuned biomedical reranker (`bioformers/bioformer-16L`) improves Hit@10 accuracy from ~75-80% (retrieval only) to **85-90%** (with reranker)\n- **LLM Disambiguation**: Uses large language models for context-aware term selection\n- **Multi-field Support**: Handles 7 biological field types (cell_type, tissue, disease, etc.) across 5 organisms\n\nOld submitted evaluation artifacts are archived under `archive/legacy/bond_paper_evals/`. Revised metrics must be regenerated from the current grouped release before making final claims.\n\n## 🔄 Current Work\n\nActive development and research efforts:\n\n- **Harmonized Knowledge Graph**: Building a harmonized transcriptomic knowledge graph from BOND-normalized metadata to enable advanced querying, cross-dataset analysis, and relationship discovery in single-cell transcriptomics data.\n\n## 🛠️ Development\n\n### Running Tests\n\n```bash\nmake test\n# or\npytest\n```\n\n### Code Quality\n\n```bash\nmake lint\n# or\nruff check .\nblack .\n```\n\n### Building FAISS Index\n\n```bash\nbond-build-faiss \\\n  --sqlite_path assets/snapshots/bond-ontology-current/ontologies.sqlite \\\n  --assets_path assets/snapshots/bond-ontology-current\n```\n\n### Generating Ontology Database\n\n```bash\nbond-generate-sqlite\n```\n\n## 📝 Citation\n\nIf you use BOND in your research, please cite:\n\n**BOND System:**\n\n```bibtex\n@software{bond_2026,\n  title={BOND: Biomedical Ontology Normalization and Disambiguation},\n  author={Rajdeo, Pankaj and Gelal, Rupesh},\n  year={2026},\n  url={https://github.com/Aronow-Lab/BOND}\n}\n```\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n---\n\n- **Repository**: [github.com/Aronow-Lab/BOND](https://github.com/Aronow-Lab/BOND)\n- **Benchmark Dataset**: [huggingface.co/datasets/AronowLab/bond-czi-benchmark](https://huggingface.co/datasets/AronowLab/bond-czi-benchmark)\n- **Reranker Model**: [huggingface.co/AronowLab/BOND-reranker](https://huggingface.co/AronowLab/BOND-reranker)\n- **Authors**: [Pankaj Rajdeo](https://github.com/pankajrajdeo), [Rupesh Gelal](https://github.com/rgrupesh)\n"}