Skip to content
Back to skills

1771 Storage Architecture Mongodb Documentdb 0b595b60

BSecurity

**Status:** Current Implementation **Last Updated:** January 30, 2026 **Target Audience:** Developers, DevOps Engineers, System Architects

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
devopspythongobashnodedockerawsterraformtestinggitapi

Works with

  • cli
  • api
  • mcp

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1771-storage-architecture-mongodb-documentdb_0b595b60 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1771 Storage Architecture Mongodb Documentdb 0b595b60?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1771 Storage Architecture Mongodb Documentdb 0b595b60
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1771-storage-architecture-mongodb-documentdb-0b595/badge)](https://www.skillsdirectory.com/skills/tools-only-1771-storage-architecture-mongodb-documentdb-0b595)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Storage Architecture: MongoDB CE & AWS DocumentDB

**Status:** Current Implementation
**Last Updated:** January 30, 2026
**Target Audience:** Developers, DevOps Engineers, System Architects

## Table of Contents

1. [Overview](#overview)
2. [Storage Backend Options](#storage-backend-options)
3. [MongoDB CE Local Development](#mongodb-ce-local-development)
4. [AWS DocumentDB Production](#aws-documentdb-production)
5. [Vector Search Implementation](#vector-search-implementation)
6. [Build and Run Process](#build-and-run-process)
7. [Repository Architecture](#repository-architecture)
8. [Configuration](#configuration)
9. [Migration Strategy](#migration-strategy)

## Overview

The MCP Gateway Registry supports three storage backends for data persistence:

1. **File-Based Backend** (Legacy) - JSON/YAML files with FAISS
2. **MongoDB CE** (Local Development) - MongoDB Community Edition 8.2 with application-level vector search
3. **AWS DocumentDB** (Production) - MongoDB-compatible service with native vector search

This document focuses on the MongoDB and DocumentDB backends, which provide production-grade distributed storage with semantic search capabilities.

### Architecture Diagram

```
┌─────────────────────────────────────────────────────────────┐
│                   Application Layer                          │
│             (Services, API Endpoints)                        │
└────────────────────┬────────────────────────────────────────┘
                     │ depends on
                     ▼
┌─────────────────────────────────────────────────────────────┐
│              Repository Factory Layer                        │
│  get_server_repository()                                    │
│  get_search_repository()                                    │
│  etc.                                                       │
└────────┬──────────────────────┬──────────────┬─────────────┘
         │                      │              │
         │ STORAGE_BACKEND=     │              │
         │ file / mongodb-ce /  │              │
         │ documentdb           │              │
         ▼                      ▼              ▼
┌──────────────────┐  ┌─────────────────┐  ┌──────────────────┐
│ File Backend     │  │ MongoDB CE      │  │ AWS DocumentDB   │
├──────────────────┤  ├─────────────────┤  ├──────────────────┤
│ FileServerRepo   │  │ DocumentDBRepo  │  │ DocumentDBRepo   │
│ FaissSearch      │  │ + App-level     │  │ + Native         │
│                  │  │   vector search │  │   vector search  │
└──────────────────┘  └─────────────────┘  └──────────────────┘
         │                      │                     │
         ▼                      ▼                     ▼
    Local Files        Local MongoDB CE     AWS DocumentDB
   (JSON + FAISS)        (Docker)           (Managed Service)
```

---

## Storage Backend Options

### Comparison Matrix

| Aspect | File | MongoDB CE | AWS DocumentDB |
|--------|------|------------|----------------|
| **Use Case** | Dev/Testing | Local Development | Production |
| **Scalability** | ~1000 entities | 10,000s | Millions |
| **Vector Search** | FAISS (app-level) | App-level (Python) | Native (HNSW) |
| **Setup Complexity** | None | Docker Compose | Terraform/AWS |
| **Concurrency** | Limited | Good | Excellent |
| **HA/Clustering** | No | Manual | Automatic |
| **Cost** | Free | Free | AWS Pricing |
| **Best For** | Quick start | Feature development | Production deployments |

---

## MongoDB CE Local Development

### Architecture

MongoDB Community Edition 8.2 provides a local development environment that mimics production DocumentDB behavior without requiring AWS infrastructure.

#### Key Components

1. **MongoDB 8.2 Container** (`mongo:8.2`)
   - Runs in Docker Compose
   - Configured as replica set (`rs0`) for transaction support
   - No authentication for local development simplicity
   - Bind address: `127.0.0.1,mongodb`

2. **Application-Level Vector Search**
   - Python-based cosine similarity computation
   - Embeddings stored in `mcp_embeddings_1536_default` collection
   - Full scan with in-memory ranking for search queries
   - Isolated in `DocumentDBSearchRepository` class

3. **Collections**
   - `mcp_servers_{namespace}` - Server definitions
   - `mcp_agents_{namespace}` - Agent cards
   - `mcp_scopes_{namespace}` - Authorization scopes
   - `mcp_embeddings_1536_{namespace}` - Vector embeddings
   - `mcp_security_scans_{namespace}` - Security scan results
   - `mcp_federation_config_{namespace}` - Federation settings

### Vector Search Implementation (MongoDB CE)

Since MongoDB CE 8.2 doesn't include the separate `mongot` search component needed for native vector search, we implement semantic search at the application layer.

#### Search Flow

```python
# 1. Query arrives
query = "financial analysis tools"

# 2. Generate query embedding
model = create_embeddings_client(...)
query_embedding = model.encode([query])[0]  # [1536 dimensions]

# 3. Retrieve all embeddings from MongoDB
docs = await collection.find({"entity_type": "mcp_server"}).to_list(length=1000)

# 4. Calculate cosine similarity in Python
for doc in docs:
    doc_embedding = doc["embedding"]  # [1536 dimensions]
    score = cosine_similarity(query_embedding, doc_embedding)
    doc["relevance_score"] = score

# 5. Rank results by similarity
results = sorted(docs, key=lambda x: x["relevance_score"], reverse=True)

# 6. Apply text-based boosting (hybrid search)
# If query appears in name or description, add bonus points
for result in results:
    if query.lower() in result["name"].lower():
        result["relevance_score"] += 0.1  # Name match bonus
    if query.lower() in result["description"].lower():
        result["relevance_score"] += 0.05  # Description match bonus

# 7. Return top-k results
return results[:max_results]
```

#### Code Location

**File:** `registry/repositories/documentdb/search_repository.py`

**Key Methods:**

```python
class DocumentDBSearchRepository:
    async def search(
        self,
        query: str,
        entity_types: Optional[List[str]] = None,
        max_results: int = 10,
    ) -> Dict[str, List[Dict[str, Any]]]:
        """Hybrid search with application-level vector similarity."""
        # Lines 240-385: Full implementation

    def _calculate_cosine_similarity(
        self,
        vec1: List[float],
        vec2: List[float]
    ) -> float:
        """Calculate cosine similarity between two vectors."""
        # Lines 199-220: Pure Python implementation
        # Returns value between 0 and 1 (1 = identical)
```

#### Performance Characteristics

- **Pros:**
  - No dependency on external search services
  - Works identically to production DocumentDB (same code path)
  - Full control over ranking algorithm
  - No additional containers needed

- **Cons:**
  - O(n) full collection scan for every search query
  - All embeddings loaded into memory for comparison
  - Not suitable for >10,000 entities
  - No index optimization (brute force)

- **Optimization:**
  - For local dev with <1,000 entities, performance is acceptable (<100ms)
  - Production workloads should use AWS DocumentDB with native vector search

### Docker Compose Configuration

**File:** `docker-compose.yml` (lines 59-77)

```yaml
mongodb:
  image: mongo:8.2
  container_name: mcp-mongodb
  command: mongod --replSet rs0 --bind_ip 127.0.0.1,mongodb
  ports:
    - "27017:27017"
  volumes:
    - mongodb-data:/data/db
    - mongodb-config:/data/configdb
  healthcheck:
    test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
    interval: 10s
    timeout: 5s
    retries: 5
    start_period: 20s
  restart: unless-stopped
```

**Key Settings:**

- **Replica Set:** `--replSet rs0` enables transactions (required for DocumentDB compatibility)
- **Bind Address:** `127.0.0.1,mongodb` - listens on localhost and container network
- **No Authentication:** Simplifies local development (not for production!)
- **Healthcheck:** Ensures container is ready before dependent services start

### Initialization

**Script:** `scripts/init-mongodb-ce.py`

**What It Does:**

1. **Initializes Replica Set**
   ```python
   # Initialize rs0 replica set (required for transactions)
   config = {
       "_id": "rs0",
       "members": [{"_id": 0, "host": "mongodb:27017"}]
   }
   client.admin.command("replSetInitiate", config)
   ```

2. **Creates Collections**
   - Server registry (`mcp_servers_default`)
   - Agent registry (`mcp_agents_default`)
   - Authorization scopes (`mcp_scopes_default`)
   - Vector embeddings (`mcp_embeddings_1536_default` - 1536 dimensions for OpenAI/Titan)
   - Security scans (`mcp_security_scans_default`)
   - Federation config (`mcp_federation_config_default`)

3. **Creates Indexes** for query performance
   ```python
   # Server indexes
   await collection.create_index([("path", ASCENDING)], unique=True)
   await collection.create_index([("enabled", ASCENDING)])
   await collection.create_index([("tags", ASCENDING)])

   # Embeddings indexes
   await collection.create_index([("path", ASCENDING)], unique=True)
   await collection.create_index([("entity_type", ASCENDING)])
   ```

4. **Loads OAuth Scopes** from `auth_server/scopes.yml`
   ```python
   # Reads scopes.yml and populates mcp_scopes_default collection
   # Includes server scopes and group mappings
   await _load_scopes_from_yaml(db, namespace, scopes_file)
   ```

5. **Note on Vector Index**
   - MongoDB CE 8.2 does not include native vector search (requires `mongot` component)
   - Vector search is implemented at application level using Python cosine similarity
   - See `registry/repositories/documentdb/search_repository.py` for implementation

### Environment Variables

**File:** `.env.example` (lines 360-386)

```bash
# Storage backend selection
STORAGE_BACKEND=mongodb-ce  # Use MongoDB CE local instance

# DocumentDB Configuration (reused for MongoDB CE)
DOCUMENTDB_HOST=mongodb  # Docker Compose service name
DOCUMENTDB_PORT=27017
DOCUMENTDB_DATABASE=mcp_registry
DOCUMENTDB_NAMESPACE=default

# No authentication needed for local MongoDB CE
# DOCUMENTDB_USERNAME and DOCUMENTDB_PASSWORD not required
# DOCUMENTDB_USE_TLS=false (disabled for local)
```

---

## AWS DocumentDB Production

### Architecture

AWS DocumentDB is a MongoDB-compatible managed database service optimized for cloud deployments with native vector search support.

#### Key Components

1. **DocumentDB Cluster**
   - Managed by AWS
   - Multi-AZ deployment for high availability
   - Auto-scaling read replicas
   - Automated backups and point-in-time recovery

2. **Native Vector Search**
   - HNSW (Hierarchical Navigable Small World) algorithm
   - Index-based approximate nearest neighbor (ANN)
   - Sub-100ms query times even with millions of vectors
   - Cosine similarity metric

3. **Network Architecture**
   - Private VPC deployment
   - TLS encryption in transit
   - VPC security groups for access control

### Vector Search Implementation (DocumentDB)

AWS DocumentDB provides native vector search using optimized indexes, eliminating the need for application-level computation.

#### Search Flow

```python
# 1. Query arrives
query = "financial analysis tools"

# 2. Generate query embedding (same as MongoDB CE)
query_embedding = model.encode([query])[0]

# 3. DocumentDB performs indexed vector search with tuned parameters
ef_search = settings.vector_search_ef_search  # Default: 100
k_value = max(max_results * 3, 50)            # At least 50 for small collections
pipeline = [
    {
        "$search": {
            "vectorSearch": {
                "vector": query_embedding,
                "path": "embedding",
                "similarity": "cosine",
                "k": k_value,
                "efSearch": ef_search,
            }
        }
    }
]

# 4. DocumentDB returns sorted results (FAST - uses HNSW index)
# Results are already ranked by vector similarity

# 5. Apply text-based boosting in aggregation pipeline
#    Each query keyword is matched independently against path, name,
#    description, tags, and tool names/descriptions
pipeline.append({
    "$addFields": {
        "text_boost": {
            "$add": [
                # Per keyword: path(+5), name(+3), description(+2), tags(+1.5)
                {"$cond": [{"$regexMatch": {"input": "$path", "regex": keyword, "options": "i"}}, 5.0, 0.0]},
                {"$cond": [{"$regexMatch": {"input": "$name", "regex": keyword, "options": "i"}}, 3.0, 0.0]},
                {"$cond": [{"$regexMatch": {"input": "$description", "regex": keyword, "options": "i"}}, 2.0, 0.0]},
                # ... plus tags (+1.5) and each tool (+1.0)
            ]
        }
    }
})

# 6. Score combination: normalized_vector + (text_boost * 0.1)
# All candidates scored, sorted by hybrid score, then top-3 per entity type

# 7. Execute aggregation pipeline
results = await collection.aggregate(pipeline).to_list(k_value)
```

#### Code Location

**File:** `registry/repositories/documentdb/search_repository.py`

**The same code works for both MongoDB CE and AWS DocumentDB!**

The key difference:
- **MongoDB CE:** No vector index → slow full scan
- **DocumentDB:** HNSW vector index → fast indexed search

The application code is identical, but DocumentDB executes it much faster.

#### Performance Characteristics

- **Pros:**
  - O(log n) indexed search via HNSW
  - Handles millions of vectors efficiently
  - Sub-100ms latency even with large datasets
  - Native database operation (no network round trips)
  - Automatic index optimization

- **Cons:**
  - Requires AWS infrastructure
  - Additional cost for managed service
  - Network latency to AWS region

- **Optimization:**
  - HNSW parameters tuned for accuracy vs. speed tradeoff
  - `m=16, efConstruction=128` provides good balance for index construction
  - `efSearch=100` (configurable) provides near-exact recall for typical deployments
  - Minimum `k=50` ensures small collections are fully covered
  - Can adjust via `VECTOR_SEARCH_EF_SEARCH` environment variable

### Terraform Configuration

**Directory:** `terraform/aws-ecs/`

**Key Resources:**

1. **DocumentDB Cluster** (`modules/documentdb/main.tf`)
   ```hcl
   resource "aws_docdb_cluster" "main" {
     cluster_identifier      = "mcp-registry-${var.environment}"
     engine                  = "docdb"
     master_username         = var.master_username
     master_password         = var.master_password

     # High availability
     backup_retention_period = 7
     preferred_backup_window = "03:00-04:00"

     # Security
     storage_encrypted       = true
     kms_key_id             = aws_kms_key.docdb.arn

     # Network
     db_subnet_group_name    = aws_docdb_subnet_group.main.name
     vpc_security_group_ids  = [aws_security_group.docdb.id]
   }
   ```

2. **DocumentDB Instance(s)** (read/write nodes)
   ```hcl
   resource "aws_docdb_cluster_instance" "main" {
     count              = var.instance_count
     identifier         = "mcp-registry-${var.environment}-${count.index}"
     cluster_identifier = aws_docdb_cluster.main.id
     instance_class     = var.instance_class  # db.r5.large, db.r6g.xlarge, etc.
   }
   ```

3. **Vector Search Configuration**
   - Automatically enabled on DocumentDB 5.0+
   - No additional configuration needed
   - HNSW index created via application init script

### Environment Variables (Production)

**File:** `.env` (not in git)

```bash
# Storage backend
STORAGE_BACKEND=documentdb  # Use AWS DocumentDB

# DocumentDB connection
DOCUMENTDB_HOST=mcp-registry-prod.cluster-xxxxx.us-east-1.docdb.amazonaws.com
DOCUMENTDB_PORT=27017
DOCUMENTDB_DATABASE=mcp_registry
DOCUMENTDB_USERNAME=mcp_admin
DOCUMENTDB_PASSWORD=<secure-password-from-secrets-manager>

# Security settings
DOCUMENTDB_USE_TLS=true
DOCUMENTDB_TLS_CA_FILE=/app/global-bundle.pem  # AWS DocumentDB CA bundle
DOCUMENTDB_USE_IAM=false  # Set to true for IAM authentication

# Replica set configuration
DOCUMENTDB_REPLICA_SET=rs0
DOCUMENTDB_READ_PREFERENCE=secondaryPreferred  # Distribute read load

# Namespace for multi-tenancy
DOCUMENTDB_NAMESPACE=production
```

---

## Vector Search Implementation

### Overview

Vector search enables semantic search - finding conceptually similar servers and agents even when exact keywords don't match.

**Example:**

```
Query: "financial analytics"
Matches:
  ✓ "Stock market analysis tools" (85% similarity)
  ✓ "Portfolio management assistant" (78% similarity)
  ✗ "Weather forecast service" (12% similarity)
```

### Embedding Generation

**Module:** `registry/embeddings/`

**Providers:**

1. **Sentence Transformers** (Default, Local)
   - Model: `all-MiniLM-L6-v2`
   - Dimensions: 384
   - Runs locally, no API costs

2. **LiteLLM** (Cloud, via API)
   - OpenAI: `text-embedding-ada-002` (1536 dims)
   - Amazon Bedrock Titan: `amazon.titan-embed-text-v1` (1536 dims)
   - Cohere: `embed-english-v3.0` (1024 dims)

**Configuration:**

```bash
# Local embeddings
EMBEDDINGS_PROVIDER=sentence-transformers
EMBEDDINGS_MODEL_NAME=all-MiniLM-L6-v2
EMBEDDINGS_MODEL_DIMENSIONS=384

# OR Cloud embeddings (OpenAI)
EMBEDDINGS_PROVIDER=litellm
EMBEDDINGS_MODEL_NAME=openai/text-embedding-ada-002
EMBEDDINGS_MODEL_DIMENSIONS=1536
EMBEDDINGS_API_KEY=sk-...

# OR Amazon Bedrock
EMBEDDINGS_PROVIDER=litellm
EMBEDDINGS_MODEL_NAME=bedrock/amazon.titan-embed-text-v1
EMBEDDINGS_MODEL_DIMENSIONS=1536
EMBEDDINGS_AWS_REGION=us-east-1
```

### Embedding Storage

**Collection:** `mcp_embeddings_{dimensions}_{namespace}`

**Document Structure:**

```json
{
  "_id": "/servers/financial-data",
  "entity_type": "mcp_server",
  "path": "/servers/financial-data",
  "name": "Financial Data Server",
  "description": "Provides stock market data and analysis tools",
  "tags": ["finance", "data", "stocks"],
  "is_enabled": true,
  "text_for_embedding": "Financial Data Server. Provides stock market data and analysis tools. Tools: get_stock_price, analyze_portfolio, market_trends",
  "embedding": [0.125, -0.342, 0.098, ...],  // 1536 floats
  "embedding_metadata": {
    "model": "amazon.titan-embed-text-v1",
    "provider": "litellm",
    "dimensions": 1536,
    "created_at": "2026-01-03T10:30:00Z"
  },
  "tools": [
    {"name": "get_stock_price", "description": "Get current stock price"},
    {"name": "analyze_portfolio", "description": "Analyze investment portfolio"}
  ],
  "metadata": { /* full server info */ },
  "indexed_at": "2026-01-03T10:30:00Z"
}
```

### Search Algorithm Comparison

#### MongoDB CE (Application-Level)

```python
# File: registry/repositories/documentdb/search_repository.py

async def search(self, query: str, max_results: int = 10):
    # 1. Generate query embedding
    query_embedding = model.encode([query])[0]

    # 2. Fetch ALL documents (full scan)
    docs = await collection.find({}).to_list(length=10000)

    # 3. Calculate similarity for each document
    for doc in docs:
        doc["score"] = cosine_similarity(query_embedding, doc["embedding"])

    # 4. Sort by score (in Python)
    ranked = sorted(docs, key=lambda x: x["score"], reverse=True)

    # 5. Return top-k
    return ranked[:max_results]
```

**Time Complexity:** O(n) - must compare against every document
**Latency:** ~50-200ms for 1,000 documents
**Scalability:** Limited to ~10,000 documents

#### DocumentDB (Native Vector Search)

```python
# File: registry/repositories/documentdb/search_repository.py

async def search(self, query: str, max_results: int = 10):
    # 1. Generate query embedding
    query_embedding = model.encode([query])[0]

    # 2. DocumentDB HNSW index search with tuned parameters
    ef_search = settings.vector_search_ef_search  # Default: 100
    k_value = max(max_results * 3, 50)
    pipeline = [{
        "$search": {
            "vectorSearch": {
                "vector": query_embedding,
                "path": "embedding",
                "similarity": "cosine",
                "k": k_value,
                "efSearch": ef_search,
            }
        }
    }]

    # 3. DocumentDB returns sorted results (FAST!)
    results = await collection.aggregate(pipeline).to_list(k_value)

    # 4. Score all results, sort by hybrid score, pick top-3 per entity type
    return results
```

**Time Complexity:** O(log n) - HNSW index lookup
**Latency:** ~10-50ms for millions of documents
**Scalability:** Millions of documents

### Search Resilience: Lexical Fallback

Both backends support automatic fallback to lexical-only search when the embedding model is unavailable. This ensures search remains operational even during embedding provider outages, misconfiguration, or API key expiration.

**Behavior when embeddings are unavailable:**

- Servers and agents are indexed without embeddings (empty vectors)
- DocumentDB rejects 0-dimension vectors, so documents are stored without vector data
- Search uses MongoDB aggregation with `$regexMatch` for keyword matching on path, name, description, tags, and tools
- The `_load_error` cache in `SentenceTransformersClient` prevents repeated model download attempts
- API response includes `"search_mode": "lexical-only"` to indicate degraded mode

**Recovery:** Restart the service with correct embedding configuration. The error cache resets on restart and search returns to full hybrid mode.

See [Hybrid Search Architecture](hybrid-search-architecture.md) for detailed fallback flow and scoring.

### Hybrid Search (Text + Vector)

Both backends support hybrid search combining:
- **Vector similarity** (semantic matching)
- **Text matching** (keyword boosting)

**Example:**

```python
# Query: "stock market"
results = [
    {
        "name": "Financial Analysis Server",
        "vector_score": 0.85,         # Cosine similarity
        "normalized_vector": 0.925,   # (0.85 + 1.0) / 2.0
        "text_boost": 3.0,            # "market" found in name
        "boost_contrib": 0.30,        # 3.0 * 0.1
        "final_score": 1.0            # clamped to 1.0
    },
    {
        "name": "Investment Tools",
        "vector_score": 0.75,         # Cosine similarity
        "normalized_vector": 0.875,   # (0.75 + 1.0) / 2.0
        "text_boost": 0.0,            # No keyword match
        "boost_contrib": 0.0,
        "final_score": 0.875
    }
]
```

**Formula:**

```
normalized_vector = (cosine_similarity + 1.0) / 2.0   # Map [-1,1] to [0,1]
boost_contribution = text_boost * 0.1                   # Scale boost down
final_score = clamp(normalized_vector + boost_contribution, 0.0, 1.0)
```

The `0.1` multiplier is consistent across both DocumentDB and MongoDB CE search paths. Semantic relevance is primary (normalized vector score dominates) while keyword matches provide a meaningful boost for exact references.

---

## Build and Run Process

### Local Development with MongoDB CE

**Script:** `build_and_run.sh`

#### Flow

```
1. Load .env file
   └─> Check STORAGE_BACKEND variable

2. If STORAGE_BACKEND = mongodb-ce or documentdb:
   └─> Create empty directories for Docker mounts
   └─> (Data stored in MongoDB, not local files)

3. Start Docker Compose
   ├─> Start MongoDB container
   │   └─> Wait for healthcheck to pass
   ├─> Run mongodb-init container
   │   ├─> Initialize replica set
   │   ├─> Create collections
   │   └─> Create indexes
   └─> Start application services

4. Application startup
   ├─> Repository factory creates DocumentDBRepository instances
   ├─> Search repository initializes
   │   └─> Creates vector index if not exists (DocumentDB only)
   └─> Services load data from MongoDB
```

#### Key Script Logic

**File:** `build_and_run.sh` (lines 180-298)

```bash
# Build and run script always creates mount directories
# and copies JSON files for all backends
# (MongoDB/DocumentDB stores data in database, files are for initial seeding)

# Create mount directories
mkdir -p "$MCPGATEWAY_SERVERS_DIR"
mkdir -p "${HOME}/mcp-gateway/agents"
mkdir -p "${HOME}/mcp-gateway/auth_server"
mkdir -p "${HOME}/mcp-gateway/security_scans"
touch "${HOME}/mcp-gateway/federation.json"

# Copy server definitions from registry/servers/*.json
# Copy agent cards from cli/examples/*agent*.json
# Copy scopes.yml
# (These provide initial data that can be imported via API)
```

### Starting the Stack

```bash
# 1. Ensure .env is configured
cat .env | grep STORAGE_BACKEND
# Should show: STORAGE_BACKEND=mongodb-ce

# 2. Run build and run script
./build_and_run.sh

# What happens:
# - MongoDB container starts
# - Waits for healthcheck (ping succeeds)
# - Runs init script (replica set + collections)
# - Starts application services
# - Registry connects to MongoDB
# - Search repository creates vector index (if DocumentDB)
```

### Verifying MongoDB CE Setup

```bash
# 1. Check MongoDB is running
docker compose ps mongodb
# Should show: Status = healthy

# 2. Check collections were created
docker exec -it mcp-mongodb mongosh --eval "use mcp_registry; show collections"
# Expected output:
#   mcp_agents_default
#   mcp_embeddings_1536_default
#   mcp_federation_config_default
#   mcp_scopes_default
#   mcp_security_scans_default
#   mcp_servers_default

# 3. Check replica set status
docker exec -it mcp-mongodb mongosh --eval "rs.status()"
# Should show: rs0 with 1 member (primary)

# 4. Verify application can connect
curl http://localhost:7860/health
# Should return: {"status": "healthy"}
```

### Data Flow

```
User Action          →  API Endpoint  →  Service Layer  →  Repository
───────────────────────────────────────────────────────────────────────
Register Server      →  POST /servers →  server_service →  DocumentDBServerRepository
                                                           └─> MongoDB: mcp_servers_default

Search "finance"     →  GET /search   →  search_service →  DocumentDBSearchRepository
                                                           └─> MongoDB: mcp_embeddings_1536_default
                                                               └─> Vector search (app-level)

List Agents          →  GET /agents   →  agent_service  →  DocumentDBAgentRepository
                                                           └─> MongoDB: mcp_agents_default
```

---

## Repository Architecture

### Abstract Base Classes

**File:** `registry/repositories/interfaces.py`

All storage backends implement the same interfaces:

```python
class ServerRepositoryBase(ABC):
    @abstractmethod
    async def get(self, path: str) -> Optional[Dict[str, Any]]: ...

    @abstractmethod
    async def list_all(self) -> Dict[str, Dict[str, Any]]: ...

    @abstractmethod
    async def create(self, server_info: Dict[str, Any]) -> bool: ...
```

### Factory Pattern

**File:** `registry/repositories/factory.py`

```python
def get_server_repository() -> ServerRepositoryBase:
    backend = settings.storage_backend

    if backend in ["documentdb", "mongodb-ce"]:
        from .documentdb.server_repository import DocumentDBServerRepository
        return DocumentDBServerRepository()
    else:
        from .file.server_repository import FileServerRepository
        return FileServerRepository()
```

**Key Point:** `mongodb-ce` and `documentdb` use the **same repository implementation**. The only difference is:
- **mongodb-ce:** Connects to local MongoDB container
- **documentdb:** Connects to AWS DocumentDB cluster

The repository code is identical - only the connection string changes!

### Implementation Files

**Directory:** `registry/repositories/documentdb/`

```
documentdb/
├── __init__.py
├── client.py                        # MongoDB/DocumentDB client management
├── server_repository.py             # Server CRUD operations
├── agent_repository.py              # Agent CRUD operations
├── scope_repository.py              # Authorization scopes
├── search_repository.py             # Vector search (app-level OR native)
├── security_scan_repository.py      # Security scan results
└── federation_config_repository.py  # Federation configuration
```

### Client Management

**File:** `registry/repositories/documentdb/client.py`

```python
async def get_documentdb_client() -> AsyncIOMotorDatabase:
    """Get DocumentDB/MongoDB database client.

    Works with both:
    - MongoDB CE (local Docker)
    - AWS DocumentDB (production)

    Configuration via environment variables.
    """
    if _client is None:
        connection_string = _build_connection_string()
        # Example (MongoDB CE):
        # mongodb://mongodb:27017/mcp_registry?replicaSet=rs0

        # Example (DocumentDB):
        # mongodb://user:pass@docdb-cluster.us-east-1.docdb.amazonaws.com:27017/
        #   ?tls=true&tlsCAFile=/app/global-bundle.pem&replicaSet=rs0

        motor_client = AsyncIOMotorClient(connection_string)
        _client = motor_client[settings.documentdb_database]

    return _client

def get_collection_name(base_name: str) -> str:
    """Add namespace suffix to collection name."""
    return f"{base_name}_{settings.documentdb_namespace}"
```

---

## Configuration

### Environment Variables

**File:** `.env`

```bash
# ============================================================================
# STORAGE BACKEND CONFIGURATION
# ============================================================================

# Backend selection
STORAGE_BACKEND=mongodb-ce  # Options: file, mongodb-ce, documentdb

# MongoDB/DocumentDB connection
DOCUMENTDB_HOST=mongodb                    # MongoDB CE: "mongodb"
                                          # DocumentDB: "cluster.us-east-1.docdb.amazonaws.com"
DOCUMENTDB_PORT=27017
DOCUMENTDB_DATABASE=mcp_registry
DOCUMENTDB_NAMESPACE=default              # Multi-tenancy: dev, staging, production

# Authentication (not needed for MongoDB CE local)
DOCUMENTDB_USERNAME=admin                 # DocumentDB: actual username
DOCUMENTDB_PASSWORD=secure_password       # DocumentDB: from Secrets Manager

# TLS/Security (MongoDB CE: disabled, DocumentDB: enabled)
DOCUMENTDB_USE_TLS=false                  # MongoDB CE: false
                                          # DocumentDB: true
DOCUMENTDB_TLS_CA_FILE=global-bundle.pem  # DocumentDB CA bundle
DOCUMENTDB_USE_IAM=false                  # DocumentDB: set true for IAM auth

# Replica set configuration
DOCUMENTDB_REPLICA_SET=rs0
DOCUMENTDB_READ_PREFERENCE=secondaryPreferred  # Load balance reads

# ============================================================================
# EMBEDDINGS CONFIGURATION
# ============================================================================

# Embedding provider
EMBEDDINGS_PROVIDER=sentence-transformers  # Options: sentence-transformers, litellm
EMBEDDINGS_MODEL_NAME=all-MiniLM-L6-v2    # Or: openai/text-embedding-ada-002
EMBEDDINGS_MODEL_DIMENSIONS=384           # Or: 1536 for OpenAI/Titan

# For cloud embeddings
EMBEDDINGS_API_KEY=                       # OpenAI: sk-...
                                          # Bedrock: uses IAM (leave empty)
EMBEDDINGS_AWS_REGION=us-east-1           # For Amazon Bedrock
```

### Docker Compose

**File:** `docker-compose.yml`

```yaml
services:
  # MongoDB CE 8.2
  mongodb:
    image: mongo:8.2
    container_name: mcp-mongodb
    command: mongod --replSet rs0 --bind_ip 127.0.0.1,mongodb
    ports:
      - "27017:27017"
    volumes:
      - mongodb-data:/data/db
      - mongodb-config:/data/configdb
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s
    restart: unless-stopped

  # MongoDB initialization (runs once)
  mongodb-init:
    image: mongo:8.2
    container_name: mcp-mongodb-init
    depends_on:
      mongodb:
        condition: service_healthy
    environment:
      - DOCUMENTDB_HOST=mongodb
      - DOCUMENTDB_PORT=27017
      - DOCUMENTDB_DATABASE=${DOCUMENTDB_DATABASE:-mcp_registry}
      - DOCUMENTDB_NAMESPACE=${DOCUMENTDB_NAMESPACE:-default}
    volumes:
      - ./scripts/init-mongodb.sh:/init-mongodb.sh:ro
    entrypoint: ["/bin/bash", "/init-mongodb.sh"]
    restart: "no"

volumes:
  mongodb-data:
  mongodb-config:
```

### Terraform (DocumentDB)

**File:** `terraform/aws-ecs/modules/documentdb/variables.tf`

```hcl
variable "cluster_name" {
  description = "DocumentDB cluster name"
  type        = string
}

variable "instance_class" {
  description = "Instance class (e.g., db.r5.large)"
  type        = string
  default     = "db.r5.large"
}

variable "instance_count" {
  description = "Number of instances (1 writer + N readers)"
  type        = number
  default     = 3  # 1 writer + 2 readers
}

variable "master_username" {
  description = "Master username"
  type        = string
  sensitive   = true
}

variable "master_password" {
  description = "Master password"
  type        = string
  sensitive   = true
}

variable "backup_retention_period" {
  description = "Backup retention in days"
  type        = number
  default     = 7
}
```

---

## Migration Strategy

### From File Backend to MongoDB CE

**Scenario:** Moving from JSON files to MongoDB for local development

**Steps:**

1. **Export existing data**
   ```bash
   # Servers
   cp ~/mcp-gateway/servers/*.json /tmp/servers-backup/

   # Agents
   cp ~/mcp-gateway/agents/*.json /tmp/agents-backup/
   ```

2. **Update configuration**
   ```bash
   # In .env
   sed -i 's/STORAGE_BACKEND=file/STORAGE_BACKEND=mongodb-ce/' .env
   ```

3. **Start MongoDB**
   ```bash
   docker compose up -d mongodb
   docker compose up mongodb-init
   ```

4. **Import data via API**
   ```bash
   # Re-register servers
   for file in /tmp/servers-backup/*.json; do
       curl -X POST http://localhost:7860/servers \
           -H "Content-Type: application/json" \
           -d @"$file"
   done

   # Re-register agents
   for file in /tmp/agents-backup/*.json; do
       curl -X POST http://localhost:7860/agents \
           -H "Content-Type: application/json" \
           -d @"$file"
   done
   ```

5. **Verify**
   ```bash
   # Check server count
   curl http://localhost:7860/servers | jq 'length'

   # Test search
   curl "http://localhost:7860/search?q=financial" | jq '.servers | length'
   ```

### From MongoDB CE to AWS DocumentDB

**Scenario:** Moving from local development to production

**Steps:**

1. **Export from MongoDB CE**
   ```bash
   # Dump all collections
   docker exec mcp-mongodb mongodump \
       --db=mcp_registry \
       --out=/tmp/mongodb-backup

   # Copy backup from container
   docker cp mcp-mongodb:/tmp/mongodb-backup ./mongodb-backup
   ```

2. **Deploy DocumentDB with Terraform**
   ```bash
   cd terraform/aws-ecs
   terraform apply

   # Get DocumentDB endpoint
   terraform output documentdb_endpoint
   ```

3. **Import to DocumentDB**
   ```bash
   # From bastion host or ECS task
   mongorestore \
       --host=mcp-registry.cluster-xxxxx.us-east-1.docdb.amazonaws.com:27017 \
       --ssl \
       --sslCAFile=/app/global-bundle.pem \
       --username=mcp_admin \
       --password=<password> \
       --db=mcp_registry \
       ./mongodb-backup/mcp_registry
   ```

4. **Update application configuration**
   ```bash
   # In .env
   STORAGE_BACKEND=documentdb
   DOCUMENTDB_HOST=mcp-registry.cluster-xxxxx.us-east-1.docdb.amazonaws.com
   DOCUMENTDB_USERNAME=mcp_admin
   DOCUMENTDB_PASSWORD=<password>
   DOCUMENTDB_USE_TLS=true
   DOCUMENTDB_TLS_CA_FILE=/app/global-bundle.pem
   ```

5. **Deploy application**
   ```bash
   terraform apply
   ```

6. **Verify vector search**
   ```bash
   # Test search endpoint
   curl "https://api.example.com/search?q=financial" | jq '.servers'

   # Should return results with relevance_score
   # DocumentDB will use native HNSW index (faster!)
   ```

---

## Summary

### Architecture Highlights

| Component | MongoDB CE | AWS DocumentDB |
|-----------|------------|----------------|
| **Container** | mongo:8.2 | Managed Service |
| **Connection** | mongodb://mongodb:27017 | mongodb://cluster.docdb.amazonaws.com:27017 |
| **Authentication** | None (local) | Username/Password or IAM |
| **TLS** | Disabled | Required |
| **Vector Search** | App-level (Python) | Native (HNSW) |
| **Latency** | 50-200ms | 10-50ms |
| **Max Scale** | ~10,000 docs | Millions |
| **Cost** | Free | AWS pricing |

### Key Takeaways

1. **Same Code, Different Backends**
   - Identical repository implementation
   - Only connection configuration differs
   - Seamless migration path

2. **Vector Search Strategy**
   - MongoDB CE: Application-level for dev simplicity
   - DocumentDB: Native HNSW for production performance
   - Both use cosine similarity metric

3. **Development Workflow**
   - Local dev: `STORAGE_BACKEND=mongodb-ce`
   - Production: `STORAGE_BACKEND=documentdb`
   - Terraform handles infrastructure

4. **No Terraform Changes**
   - AWS DocumentDB infrastructure deployed via Terraform
   - Local MongoDB CE runs in Docker Compose
   - Terraform only manages AWS resources

---

## See Also

- [Database Abstraction Layer Design](./database-abstraction-layer.md)
- [Embeddings Configuration](../embeddings.md)
- [Configuration Guide](../configuration.md)
- [MongoDB Documentation](https://www.mongodb.com/docs/manual/)
- [AWS DocumentDB Documentation](https://docs.aws.amazon.com/documentdb/)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.