Skip to content

Registry of Registries

Introduction

The Registry Management and Access System is a comprehensive backend framework for managing, querying, and securely accessing distributed registry services. It provides an integrated solution that combines:

  • CRUD operations for dynamic registry creation, updates, and deletions
  • Query interfaces for advanced filtering and discovery via both REST and GraphQL
  • Health-aware socket proxying, enabling safe and real-time access to healthy registry nodes

This system is designed to power infrastructure platforms that require modular, decentralized registries representing services, agents, AI tools, or computational units. It ensures that all registry operations—from onboarding and metadata indexing to access routing—are governed by verified health status and reliable data models.

Key Objectives

  • Provide a MongoDB-backed registry layer with full metadata and health endpoint support
  • Offer flexible and powerful query interfaces to locate registries by ID, type, tags, or partial matches
  • Enable real-time access to registries via a socket-level proxy, guarded by health checks and caching
  • Support caching and performance optimization using Redis with TTL-based health status management

Who Is This For?

This system is intended for:

  • Developers managing a distributed ecosystem of services or agents
  • Platform engineers who require a safe and efficient proxy to forward traffic only to live registries
  • API developers who want unified access to create, search, and route to registry services
  • Infrastructure designers building a service-oriented architecture with runtime contract enforcement

Architecture

The Registries System is a modular service designed to manage, store, query, and monitor external or internal registries. It supports registry specification management, asset uploading, dynamic indexing, metadata search, health monitoring, and multi-modal query access (REST, GraphQL, and DSL-based). This section provides a detailed architectural breakdown of the system, categorized into key subsystems.

registry-of-registries

1. Registry Specification Lifecycle

This subsystem handles creation, update, and deletion of registry entries. The architecture is designed to support full validation, metadata persistence, and asset archival.

Components

  • Controller

  • Entry point for the create, update, and delete APIs.

  • Routes validated inputs to appropriate modules.
  • Spec Parser and Validator

  • Validates the structure and schema of incoming registry specifications.

  • Ensures conformance before storage or execution.
  • Create / Update / Delete Modules

  • Encapsulate business logic for respective operations.

  • Handle DB interaction and asset upload orchestration.
  • Assets Uploader

  • Uploads specification ZIP files to S3-compatible storage.

  • Works in tandem with the zip file reader to extract asset contents.
  • Assets DB Client API

  • Registers the uploaded specification as an asset within the asset registry.

  • DB Module

  • Updates the registry index and metadata in the internal database (DB index).

Flow Summary

  1. Registry ZIP specification is submitted.
  2. The spec is parsed and validated.
  3. Assets are extracted and uploaded to object storage.
  4. Metadata is stored, and the registry is registered in both the assets registry and DB index.

2. Index and Query Subsystem

This subsystem enables advanced querying over registered registries using indexed metadata. It supports generic REST queries, GraphQL queries, and DSL-based search execution.

Components

  • DB Index

  • Central database index storing searchable metadata from registry specifications.

  • DB Query System

  • Provides querying capabilities over the DB index.

  • Used by REST, GraphQL, and DSL query interfaces.
  • Generic Query REST API

  • Accepts structured query requests via standard REST endpoints.

  • Converts query to internal DB-compatible format for execution.
  • GraphQL API

  • Provides flexible querying using GraphQL syntax.

  • Powered by the GraphQL Middleware, which resolves query trees into DB queries.
  • DSL-Based Search API

  • Enables complex logic-based filtering and querying using a custom DSL.

  • Handled by the Search DSL Executor and Search DSL Engine, both of which translate logical expressions into database queries.

Flow Summary

  1. Client sends a query via REST, GraphQL, or DSL.
  2. The controller (or middleware) translates it to a DB-compatible query.
  3. The DB Query System executes the query against the indexed metadata.

3. Health Check and Proxy Subsystem

This subsystem provides runtime health monitoring of registries and facilitates proxy access to internal or external registry endpoints.

Components

  • Health Checker

  • Actively probes the health of each registry using its health_check_api.

  • Health Cache with TTL (Redis)

  • Caches health results with a short TTL to reduce redundant checks.

  • Ensures responsiveness and load minimization.
  • Internal Health Checker

  • Uses the core database to locate registry health check APIs.

  • Triggers health checks and stores results in cache.
  • Internal Registry Proxy

  • Forwards data requests to registry endpoints.

  • Supports secure, internal-only communication as needed.
  • Registries Proxy

  • Acts as the outer gateway, combining caching, health checks, and proxy routing logic.

Flow Summary

  1. A request arrives to access a registry.
  2. The internal proxy checks the health cache (Redis).
  3. If data is missing or expired, the health check is triggered.
  4. Results are cached and passed to the client through the proxy.

Schema

The RegistryCoreData schema represents a single registry record in the system. Each registry holds metadata, routing configuration, documentation links, asset IDs, and a nested registry_search_data block for search indexing and classification.

This schema is persisted in the MongoDB registry_core_data collection.


RegistryCoreData – Field Reference

Field Type Description
registry_id str Unique identifier for the registry
registry_url str (optional) Public endpoint for accessing the registry
registry_api_index str (optional) Index or root path to the registry's API surface
registry_documentation_s3_url str (optional) S3 URL pointing to documentation zip
registry_client_sdk_s3_url str (optional) S3 URL pointing to downloadable client SDK
registry_asset_id str (optional) Reference to the asset record linked to this registry
health_check_api str (optional) URL to ping for checking if the registry is healthy
registry_acl_config_info dict[str, str] Access control metadata (e.g., visibility, auth mode, org ownership, etc.)
registry_search_data RegistrySearchData Embedded search indexing object used for querying

RegistrySearchData – Field Reference

Field Type Description
registry_id str Redundant reference to registry_id
registry_type str (optional) High-level category of the registry (e.g., "tool", "agent", "asset")
registry_sub_type str (optional) Sub-classification for internal grouping
registry_search_tags List[str] List of searchable tags associated with this registry
registry_search_description str (optional) Short searchable description used in UI and query filtering
registry_metadata dict[str, str] Additional structured metadata for search/lookup

Python Dataclass

from dataclasses import dataclass, field
from typing import Optional, List, Dict

@dataclass
class RegistrySearchData:
    registry_id: str
    registry_type: Optional[str] = None
    registry_sub_type: Optional[str] = None
    registry_metadata: Dict[str, str] = field(default_factory=dict)
    registry_search_tags: List[str] = field(default_factory=list)
    registry_search_description: Optional[str] = None

    def to_dict(self):
        return {
            "registry_id": self.registry_id,
            "registry_type": self.registry_type,
            "registry_sub_type": self.registry_sub_type,
            "registry_metadata": self.registry_metadata,
            "registry_search_tags": self.registry_search_tags,
            "registry_search_description": self.registry_search_description,
        }

    @classmethod
    def from_dict(cls, data):
        return cls(
            registry_id=data.get("registry_id", ""),
            registry_type=data.get("registry_type"),
            registry_sub_type=data.get("registry_sub_type"),
            registry_metadata=data.get("registry_metadata", {}),
            registry_search_tags=data.get("registry_search_tags", []),
            registry_search_description=data.get("registry_search_description")
        )


@dataclass
class RegistryCoreData:
    registry_id: str
    registry_url: Optional[str] = None
    registry_api_index: Optional[str] = None
    registry_documentation_s3_url: Optional[str] = None
    registry_client_sdk_s3_url: Optional[str] = None
    registry_acl_config_info: Dict[str, str] = field(default_factory=dict)
    registry_asset_id: Optional[str] = None
    health_check_api: Optional[str] = None
    registry_search_data: Optional[RegistrySearchData] = None

    def to_dict(self):
        return {
            "registry_id": self.registry_id,
            "registry_url": self.registry_url,
            "registry_api_index": self.registry_api_index,
            "registry_documentation_s3_url": self.registry_documentation_s3_url,
            "registry_client_sdk_s3_url": self.registry_client_sdk_s3_url,
            "registry_acl_config_info": self.registry_acl_config_info,
            "registry_asset_id": self.registry_asset_id,
            "health_check_api": self.health_check_api,
            "registry_search_data": self.registry_search_data.to_dict() if self.registry_search_data else None,
        }

    @classmethod
    def from_dict(cls, data):
        return cls(
            registry_id=data.get("registry_id", ""),
            registry_url=data.get("registry_url"),
            registry_api_index=data.get("registry_api_index"),
            registry_documentation_s3_url=data.get("registry_documentation_s3_url"),
            registry_client_sdk_s3_url=data.get("registry_client_sdk_s3_url"),
            registry_acl_config_info=data.get("registry_acl_config_info", {}),
            registry_asset_id=data.get("registry_asset_id"),
            health_check_api=data.get("health_check_api"),
            registry_search_data=RegistrySearchData.from_dict(data["registry_search_data"])
            if data.get("registry_search_data") else None
        )

You're welcome! Below is the ## Create, Update, Delete, and ZIP Upload APIs section with:

  • Endpoint descriptions
  • Sample payloads
  • cURL examples

Create, Update, Delete and ZIP Upload APIs

These endpoints manage the lifecycle of registries in the system. All operations persist data to the MongoDB registry_core_data collection. The ZIP upload API supports bundled asset ingestion and asynchronous background processing with Redis-based status tracking.

1. Create Registry

POST /registry/create Creates a new registry entry from a structured JSON spec.

Request Payload (application/json)

{
  "registry_id": "demo-registry",
  "registry_url": "https://demo.example.com",
  "registry_api_index": "/v1",
  "registry_documentation_s3_url": "s3://docs/demo.zip",
  "health_check_api": "https://demo.example.com/health",
  "registry_acl_config_info": {
    "visibility": "public"
  },
  "registry_search_data": {
    "registry_id": "demo-registry",
    "registry_type": "tool",
    "registry_search_tags": ["AI", "demo"],
    "registry_search_description": "Demo registry for testing"
  }
}

Sample cURL

curl -X POST http://localhost:8080/registry/create \
  -H "Content-Type: application/json" \
  -d @registry.json

2. Update Registry

PUT /registry/update Updates an existing registry by registry_id. Only specified fields will be overwritten.

Request Payload (application/json)

{
  "registry_id": "demo-registry",
  "registry_url": "https://demo-updated.example.com"
}

Sample cURL

curl -X PUT http://localhost:8080/registry/update \
  -H "Content-Type: application/json" \
  -d '{"registry_id": "demo-registry", "registry_url": "https://demo-updated.example.com"}'

3. Delete Registry

DELETE /registry/delete/<registry_id> Deletes the registry by ID.

Sample cURL

curl -X DELETE http://localhost:8080/registry/delete/demo-registry

4. ZIP Upload API (Async)

POST /registry/upload_zip Uploads a ZIP file containing assets and a registry spec, processes it in the background, and returns a task ID.

Multipart Form-Data Fields

Field Type Description
spec JSON string RegistryCoreData spec (as text)
zip .zip file ZIP file with docs/sdk/etc.

Sample cURL

curl -X POST http://localhost:8080/registry/upload_zip \
  -F 'spec={"registry_id":"demo-registry","registry_search_data":{"registry_id":"demo-registry"}}' \
  -F 'zip=@assets_bundle.zip'

5. Upload Status API

GET /registry/upload/status/<task_id> Checks the current status of a background ZIP upload.

Sample cURL

curl http://localhost:8080/registry/upload/status/<task_id>

Great — let’s now proceed with the next section:


Query APIs

The Query System allows clients to search registries using both structured REST endpoints and a flexible Mongo-style query interface. It supports exact matching, tag-based filtering, partial string matching, and advanced queries via raw MongoDB filters.

1. Get Registry by ID

GET /registry/query/by-id/<registry_id>

Retrieves the full registry document by ID.

Sample cURL

curl http://localhost:8090/registry/query/by-id/demo-registry

2. Get Registries by Type

GET /registry/query/by-type/<registry_type>

Returns all registries with a specific type (e.g., tool, agent).

Sample cURL

curl http://localhost:8090/registry/query/by-type/tool

3. Get Registries by Tags

POST /registry/query/by-tags

Filters registries where any tag in the provided list matches.

Request Payload

{
  "tags": ["AI", "compute"]
}

Sample cURL

curl -X POST http://localhost:8090/registry/query/by-tags \
  -H "Content-Type: application/json" \
  -d '{"tags": ["AI", "compute"]}'

4. Find by Partial URL Match

GET /registry/query/by-url?fragment=<text>

Performs a case-insensitive partial match on the registry_url.

Sample cURL

curl "http://localhost:8090/registry/query/by-url?fragment=openai"

5. Partial Match on Arbitrary Field

POST /registry/query/partial

Performs a partial (regex-based) match on any field.

Request Payload

{
  "field": "registry_search_data.registry_search_description",
  "fragment": "vision"
}

Sample cURL

curl -X POST http://localhost:8090/registry/query/partial \
  -H "Content-Type: application/json" \
  -d '{"field": "registry_search_data.registry_search_description", "fragment": "vision"}'

6. Generic Mongo Query

POST /registry/query

Performs a Mongo-style raw filter query on the collection.

Request Payload

{
  "filter": {
    "registry_search_data.registry_type": "tool",
    "registry_url": { "$regex": "openai", "$options": "i" }
  },
  "limit": 50
}

Sample cURL

curl -X POST http://localhost:8090/registry/query \
  -H "Content-Type: application/json" \
  -d @query.json

GraphQL API

The system exposes a GraphQL endpoint (/graphql) that allows clients to query registries using structured field selectors, filters, and search parameters. This provides a flexible alternative to REST with typed introspection and composability.

Endpoint

POST /graphql

The endpoint also supports the GraphiQL web interface for manual exploration.

Supported Query Operations

Operation Parameters Description
registryById registryId Fetch a single registry by ID
registriesByType registryType Fetch registries by type
registriesByTags tags: [String] Find registries containing any of the tags
registriesByUrl urlFragment Case-insensitive partial match on URL
registriesByFilter mongoFilter, limit Full Mongo-style query as a JSON string

Sample Queries

1. Get Registry by ID

query {
  registryById(registryId: "demo-registry") {
    registryId
    registryUrl
    registrySearchData {
      registryType
      registrySearchTags
    }
  }
}

2. Search by Tags

query {
  registriesByTags(tags: ["AI", "compute"]) {
    registryId
    registrySearchData {
      registrySearchTags
    }
  }
}

3. Search by Type

query {
  registriesByType(registryType: "tool") {
    registryId
    registrySearchData {
      registryType
    }
  }
}

4. Generic Filter

query {
  registriesByFilter(
    mongoFilter: "{ \"registry_search_data.registry_type\": \"tool\" }"
    limit: 10
  ) {
    registryId
    registryUrl
    registrySearchData {
      registrySearchDescription
    }
  }
}

GraphQL Schema (Simplified)

type RegistrySearchDataType {
  registryId: String
  registryType: String
  registrySubType: String
  registryMetadata: JSON
  registrySearchTags: [String]
  registrySearchDescription: String
}

type RegistryType {
  registryId: String
  registryUrl: String
  registryApiIndex: String
  registryDocumentationS3Url: String
  registryClientSdkS3Url: String
  registryAssetId: String
  healthCheckApi: String
  registryAclConfigInfo: JSON
  registrySearchData: RegistrySearchDataType
}

Proxy System

The Registry Proxy System is a socket-level proxy server that conditionally tunnels traffic to a target registry only if it passes a real-time health check. It is designed to ensure that clients never reach stale or unresponsive registries and enables dynamic routing based on registry health.

This proxy allows external clients to establish TCP connections and interact with registries transparently, while behind the scenes it performs:

  • Health cache lookup (via Redis)
  • Live health check (via HTTP/TCP probe)
  • MongoDB-backed registry endpoint resolution

Key Components

Component Description
SocketRegistryProxy Accepts and relays client TCP connections conditionally based on health
HealthChecker Combines cached and live health status lookups
HealthCache Uses Redis TTL cache to minimize repeated live checks
InternalHealthChecker Performs live HTTP GET or TCP socket probe using metadata from MongoDB

Flow

  1. Client connects to SocketRegistryProxy
  2. First message must include the registry_id
  3. Proxy checks Redis cache for recent health status
  4. If no cache exists, it performs live check via InternalHealthChecker
  5. If healthy, it opens a TCP socket to the target registry and relays data
  6. If unhealthy, connection is dropped or error is returned

Environment Variables

Variable Description
REDIS_HOST Redis host (default: localhost)
REDIS_PORT Redis port (default: 6379)
MONGO_URI MongoDB connection string
HEALTH_CACHE_TTL TTL in seconds for Redis health cache

Running the Proxy

python socket_registry_proxy.py

This launches the proxy on port 9000 by default and listens for client socket connections.


Sample Connection (Client)

import socket

s = socket.socket()
s.connect(("localhost", 9000))
s.send(b"demo-registry\n")  # registry_id as first message
s.send(b"GET /status\n")     # downstream traffic (e.g., HTTP request)
response = s.recv(4096)
print(response.decode())