Skip to content

[Feature Request]: MCP Server Marketplace and Registry #295

@crivetimihai

Description

@crivetimihai

Title: MCP Server Marketplace
Goal: Create a comprehensive centralized marketplace for discovering, installing, and managing MCP servers with enterprise-grade controls, community features, and seamless integration into the gateway's server management system
Why now: The MCP ecosystem is rapidly growing with hundreds of servers being developed. Organizations need a trusted, centralized way to discover, evaluate, and deploy MCP servers while maintaining security and governance standards.

See also: #209 and https://github.com/modelcontextprotocol/registry

🎯 Feature Overview

The MCP Server Marketplace transforms the gateway from a passive server registry into an active marketplace platform that enables:

  • Server Discovery - Browse curated MCP servers by category, popularity, and functionality
  • One-Click Installation - Deploy servers directly from the marketplace with automatic configuration
  • Enterprise Controls - Admin approval workflows, security scanning, and policy enforcement
  • Community Features - Ratings, reviews, usage analytics, and recommendations
  • Multi-Source Support - Public marketplace, private repositories, and custom catalogs
  • Lifecycle Management - Updates, rollbacks, dependency resolution, and health monitoring
  • Integration Foundation - Extensible architecture supporting DTX and other extensions

🙋‍♂️ User Stories

Story 1 — Server Discovery & Browsing

As a Developer/Administrator
I want to browse and search available MCP servers in a marketplace interface
So that I can discover tools and capabilities to enhance my development workflow.

✅ Acceptance Criteria
Scenario: Browse marketplace catalog
  Given I access the MCP Server Marketplace
  When I navigate to the marketplace section
  Then I see a categorized catalog of available MCP servers
  And I can filter by category (Development, Data, AI/ML, Security, etc.)
  And I can search by name, description, or tags
  And I can sort by popularity, rating, or last updated
  And each server shows description, rating, download count, and compatibility info

Scenario: View server details
  Given I'm browsing the marketplace
  When I click on a specific MCP server
  Then I see detailed information including:
    - Full description and documentation
    - Screenshots or demo videos
    - Version history and changelog
    - Community ratings and reviews
    - Security scan results
    - System requirements and dependencies
    - Installation and configuration instructions

Story 2 — One-Click Server Installation

As a Administrator
I want to install MCP servers directly from the marketplace
So that I can quickly deploy new capabilities without manual configuration.

✅ Acceptance Criteria
Scenario: Install server from marketplace
  Given I have selected an MCP server from the marketplace
  When I click "Install" and provide any required configuration
  Then the system downloads and configures the server automatically
  And the server is registered in my gateway instance
  And it appears in my local server catalog as "Running"
  And all tools, resources, and prompts are immediately available
  And installation status is tracked with progress indicators

Scenario: Configure server during installation
  Given I'm installing an MCP server that requires configuration
  When the installation wizard appears
  Then I can provide required parameters (API keys, endpoints, etc.)
  And the system validates the configuration before proceeding
  And I can save the configuration as a template for future installations
  And the server starts automatically after successful configuration

Story 3 — Enterprise Administration & Policies

As an Enterprise Administrator
I want granular control over marketplace access and server installations
So that I can maintain security and compliance while enabling productivity.

✅ Acceptance Criteria
Scenario: Configure marketplace policies
  Given I'm an enterprise administrator
  When I access marketplace administration settings
  Then I can define policies for:
    - Which users/groups can browse the marketplace
    - Which servers require approval before installation
    - Automatic security scanning requirements
    - Maximum server resource limits
    - Data privacy and compliance controls
  And I can create pre-approved server lists for different user groups
  And I can disable marketplace access entirely if needed

Scenario: Server approval workflow
  Given a user requests to install a server requiring approval
  When the request is submitted
  Then I receive a notification with server details and security scan results
  And I can approve, reject, or request additional review
  And the user is notified of the decision
  And approved servers are automatically installed for the user
  And I can track all installation requests and decisions

Story 4 — Community Features & Reviews

As a Marketplace User
I want to see community feedback and contribute my own reviews
So that I can make informed decisions about server quality and reliability.

✅ Acceptance Criteria
Scenario: View community ratings and reviews
  Given I'm viewing a server in the marketplace
  When I scroll to the community section
  Then I see aggregate ratings (1-5 stars) and review count
  And I can read individual reviews with:
    - Rating, review text, and reviewer username
    - Helpful/unhelpful voting on reviews
    - Server version the review applies to
    - Review date and verification status
  And I can filter reviews by rating or recency
  And I see usage statistics (downloads, active installations)

Scenario: Submit a server review
  Given I have installed and used an MCP server
  When I navigate to the server's marketplace page
  Then I can submit a review with:
    - Star rating (1-5)
    - Written review of my experience
    - Recommendation for specific use cases
  And my review appears after moderation (if enabled)
  And I can update my review based on new versions
  And I receive notifications when others find my review helpful

Story 5 — Multi-Source Server Repositories

As a Platform Administrator
I want to configure multiple server sources beyond the public marketplace
So that I can access private, enterprise, or specialized server repositories.

✅ Acceptance Criteria
Scenario: Configure custom server repositories
  Given I'm configuring marketplace settings
  When I add a custom repository source
  Then I can specify:
    - Repository URL and authentication credentials
    - Trust level and security requirements
    - Visibility (public, admin-only, specific groups)
    - Update frequency and caching settings
  And servers from custom repositories appear in the marketplace
  And they are clearly labeled with their source
  And I can prioritize sources in search results

Scenario: Private enterprise repository
  Given I have configured a private enterprise repository
  When developers browse the marketplace
  Then they see both public and private servers
  And private servers are marked with enterprise branding
  And access controls are enforced based on user permissions
  And enterprise servers can be pre-installed for specific groups
  And custom repositories support versioning and staging environments

Story 6 — Server Lifecycle Management

As a System Administrator
I want automated management of server updates, dependencies, and health monitoring
So that my MCP servers remain current, secure, and operational.

✅ Acceptance Criteria
Scenario: Automatic server updates
  Given I have marketplace-installed servers running
  When new versions become available
  Then I receive notifications about available updates
  And I can configure automatic update policies:
    - Auto-install security updates
    - Notify for major version updates
    - Test updates in staging first
  And update rollback is available if issues occur
  And server health is monitored during updates

Scenario: Dependency management
  Given I install a server with dependencies
  When dependencies conflict with existing servers
  Then the system identifies conflicts and suggests resolutions
  And I can choose to:
    - Install compatible versions
    - Run servers in isolation
    - Skip conflicting dependencies
  And dependency trees are visualized in the admin UI
  And unused dependencies are automatically cleaned up

🏗️ Architecture

Marketplace System Architecture

flowchart TD
    subgraph "MCP Gateway"
        UI[Admin UI] --> MP[Marketplace Manager]
        API[REST API] --> MP
        MP --> SM[Server Manager]
        MP --> PM[Policy Manager]
        MP --> IM[Installation Manager]
        SM --> DB[(Gateway Database)]
    end
    
    subgraph "Marketplace Sources"
        PUB[Public Marketplace]
        ENT[Enterprise Repository]
        PRIV[Private Registry]
        GITHUB[GitHub Releases]
        DOCKER[Docker Registry]
    end
    
    subgraph "Installation & Runtime"
        IM --> DOCKER_RUNTIME[Docker Runtime]
        IM --> VENV[Python venv]
        IM --> BIN[Binary Execution]
        SM --> HEALTH[Health Monitor]
    end
    
    subgraph "Community & Reviews"
        MP --> REVIEW[Review System]
        MP --> RATING[Rating Engine]
        MP --> ANALYTICS[Usage Analytics]
    end
    
    subgraph "Security & Compliance"
        PM --> SCAN[Security Scanner]
        PM --> APPROVAL[Approval Workflow]
        PM --> AUDIT[Audit Log]
    end
    
    MP --> PUB
    MP --> ENT
    MP --> PRIV
    MP --> GITHUB
    MP --> DOCKER
    
    REVIEW --> DB
    RATING --> DB
    ANALYTICS --> DB
    SCAN --> DB
    APPROVAL --> DB
    AUDIT --> DB
    
    classDef manager fill:#e3f2fd,stroke:#1976d2;
    classDef source fill:#f3e5f5,stroke:#7b1fa2;
    classDef runtime fill:#e8f5e8,stroke:#388e3c;
    classDef community fill:#fff3e0,stroke:#f57c00;
    
    class MP,SM,PM,IM manager
    class PUB,ENT,PRIV,GITHUB,DOCKER source
    class DOCKER_RUNTIME,VENV,BIN,HEALTH runtime
    class REVIEW,RATING,ANALYTICS community
Loading

Server Installation Flow

sequenceDiagram
    participant USER as User
    participant UI as Admin UI
    participant MP as Marketplace Manager
    participant PM as Policy Manager
    participant IM as Installation Manager
    participant SM as Server Manager
    participant RUNTIME as Server Runtime

    USER ->> UI: Browse marketplace
    UI ->> MP: get_marketplace_catalog()
    MP -->> UI: server_catalog
    
    USER ->> UI: Select server to install
    UI ->> MP: get_server_details(server_id)
    MP -->> UI: server_details
    
    USER ->> UI: Click "Install"
    UI ->> PM: check_installation_policy(user, server)
    
    alt Requires Approval
        PM -->> UI: approval_required
        UI -->> USER: "Installation requires admin approval"
        PM ->> PM: create_approval_request()
    else Auto-approved
        PM -->> UI: approved
        UI ->> IM: install_server(server_config)
        
        IM ->> IM: download_server_package()
        IM ->> IM: prepare_runtime_environment()
        IM ->> RUNTIME: start_server()
        IM ->> SM: register_server()
        
        IM -->> UI: installation_complete
        UI -->> USER: "Server installed successfully"
    end
Loading

💻 Implementation Design

Core Marketplace Components

class MarketplaceManager:
    """Main orchestrator for marketplace functionality"""
    
    def __init__(self):
        self.repository_manager = RepositoryManager()
        self.installation_manager = InstallationManager()
        self.policy_manager = PolicyManager()
        self.review_system = ReviewSystem()
        self.security_scanner = SecurityScanner()
        
    async def get_marketplace_catalog(
        self, 
        user: User,
        filters: MarketplaceFilters = None
    ) -> MarketplaceCatalog:
        """Get filtered marketplace catalog for user"""
        
        # Get servers from all configured repositories
        all_servers = await self.repository_manager.get_all_servers()
        
        # Apply user-specific policies
        accessible_servers = await self.policy_manager.filter_accessible_servers(
            all_servers, user
        )
        
        # Apply search/filter criteria
        if filters:
            accessible_servers = self._apply_filters(accessible_servers, filters)
        
        # Enrich with community data
        enriched_servers = await self._enrich_with_community_data(accessible_servers)
        
        return MarketplaceCatalog(
            servers=enriched_servers,
            total_count=len(all_servers),
            filtered_count=len(accessible_servers),
            categories=await self._get_categories(),
            featured_servers=await self._get_featured_servers(user)
        )
    
    async def install_server(
        self,
        server_id: str,
        user: User,
        config: InstallationConfig
    ) -> InstallationResult:
        """Install an MCP server from the marketplace"""
        
        # Get server details
        server = await self.repository_manager.get_server(server_id)
        if not server:
            raise ServerNotFoundError(f"Server {server_id} not found")
        
        # Check installation policies
        policy_result = await self.policy_manager.check_installation_policy(
            server, user, config
        )
        
        if policy_result.requires_approval:
            return await self._create_approval_request(server, user, config)
        
        # Scan server for security issues
        if config.security_scan_enabled:
            scan_result = await self.security_scanner.scan_server(server)
            if scan_result.has_critical_issues:
                raise SecurityScanFailedException(scan_result.issues)
        
        # Perform installation
        installation_result = await self.installation_manager.install_server(
            server, config
        )
        
        # Register in local gateway
        if installation_result.success:
            await self._register_installed_server(server, installation_result)
            await self._track_installation_analytics(server, user)
        
        return installation_result


class RepositoryManager:
    """Manages multiple server repositories and sources"""
    
    def __init__(self):
        self.repositories: Dict[str, Repository] = {}
        self.cache = RepositoryCache()
        
    async def add_repository(self, repo_config: RepositoryConfig) -> Repository:
        """Add a new server repository"""
        repo = await self._create_repository(repo_config)
        await repo.initialize()
        self.repositories[repo_config.name] = repo
        return repo
    
    async def get_all_servers(self) -> List[MarketplaceServer]:
        """Get servers from all configured repositories"""
        all_servers = []
        
        for repo_name, repo in self.repositories.items():
            try:
                # Check cache first
                cached_servers = await self.cache.get_servers(repo_name)
                if cached_servers and not self._is_cache_expired(repo_name):
                    servers = cached_servers
                else:
                    # Fetch fresh data
                    servers = await repo.list_servers()
                    await self.cache.store_servers(repo_name, servers)
                
                # Tag servers with repository source
                for server in servers:
                    server.repository_name = repo_name
                    server.repository_type = repo.repository_type
                    server.trust_level = repo.trust_level
                
                all_servers.extend(servers)
                
            except Exception as e:
                logger.error(f"Failed to fetch servers from {repo_name}: {e}")
                # Continue with other repositories
                continue
        
        return all_servers
    
    async def _create_repository(self, config: RepositoryConfig) -> Repository:
        """Factory method to create repository instances"""
        if config.type == "github":
            return GitHubRepository(config)
        elif config.type == "docker":
            return DockerRegistryRepository(config)
        elif config.type == "http":
            return HTTPRepository(config)
        elif config.type == "local":
            return LocalRepository(config)
        else:
            raise UnsupportedRepositoryTypeError(config.type)


class InstallationManager:
    """Handles server installation and lifecycle management"""
    
    def __init__(self):
        self.runtime_managers = {
            "docker": DockerRuntimeManager(),
            "python": PythonRuntimeManager(),
            "binary": BinaryRuntimeManager(),
            "nodejs": NodeJSRuntimeManager()
        }
        
    async def install_server(
        self,
        server: MarketplaceServer,
        config: InstallationConfig
    ) -> InstallationResult:
        """Install and configure an MCP server"""
        
        installation_id = self._generate_installation_id()
        
        try:
            # Download server package
            package_path = await self._download_server_package(
                server, 
                installation_id
            )
            
            # Detect runtime requirements
            runtime_type = await self._detect_runtime_type(package_path, server)
            runtime_manager = self.runtime_managers[runtime_type]
            
            # Prepare runtime environment
            environment = await runtime_manager.prepare_environment(
                package_path, 
                config
            )
            
            # Install dependencies
            await runtime_manager.install_dependencies(environment, server)
            
            # Configure server
            server_config = await self._generate_server_config(
                server, 
                config, 
                environment
            )
            
            # Start server
            process_info = await runtime_manager.start_server(
                environment, 
                server_config
            )
            
            # Verify server is responding
            health_check_result = await self._verify_server_health(
                server_config.endpoint
            )
            
            if not health_check_result.healthy:
                raise ServerStartupFailedException(health_check_result.error)
            
            return InstallationResult(
                installation_id=installation_id,
                success=True,
                server_config=server_config,
                process_info=process_info,
                environment=environment,
                health_status=health_check_result
            )
            
        except Exception as e:
            logger.error(f"Installation failed for {server.name}: {e}")
            await self._cleanup_failed_installation(installation_id)
            return InstallationResult(
                installation_id=installation_id,
                success=False,
                error=str(e)
            )


class PolicyManager:
    """Manages enterprise policies and approval workflows"""
    
    def __init__(self):
        self.policy_engine = PolicyEngine()
        self.approval_workflows = ApprovalWorkflowManager()
        
    async def check_installation_policy(
        self,
        server: MarketplaceServer,
        user: User,
        config: InstallationConfig
    ) -> PolicyCheckResult:
        """Check if server installation is allowed per policies"""
        
        result = PolicyCheckResult()
        
        # Check user permissions
        if not await self.policy_engine.user_can_install_servers(user):
            result.denied = True
            result.reason = "User lacks server installation permissions"
            return result
        
        # Check server whitelist/blacklist
        if await self.policy_engine.is_server_blacklisted(server):
            result.denied = True
            result.reason = f"Server {server.name} is blacklisted"
            return result
        
        # Check if server requires approval
        if await self.policy_engine.requires_approval(server, user):
            result.requires_approval = True
            result.approval_workflow = await self._get_approval_workflow(server)
            return result
        
        # Check resource limits
        resource_check = await self.policy_engine.check_resource_limits(
            server, user
        )
        if not resource_check.allowed:
            result.denied = True
            result.reason = resource_check.reason
            return result
        
        # Check security requirements
        if config.require_security_scan:
            scan_required = await self.policy_engine.requires_security_scan(server)
            result.security_scan_required = scan_required
        
        result.approved = True
        return result


class ReviewSystem:
    """Manages community reviews and ratings"""
    
    def __init__(self):
        self.review_storage = ReviewStorage()
        self.moderation_engine = ModerationEngine()
        
    async def submit_review(
        self,
        server_id: str,
        user: User,
        review: ReviewSubmission
    ) -> Review:
        """Submit a new server review"""
        
        # Check if user can review (has used the server)
        if not await self._user_can_review(user, server_id):
            raise ReviewPermissionError("User must install server before reviewing")
        
        # Check for existing review from user
        existing_review = await self.review_storage.get_user_review(
            user.id, server_id
        )
        
        if existing_review:
            # Update existing review
            return await self._update_review(existing_review, review)
        
        # Create new review
        new_review = Review(
            id=self._generate_review_id(),
            server_id=server_id,
            user_id=user.id,
            username=user.username,
            rating=review.rating,
            title=review.title,
            content=review.content,
            version_reviewed=review.server_version,
            created_at=datetime.utcnow(),
            helpful_count=0,
            unhelpful_count=0
        )
        
        # Apply moderation if enabled
        if settings.review_moderation_enabled:
            moderation_result = await self.moderation_engine.moderate_review(
                new_review
            )
            new_review.moderation_status = moderation_result.status
            new_review.moderation_notes = moderation_result.notes
        
        # Store review
        await self.review_storage.store_review(new_review)
        
        # Update server aggregate rating
        await self._update_server_rating(server_id)
        
        return new_review

Database Schema Extensions

class MarketplaceServer(Base):
    """Marketplace server catalog entry"""
    
    __tablename__ = "marketplace_servers"
    
    id: Mapped[str] = mapped_column(String, primary_key=True)  # Unique across all repos
    name: Mapped[str] = mapped_column(String, nullable=False)
    description: Mapped[str] = mapped_column(Text)
    version: Mapped[str] = mapped_column(String, nullable=False)
    author: Mapped[str] = mapped_column(String)
    
    # Repository information
    repository_name: Mapped[str] = mapped_column(String, nullable=False)
    repository_type: Mapped[str] = mapped_column(String, nullable=False)  # github, docker, http, local
    repository_url: Mapped[str] = mapped_column(String)
    package_url: Mapped[str] = mapped_column(String)
    
    # Categorization
    category: Mapped[str] = mapped_column(String)
    tags: Mapped[List[str]] = mapped_column(JSON)
    
    # Runtime information
    runtime_type: Mapped[str] = mapped_column(String)  # docker, python, binary, nodejs
    requirements: Mapped[Dict[str, Any]] = mapped_column(JSON)
    configuration_schema: Mapped[Dict[str, Any]] = mapped_column(JSON)
    
    # Metadata
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
    last_synced: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
    
    # Statistics
    download_count: Mapped[int] = mapped_column(Integer, default=0)
    installation_count: Mapped[int] = mapped_column(Integer, default=0)
    average_rating: Mapped[Optional[float]] = mapped_column(Float)
    review_count: Mapped[int] = mapped_column(Integer, default=0)
    
    # Status
    is_featured: Mapped[bool] = mapped_column(Boolean, default=False)
    is_verified: Mapped[bool] = mapped_column(Boolean, default=False)
    trust_level: Mapped[str] = mapped_column(String, default="community")  # community, verified, enterprise
    
    # Relationships
    reviews: Mapped[List["ServerReview"]] = relationship("ServerReview", back_populates="server")
    installations: Mapped[List["ServerInstallation"]] = relationship("ServerInstallation", back_populates="marketplace_server")


class ServerInstallation(Base):
    """Record of installed marketplace servers"""
    
    __tablename__ = "server_installations"
    
    id: Mapped[str] = mapped_column(String, primary_key=True)
    marketplace_server_id: Mapped[str] = mapped_column(String, ForeignKey("marketplace_servers.id"))
    gateway_server_id: Mapped[str] = mapped_column(String, ForeignKey("servers.id"))
    user_id: Mapped[str] = mapped_column(String, nullable=False)
    
    # Installation details
    installed_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
    installation_method: Mapped[str] = mapped_column(String)  # marketplace, manual, approval
    configuration: Mapped[Dict[str, Any]] = mapped_column(JSON)
    
    # Runtime information
    runtime_type: Mapped[str] = mapped_column(String)
    environment_path: Mapped[str] = mapped_column(String)
    process_id: Mapped[Optional[int]] = mapped_column(Integer)
    
    # Status
    status: Mapped[str] = mapped_column(String, default="installing")  # installing, running, stopped, failed
    health_status: Mapped[str] = mapped_column(String, default="unknown")
    last_health_check: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
    
    # Version tracking
    installed_version: Mapped[str] = mapped_column(String)
    available_version: Mapped[Optional[str]] = mapped_column(String)
    auto_update_enabled: Mapped[bool] = mapped_column(Boolean, default=False)
    
    # Relationships
    marketplace_server: Mapped["MarketplaceServer"] = relationship("MarketplaceServer", back_populates="installations")
    gateway_server: Mapped["Server"] = relationship("Server")


class ServerReview(Base):
    """Community reviews for marketplace servers"""
    
    __tablename__ = "server_reviews"
    
    id: Mapped[str] = mapped_column(String, primary_key=True)
    server_id: Mapped[str] = mapped_column(String, ForeignKey("marketplace_servers.id"))
    user_id: Mapped[str] = mapped_column(String, nullable=False)
    username: Mapped[str] = mapped_column(String, nullable=False)
    
    # Review content
    rating: Mapped[int] = mapped_column(Integer, nullable=False)  # 1-5 stars
    title: Mapped[str] = mapped_column(String)
    content: Mapped[str] = mapped_column(Text)
    version_reviewed: Mapped[str] = mapped_column(String)
    
    # Metadata
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
    
    # Community interaction
    helpful_count: Mapped[int] = mapped_column(Integer, default=0)
    unhelpful_count: Mapped[int] = mapped_column(Integer, default=0)
    
    # Moderation
    moderation_status: Mapped[str] = mapped_column(String, default="pending")  # pending, approved, rejected
    moderation_notes: Mapped[Optional[str]] = mapped_column(Text)
    
    # Relationships
    server: Mapped["MarketplaceServer"] = relationship("MarketplaceServer", back_populates="reviews")


class MarketplaceRepository(Base):
    """Configuration for marketplace server repositories"""
    
    __tablename__ = "marketplace_repositories"
    
    id: Mapped[str] = mapped_column(String, primary_key=True)
    name: Mapped[str] = mapped_column(String, unique=True, nullable=False)
    repository_type: Mapped[str] = mapped_column(String, nullable=False)
    url: Mapped[str] = mapped_column(String, nullable=False)
    
    # Authentication
    auth_type: Mapped[str] = mapped_column(String, default="none")  # none, basic, token, oauth
    auth_config: Mapped[Dict[str, Any]] = mapped_column(JSON)
    
    # Configuration
    enabled: Mapped[bool] = mapped_column(Boolean, default=True)
    trust_level: Mapped[str] = mapped_column(String, default="community")
    auto_sync: Mapped[bool] = mapped_column(Boolean, default=True)
    sync_interval_hours: Mapped[int] = mapped_column(Integer, default=24)
    
    # Access control
    visibility: Mapped[str] = mapped_column(String, default="public")  # public, admin, group
    allowed_groups: Mapped[List[str]] = mapped_column(JSON)
    
    # Status
    last_sync: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
    sync_status: Mapped[str] = mapped_column(String, default="never")  # never, success, failed, in_progress
    sync_error: Mapped[Optional[str]] = mapped_column(Text)
    server_count: Mapped[int] = mapped_column(Integer, default=0)
    
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)

🔧 Configuration

class MarketplaceConfig:
    # === Core Marketplace ===
    marketplace_enabled: bool = True                      # Enable marketplace functionality
    default_repository_sync_interval: int = 24           # Hours between repository syncs
    marketplace_cache_ttl: int = 3600                     # Cache TTL for marketplace data (seconds)
    
    # === Installation ===
    allow_marketplace_installs: bool = True               # Allow installations from marketplace
    default_installation_timeout: int = 600               # Max installation time (seconds)
    auto_cleanup_failed_installs: bool = True             # Clean up failed installations
    max_concurrent_installs: int = 3                      # Max concurrent installations per user
    
    # === Security & Policies ===
    require_admin_approval_by_default: bool = False       # Require approval for all installs
    security_scan_required: bool = True                   # Require security scan before install
    allow_untrusted_repositories: bool = False            # Allow community/untrusted repos
    installation_isolation_mode: str = "container"        # container, venv, none
    
    # === Community Features ===
    reviews_enabled: bool = True                          # Enable review system
    ratings_enabled: bool = True                          # Enable rating system
    review_moderation_enabled: bool = False               # Require review moderation
    min_install_time_for_review: int = 300                # Min usage time before review (seconds)
    
    # === Repository Sources ===
    enable_public_marketplace: bool = True                # Enable public MCP marketplace
    public_marketplace_url: str = "https://marketplace.mcp.dev"  # Public marketplace URL
    enable_github_repositories: bool = True               # Allow GitHub-based repositories
    enable_docker_repositories: bool = True               # Allow Docker registry repositories
    enable_local_repositories: bool = True                # Allow local file repositories
    
    # === Runtime Support ===
    supported_runtimes = [                                # Supported server runtime types
        "docker",
        "python", 
        "nodejs",
        "binary"
    ]
    
    docker_enabled: bool = True                           # Enable Docker runtime
    python_venv_enabled: bool = True                      # Enable Python venv runtime
    nodejs_enabled: bool = True                           # Enable Node.js runtime
    binary_execution_enabled: bool = False                # Enable binary execution (security risk)
    
    # === Update Management ===
    auto_update_enabled: bool = False                     # Enable automatic updates
    update_check_interval: int = 24                       # Hours between update checks
    auto_update_security_patches: bool = True             # Auto-update security patches
    rollback_retention_days: int = 7                      # Keep rollback data for N days
    
    # === Performance & Limits ===
    max_servers_per_user: int = 50                        # Max installed servers per user
    max_server_memory_mb: int = 512                       # Max memory per server (MB)
    max_server_storage_mb: int = 1024                     # Max storage per server (MB)
    installation_cleanup_interval: int = 3600             # Cleanup interval (seconds)
    
    # === Enterprise Features ===
    enterprise_policies_enabled: bool = False             # Enable enterprise policy engine
    approval_workflow_enabled: bool = False               # Enable approval workflows
    audit_logging_enabled: bool = True                    # Log all marketplace activities
    group_based_permissions: bool = False                 # Enable group-based permissions
    
    # === DTX Integration (Foundation) ===
    dtx_support_enabled: bool = False                     # Enable DTX server support (for future)
    dtx_streamable_http_enabled: bool = False             # Enable streamable-HTTP for DTX
    dtx_desktop_integration: bool = False                 # Enable desktop app integration

📱 Admin UI Integration

Marketplace Dashboard

<!-- Marketplace Tab Panel -->
<div id="marketplace-panel" class="tab-panel hidden">
  <div class="marketplace-header">
    <h2 class="text-2xl font-bold">MCP Server Marketplace</h2>
    <p class="text-gray-600">Discover, install, and manage MCP servers from trusted sources</p>
    
    <!-- Quick Stats -->
    <div class="marketplace-stats grid grid-cols-4 gap-4 my-4">
      <div class="stat-card">
        <h3>Available Servers</h3>
        <span class="stat-number">1,247</span>
      </div>
      <div class="stat-card">
        <h3>Installed Servers</h3>
        <span class="stat-number">12</span>
      </div>
      <div class="stat-card">
        <h3>Updates Available</h3>
        <span class="stat-number">3</span>
      </div>
      <div class="stat-card">
        <h3>Active Repositories</h3>
        <span class="stat-number">5</span>
      </div>
    </div>
  </div>
  
  <!-- Search and Filters -->
  <div class="marketplace-controls">
    <div class="search-box">
      <input type="text" id="marketplace-search" placeholder="Search servers..." />
      <button onclick="searchMarketplace()">Search</button>
    </div>
    
    <div class="filters">
      <select id="category-filter">
        <option value="">All Categories</option>
        <option value="development">Development</option>
        <option value="data">Data & Analytics</option>
        <option value="ai-ml">AI & Machine Learning</option>
        <option value="security">Security</option>
        <option value="productivity">Productivity</option>
      </select>
      
      <select id="repository-filter">
        <option value="">All Sources</option>
        <option value="public">Public Marketplace</option>
        <option value="enterprise">Enterprise</option>
        <option value="github">GitHub</option>
      </select>
      
      <select id="sort-filter">
        <option value="popularity">Most Popular</option>
        <option value="rating">Highest Rated</option>
        <option value="recent">Recently Updated</option>
        <option value="name">Name A-Z</option>
      </select>
    </div>
  </div>
  
  <!-- Server Grid -->
  <div class="marketplace-grid" id="marketplace-grid">
    <!-- Server cards will be populated dynamically -->
  </div>
  
  <!-- Pagination -->
  <div class="marketplace-pagination">
    <button onclick="loadMarketplacePage(currentPage - 1)">Previous</button>
    <span>Page <span id="current-page">1</span> of <span id="total-pages">42</span></span>
    <button onclick="loadMarketplacePage(currentPage + 1)">Next</button>
  </div>
</div>

<!-- Server Detail Modal -->
<div id="server-detail-modal" class="modal">
  <div class="modal-content server-detail">
    <div class="server-header">
      <img class="server-icon" src="" alt="Server Icon" />
      <div class="server-info">
        <h3 class="server-name"></h3>
        <p class="server-author"></p>
        <div class="server-rating">
          <span class="stars"></span>
          <span class="rating-text"></span>
        </div>
        <div class="server-stats">
          <span class="downloads"></span> downloads •
          <span class="version"></span><span class="updated"></span>
        </div>
      </div>
      <div class="server-actions">
        <button class="btn btn-primary install-btn" onclick="installServer()">
          Install
        </button>
        <button class="btn btn-secondary" onclick="viewServerDocumentation()">
          Documentation
        </button>
      </div>
    </div>
    
    <div class="server-tabs">
      <button class="tab-btn active" onclick="showServerTab('overview')">Overview</button>
      <button class="tab-btn" onclick="showServerTab('reviews')">Reviews</button>
      <button class="tab-btn" onclick="showServerTab('changelog')">Changelog</button>
      <button class="tab-btn" onclick="showServerTab('configuration')">Configuration</button>
    </div>
    
    <div class="server-tab-content">
      <!-- Tab content populated dynamically -->
    </div>
  </div>
</div>

Installation Wizard

class MarketplaceInstaller {
    async installServer(serverId, showWizard = true) {
        const server = await this.getServerDetails(serverId);
        
        if (showWizard && server.requires_configuration) {
            this.showInstallationWizard(server);
        } else {
            this.performInstallation(server, {});
        }
    }
    
    showInstallationWizard(server) {
        const wizard = new InstallationWizard(server);
        wizard.show()
            .then(config => this.performInstallation(server, config))
            .catch(error => this.showError('Installation cancelled'));
    }
    
    async performInstallation(server, config) {
        const installationId = this.generateInstallationId();
        
        // Show progress modal
        this.showInstallationProgress(installationId);
        
        try {
            const response = await fetch('/admin/marketplace/install', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    server_id: server.id,
                    configuration: config
                })
            });
            
            const result = await response.json();
            
            if (result.requires_approval) {
                this.showApprovalRequired(result);
            } else {
                this.pollInstallationStatus(result.installation_id);
            }
            
        } catch (error) {
            this.showInstallationError(error);
        }
    }
    
    async pollInstallationStatus(installationId) {
        const interval = setInterval(async () => {
            const status = await this.getInstallationStatus(installationId);
            
            this.updateInstallationProgress(status);
            
            if (status.status === 'completed') {
                clearInterval(interval);
                this.showInstallationSuccess(status);
                this.refreshServerList();
            } else if (status.status === 'failed') {
                clearInterval(interval);
                this.showInstallationError(status.error);
            }
        }, 2000);
    }
    
    updateInstallationProgress(status) {
        const progressBar = document.querySelector('.installation-progress');
        const statusText = document.querySelector('.installation-status');
        
        progressBar.style.width = `${status.progress}%`;
        statusText.textContent = status.current_step;
        
        // Show detailed logs if available
        if (status.logs && status.logs.length > 0) {
            const logsContainer = document.querySelector('.installation-logs');
            logsContainer.innerHTML = status.logs.map(log => 
                `<div class="log-entry log-${log.level}">${log.message}</div>`
            ).join('');
        }
    }
}

🚀 Performance Expectations

Marketplace Performance Metrics

Marketplace Operations Performance:
┌─────────────────────────┬──────────────┬────────────────┐
│ Operation               │ Target Time  │ Max Acceptable │
├─────────────────────────┼──────────────┼────────────────┤
│ Load marketplace page   │ <2 seconds   │ 5 seconds      │
│ Search servers          │ <500ms       │ 1 second       │
│ Server details view     │ <1 second    │ 2 seconds      │
│ Start installation      │ <3 seconds   │ 10 seconds     │
│ Complete installation   │ 2-10 minutes │ 30 minutes     │
│ Repository sync         │ 1-5 minutes  │ 15 minutes     │
│ Security scan           │ 30-120 sec   │ 5 minutes      │
└─────────────────────────┴──────────────┴────────────────┘

Installation Success Rates:
- Docker servers: >95% success rate
- Python servers: >90% success rate  
- Binary servers: >85% success rate
- Complex configurations: >80% success rate

Marketplace Scalability:
- Support for 10,000+ servers in catalog
- 100+ concurrent installations
- 50+ active repositories
- 1,000+ daily active users

🧭 Implementation Roadmap

Phase 1: Core Marketplace Infrastructure (Weeks 1-4)

  • Design and implement marketplace database schema
  • Create MarketplaceManager and RepositoryManager core components
  • Build basic repository connectors (HTTP, GitHub, Local)
  • Implement server catalog API endpoints
  • Create basic marketplace UI (browse, search, view details)

Phase 2: Installation System (Weeks 5-8)

  • Implement InstallationManager with Docker runtime support
  • Add Python venv runtime manager
  • Create installation wizard UI and progress tracking
  • Build server configuration management
  • Implement health monitoring for installed servers

Phase 3: Enterprise Features (Weeks 9-12)

  • Develop PolicyManager and approval workflows
  • Implement security scanning capabilities
  • Add enterprise repository support
  • Create admin policy configuration UI
  • Build audit logging and compliance reporting

Phase 4: Community Features (Weeks 13-16)

  • Implement review and rating system
  • Add community interaction features (helpful votes)
  • Create analytics and usage tracking
  • Build recommendation engine
  • Add server popularity and trending features

Phase 5: Advanced Features & DTX Foundation (Weeks 17-20)


🎯 Success Criteria

  • Marketplace catalog supports 1,000+ servers across multiple repositories
  • Installation success rate >90% for standard server types
  • Average installation time <5 minutes for typical servers
  • Repository sync completes in <10 minutes for 500+ servers
  • Search and filtering response time <500ms for 10,000+ servers
  • Enterprise approval workflow with <24 hour average response time
  • Community review system with moderation and quality controls
  • 99.9% uptime for marketplace API endpoints
  • Seamless integration with existing server management features
  • Extensible architecture supporting DTX and future extensions

🔗 Integration Points

Existing Gateway Integration

  • Server Management: Leverages existing ServerService for local server registration
  • Authentication: Uses current auth system for user permissions and policies
  • Admin UI: Extends existing admin interface with marketplace tabs
  • Health Monitoring: Integrates with current health check infrastructure
  • Metrics: Extends existing metrics collection for marketplace analytics

DTX Foundation (Issue #209)

  • Streamable-HTTP Protocol: Architecture supports DTX delivery mechanism
  • Enterprise Policies: Shared policy framework for DTX approval workflows
  • Installation Framework: Reusable installation patterns for DTX deployment
  • Repository Management: Extensible to support DTX-specific repositories
  • Admin UI Framework: Foundation for DTX marketplace interface

🧩 Additional Notes

  • 🏪 Marketplace Evolution: Starts with MCP servers, designed to support DTX and future extension types
  • 🔒 Security First: Built-in security scanning, approval workflows, and enterprise controls
  • 🚀 Performance: Optimized for large catalogs with intelligent caching and background sync
  • 👥 Community Driven: Review system encourages quality and helps users make informed decisions
  • 🔧 Extensible: Plugin architecture allows custom repository types and runtime managers
  • 📊 Analytics: Comprehensive tracking for usage patterns, popular servers, and system health
  • 🎛️ Enterprise Ready: Policies, approvals, audit logs, and compliance features for organization use
  • ⚡ Future Ready: Foundation architecture designed for DTX integration and ecosystem growth

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestpythonPython / backend development (FastAPI)triageIssues / Features awaiting triage

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions