# How to Add Custom Documentation Sources to Context Hub: A Complete Guide

> Learn to add custom documentation sources to Context Hub by configuring local directories or remote CDN URLs in your config.yaml. Enhance your knowledge base effortlessly.

- Repository: [Andrew Ng/context-hub](https://github.com/andrewyng/context-hub)
- Tags: how-to-guide
- Published: 2026-03-20

---

**Add custom documentation sources to Context Hub by defining them in `~/.chub/config.yaml` and pointing to either a local directory containing a built registry or a remote CDN URL.**

Context Hub is an open-source knowledge management system developed by Andrew Ng's team (andrewyng/context-hub) that aggregates documentation and skills from multiple sources. While it ships with public registries, organizations often need to add custom documentation sources to Context Hub to incorporate private APIs, internal wikis, or proprietary knowledge bases.

## Understanding the Source Configuration System

Context Hub loads its knowledge base from **one or more "sources"** defined in the user-level configuration file. The system distinguishes between remote sources (CDN URLs) and local sources (filesystem paths).

In [`cli/src/lib/config.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/lib/config.js), the `loadConfig()` function (lines 25-48) reads `~/.chub/config.yaml` and constructs the `config.sources` array. Each source object must include:

- **`name`**: A unique identifier for the source
- **`url`**: For remote CDN-hosted registries
- **`path`**: For local directory-based registries

## Building a Custom Documentation Registry

Before you can add custom documentation sources to Context Hub, you must build a valid registry from your content files.

### Step 1: Prepare Your Content Structure

Organize your Markdown files with front-matter in a directory tree. Each documentation entry should include a [`DOC.md`](https://github.com/andrewyng/context-hub/blob/main/DOC.md) file with metadata:

```yaml
---
id: mycompany/internal-api
title: Internal API Reference
description: Authentication and endpoints for internal services
---

```

### Step 2: Generate the Registry

Use the CLI build command to compile your content into a Context Hub-compatible registry:

```bash
chub build my-content/ -o .chub-local/

```

This command, implemented in [`cli/src/commands/build.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/commands/build.js), generates three critical files in the output directory:

- **[`registry.json`](https://github.com/andrewyng/context-hub/blob/main/registry.json)**: The main registry containing all entries and metadata
- **[`search-index.json`](https://github.com/andrewyng/context-hub/blob/main/search-index.json)**: Optimized search index for fast queries
- **[`meta.json`](https://github.com/andrewyng/context-hub/blob/main/meta.json)**: Version and configuration metadata

## Configuring Multiple Sources in Context Hub

Once you have built your local registry, you must register it in the Context Hub configuration to add custom documentation sources alongside public ones.

### Editing the Configuration File

Modify `~/.chub/config.yaml` to include your custom source:

```yaml
sources:
  - name: community
    url: https://cdn.aichub.org/v1
  - name: internal
    path: /home/you/.chub-local
source: community,internal

```

The `source:` field controls which sources are trusted for lookups. When you add custom documentation sources to Context Hub, including them in this list ensures they are available for search and retrieval operations.

## How Context Hub Merges Multiple Sources

In [`cli/src/lib/registry.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/lib/registry.js), the `getMerged()` function (lines 97-112) handles the aggregation of all configured sources:

1. **Iterates** over `config.sources`
2. **Calls** `loadSourceRegistry(source)` for each entry to read its [`registry.json`](https://github.com/andrewyng/context-hub/blob/main/registry.json)
3. **Tags** every document with `_source` (the source name) and `_sourceObj` (the full source configuration)
4. **Caches** the merged result in `_merged` for subsequent lookups

The `isMultiSource()` helper (lines 107-110) returns `true` when `config.sources.length > 1`, enabling the CLI to display source labels for entries with colliding IDs (e.g., `internal:openai/chat`).

## Accessing Custom Documentation

After you add custom documentation sources to Context Hub, you can query them using standard CLI commands:

### Search Across All Sources

```bash
chub search "authentication"

```

This searches both the public CDN and your internal registry simultaneously.

### Retrieve Specific Entries

```bash
chub get internal:mycompany/internal-api

```

If the ID is unique across all sources, you can omit the source prefix:

```bash
chub get mycompany/internal-api

```

## Summary

- **Configuration**: Define custom sources in `~/.chub/config.yaml` with `name` and either `url` (remote) or `path` (local) attributes.
- **Building**: Use `chub build <input> -o <output>` to generate [`registry.json`](https://github.com/andrewyng/context-hub/blob/main/registry.json), [`search-index.json`](https://github.com/andrewyng/context-hub/blob/main/search-index.json), and [`meta.json`](https://github.com/andrewyng/context-hub/blob/main/meta.json) from Markdown content.
- **Merging**: Context Hub automatically merges all configured sources via `getMerged()` in [`cli/src/lib/registry.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/lib/registry.js), tagging entries with their origin.
- **Usage**: Access custom documentation using source-prefixed IDs (`internal:doc-id`) or search across all sources simultaneously.

## Frequently Asked Questions

### How do I structure my local documentation directory for Context Hub?

Create a nested directory structure where each documentation entry resides in its own folder containing a [`DOC.md`](https://github.com/andrewyng/context-hub/blob/main/DOC.md) file with YAML front-matter. The front-matter must include an `id`, `title`, and `description`. You can also include a `references/` subdirectory for related Markdown files. Run `chub build` pointing to the parent directory to compile everything into a valid registry.

### Can I mix remote CDN sources with local custom sources?

Yes. Context Hub supports hybrid configurations. In `~/.chub/config.yaml`, define some sources with `url` pointing to CDN endpoints and others with `path` pointing to local directories. The `getMerged()` function in [`cli/src/lib/registry.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/lib/registry.js) loads and combines all sources regardless of their origin, tagging each entry with its `_source` attribute so you can distinguish between them.

### What happens if two sources define the same document ID?

When multiple sources contain identical IDs, Context Hub enters multi-source mode (detected by `isMultiSource()` in [`cli/src/lib/registry.js`](https://github.com/andrewyng/context-hub/blob/main/cli/src/lib/registry.js)). You must use the source prefix syntax to disambiguate: `chub get sourcename:document-id`. The CLI will display the source label for colliding entries, ensuring you retrieve the correct documentation from your custom or public sources.

### Is there a performance penalty for adding multiple custom sources?

Context Hub caches the merged registry in memory after the first call to `getMerged()`, so subsequent lookups are fast. However, initial startup time increases slightly with each additional source because `loadSourceRegistry()` must read and parse each [`registry.json`](https://github.com/andrewyng/context-hub/blob/main/registry.json) file. Local file system sources generally load faster than remote CDN sources, which require network round-trips.