This guide covers setting up and operating peer-to-peer federation between MCP Gateway Registry instances.
1ac36113-4bbd-45d0-b561-6fe165fb1c93.merged.mp4
- Two or more MCP Gateway Registry instances running
- Network connectivity between registries (HTTPS)
- Admin access to both registries
On the importing registry, generate a Fernet encryption key for storing peer credentials:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Add to your .env:
FEDERATION_ENCRYPTION_KEY=<generated-key>On the registry that will export data, enable federation static token auth:
# Generate a static token
python -c "import secrets; print(secrets.token_urlsafe(32))"
# Add to .env
FEDERATION_STATIC_TOKEN_AUTH_ENABLED=true
FEDERATION_STATIC_TOKEN=<generated-token>Restart the registry for changes to take effect.
On the importing registry, add the peer using the UI or API:
Using the UI:
- Navigate to Settings (gear icon in header)
- Select Federation > Peers
- Click "Add Peer"
- Fill in the peer details:
- Peer ID: A unique identifier (e.g., "lob-a")
- Name: Human-readable name
- Endpoint: Base URL of the peer registry
- Federation Token: The token from Step 2
- Sync Mode: Select how to filter synced items
Using the API:
curl -X POST https://your-registry.com/api/peers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin-token>" \
-d '{
"peer_id": "lob-a",
"name": "LOB-A Registry",
"endpoint": "https://lob-a-registry.corp.com",
"enabled": true,
"sync_mode": "all",
"sync_interval_minutes": 30,
"federation_token": "<token-from-step-2>"
}'On the exporting registry, mark servers and agents for federation export:
# Mark a server as public (exportable)
curl -X PUT https://lob-a-registry.corp.com/api/servers/my-tool \
-H "Authorization: Bearer <admin-token>" \
-d '{"visibility": "public"}'Or use the UI to edit server/agent settings and set visibility to "public".
Using the UI:
- Navigate to Settings > Federation > Peers
- Click the sync icon next to the peer
- View sync status and results
Using the API:
curl -X POST https://your-registry.com/api/peers/lob-a/sync \
-H "Authorization: Bearer <admin-token>"Central IT maintains a Hub that pulls from all LOB registries.
Hub Configuration:
# Hub .env
FEDERATION_ENCRYPTION_KEY=<key-for-encrypting-peer-tokens>Add each LOB as a peer (UI or API).
LOB Configuration:
# Each LOB .env
FEDERATION_STATIC_TOKEN_AUTH_ENABLED=true
FEDERATION_STATIC_TOKEN=<unique-token-per-lob>No peer configuration needed on LOBs (they only export).
Two registries share items with each other.
Registry A:
# .env
FEDERATION_ENCRYPTION_KEY=<key-a>
FEDERATION_STATIC_TOKEN_AUTH_ENABLED=true
FEDERATION_STATIC_TOKEN=<token-a>Add Registry B as a peer with its token.
Registry B:
# .env
FEDERATION_ENCRYPTION_KEY=<key-b>
FEDERATION_STATIC_TOKEN_AUTH_ENABLED=true
FEDERATION_STATIC_TOKEN=<token-b>Add Registry A as a peer with its token.
Multiple registries in a mesh where each can pull from any other.
Each registry:
- Has its own
FEDERATION_STATIC_TOKENfor others to pull from it - Has
FEDERATION_ENCRYPTION_KEYto store peer tokens - Configures each other registry as a peer
Import all public servers and agents from the peer:
{
"peer_id": "lob-a",
"sync_mode": "all"
}Import only specific servers and agents:
{
"peer_id": "lob-a",
"sync_mode": "whitelist",
"whitelist_servers": ["/production-db", "/shared-api"],
"whitelist_agents": ["/analytics-agent"]
}Import items with specific tags:
{
"peer_id": "lob-a",
"sync_mode": "tag_filter",
"tag_filters": ["production", "shared"]
}Configure automatic sync at regular intervals:
{
"peer_id": "lob-a",
"sync_interval_minutes": 30
}Set to 0 for manual-only sync.
The registry runs a background scheduler that:
- Checks every 60 seconds for peers that need syncing
- Evaluates each enabled peer with
sync_interval_minutes > 0 - Triggers sync when the time since
last_successful_syncexceeds the configured interval - Skips peers that are disabled, have sync in progress, or have interval set to 0
The scheduler starts automatically when the registry starts and stops gracefully on shutdown.
Check the registry logs for scheduled sync activity:
docker-compose logs registry | grep -i "scheduled sync"Example log output:
Scheduled sync triggered for peer 'lob-a' (interval: 30m)
Scheduled sync completed for peer 'lob-a': 15 servers, 3 agents
UI: Toggle the enabled switch in the peers list.
API:
# Enable
curl -X POST https://registry.com/api/peers/lob-a/enable \
-H "Authorization: Bearer <token>"
# Disable
curl -X POST https://registry.com/api/peers/lob-a/disable \
-H "Authorization: Bearer <token>"curl -X PUT https://registry.com/api/peers/lob-a \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"sync_mode": "tag_filter",
"tag_filters": ["production"]
}'curl -X DELETE https://registry.com/api/peers/lob-a \
-H "Authorization: Bearer <token>"This removes the peer configuration. Synced items are marked as orphaned.
UI: Click on a peer to view detailed status including:
- Last successful sync
- Total servers/agents synced
- Current generation number
- Health status
API:
curl https://registry.com/api/peers/lob-a/status \
-H "Authorization: Bearer <token>"-
Generate a new token:
python -c "import secrets; print(secrets.token_urlsafe(32))" -
Update the exporting registry's
.env:FEDERATION_STATIC_TOKEN=<new-token>
-
Restart the exporting registry.
-
Update the peer configuration on all importing registries:
curl -X PUT https://hub-registry.com/api/peers/lob-a \ -H "Authorization: Bearer <token>" \ -d '{"federation_token": "<new-token>"}'
If you need to rotate the FEDERATION_ENCRYPTION_KEY:
- Export current peer configurations (tokens will be encrypted)
- Generate new Fernet key
- Run migration script to re-encrypt tokens with new key
- Update
.envwith new key - Restart registry
Symptom: Sync fails with connection error.
Checks:
- Verify network connectivity:
curl https://peer-registry.com/api/v1/federation/health - Check firewall rules allow HTTPS traffic
- Verify endpoint URL is correct in peer config
Symptom: Sync fails with authentication error.
Checks:
- Verify
FEDERATION_STATIC_TOKEN_AUTH_ENABLED=trueon exporting registry - Verify token in peer config matches
FEDERATION_STATIC_TOKENon exporting registry - Check token was copied correctly (no extra whitespace)
- Verify
FEDERATION_ENCRYPTION_KEYis set on importing registry
Symptom: Sync succeeds but no servers/agents appear.
Checks:
- Verify items have
visibility: "public"on exporting registry - Check sync_mode and filters are not too restrictive
- Verify items exist on the exporting registry
Symptom: Sync completes successfully and authentication passes, but 0 servers/agents are returned even though items exist on the peer registry.
Root Cause: This can indicate that the federation token was lost or corrupted during a peer configuration update (issue #561, fixed in version XX.XX).
Diagnostic Steps:
-
Check if the peer had items synced previously:
curl https://registry.com/api/peers/peer-id/status
If
total_servers_syncedwas > 0 before but is now 0, the token may be lost. -
Verify the peer registry is actually returning data:
# Direct test to peer registry (replace with actual token) curl -H "Authorization: Bearer <federation-token>" \ https://peer-registry.com/api/v1/federation/servers
Resolution:
If authentication is working but 0 items are returned, update the federation token using the dedicated endpoint:
curl -X PATCH https://registry.com/api/peers/peer-id/token \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin-token>" \
-d '{
"federation_token": "<correct-token-from-peer-registry>"
}'Or use the UI:
- Navigate to Settings > Federation > Peers
- Click the peer name
- Update the Federation Token field
- Save changes
- Trigger a manual sync to verify
Symptom: After updating a peer's configuration (name, endpoint, sync interval, etc.), all subsequent syncs fail with authentication errors or return 0 items.
Root Cause: Bug in versions prior to XX.XX where the update_peer() operation would silently drop the encrypted federation token when updating any peer field.
Who is Affected:
- Anyone who updated peer configurations between version X.X and X.X
How to Identify:
- Sync was working before a peer update
- Sync now returns 0 items or authentication errors
- No changes were made to the token itself
Recovery:
Update the federation token using the dedicated token update endpoint:
curl -X PATCH https://registry.com/api/peers/<peer-id>/token \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin-token>" \
-d '{
"federation_token": "<correct-federation-token>"
}'Prevention: This issue is fixed in version XX.XX. After upgrading, peer updates will preserve the federation token correctly.
Expected behavior: Federated items cannot be modified locally.
If you need to modify a synced item:
- Modify it on the source registry
- Wait for next sync or trigger manual sync
Symptom: Items show as orphaned in the UI.
This happens when items are removed from the source registry. To resolve:
- Confirm the items should be removed from the source
- Delete orphaned items manually, or
- Re-sync to clear orphaned status if items are restored
Each registry exposes a federation health endpoint:
curl https://registry.com/api/v1/federation/healthReturns:
{
"status": "healthy",
"federation_enabled": true,
"peer_count": 3
}Monitor sync status via the API:
curl https://registry.com/api/peers/lob-a/statusReturns:
{
"peer_id": "lob-a",
"is_healthy": true,
"last_successful_sync": "2026-02-05T10:30:00Z",
"total_servers_synced": 15,
"total_agents_synced": 3,
"sync_in_progress": false,
"consecutive_failures": 0
}Set up alerts for:
consecutive_failures > 3- Sync has failed multiple timesis_healthy == false- Peer is unreachable- Time since
last_successful_sync > 2x sync_interval- Sync is stale
- Use strong tokens: Generate tokens with
secrets.token_urlsafe(32)or longer - Rotate tokens periodically: Rotate federation tokens at least annually
- Limit visibility: Only set
visibility: "public"on items that should be shared - Use tag filters: Use tag-based filtering to control what gets synced
- Monitor sync activity: Review sync logs for unexpected patterns
- Network isolation: Use private networks or VPNs between registries when possible
The Registry Card is a discovery document that provides metadata about your registry instance, including its capabilities, authentication endpoints, and contact information. It is essential for federation discovery and is accessed via the .well-known endpoint:
GET /.well-known/registry-card
Navigate to Settings > Registry Card to view and edit your registry's metadata:
The Registry Card settings page shows:
-
Registry Information (read-only):
- Registry ID (UUID)
- Name
- Organization
- Registry URL
- Federation Endpoint
- API Version
-
Authentication Configuration (read-only):
- Supported authentication schemes
- OAuth2 issuer URL
- OAuth2 token endpoint
- Supported scopes
-
Editable Information:
- Description (up to 1000 characters)
- Contact Email
- Contact URL
-
Capabilities (configured via feature flags):
- Servers, Agents, Skills management
- Security scans
- Incremental sync (future)
- Webhooks (future)
The Registry Card is automatically initialized on first startup using environment variables. Configure these in your .env file:
# Registry Identity (Required)
REGISTRY_URL=https://registry.example.com
REGISTRY_NAME=My Registry
REGISTRY_ORGANIZATION_NAME=ACME Corporation
# Optional
REGISTRY_DESCRIPTION=Enterprise MCP Gateway Registry
REGISTRY_CONTACT_EMAIL=mcp-support@example.com
REGISTRY_CONTACT_URL=https://example.com/supportFor a complete list of configuration options, see the Configuration Reference.
The Registry Card automatically configures authentication endpoints based on your AUTH_PROVIDER setting:
- Entra ID: Uses Microsoft login endpoints
- Keycloak: Uses your Keycloak realm endpoints
- Okta: Uses your Okta domain endpoints
- Cognito: Uses AWS Cognito endpoints
The authentication configuration is read-only and updates automatically when you change authentication providers.
- Federation Architecture - Technical architecture
- Federation Guide - External registry integration (Anthropic, ASOR)
- Static Token Auth - Static token authentication details
- Configuration Reference - Environment variable reference
