Skip to content

[FEATURE]: Plugin bundling, catalog, installation and versioning #9

@tedhabeck

Description

@tedhabeck

Summary

implement a comprehensive plugin catalog and versioning system for the CPEX framework that enables:

Version Management: Support multiple versions of the same plugin
Easy Installation: Install plugins from PyPI or Git repositories
Configuration Instantiation: Create multiple plugin instances from a single manifest

Plugin Manifest and Versioning System

Key Components

1. PluginPackageInfo

Location: src/cpex/framework/models.py

Defines how to install a plugin:

  • pypi_package: Install from PyPI (e.g., "cpex-pii-filter")
  • git_repository: Install from Git (e.g., "https://github.com/example/plugin.git")
  • git_branch/tag/commit: Specify which version to clone
  • version_constraint: Semantic version constraints (e.g., ">=1.0.0,<2.0.0")

2. PluginManifest

Location: src/cpex/framework/models.py

Acts as a plugin template/catalog entry:

  • Display Information: name, description, author, license, homepage
  • Capabilities: available_hooks, default_config
  • Installation: package_info
  • Methods:
    • suggest_instance_name(): Converts display name to safe identifier
    • create_instance_config(): Creates a PluginConfig instance with overrides

3. PluginConfig

Location: src/cpex/framework/models.py

Represents a configured plugin instance:

  • Each instance has a unique name (e.g., "pii_filter_production")
  • References the plugin type via kind
  • Overrides default_config with custom settings
  • Multiple instances can reference the same manifest

4. PluginVersionInfo

Location: src/cpex/framework/models.py

Metadata for a specific plugin version:

  • version: Semantic version string
  • released: Release date
  • breaking_changes: Breaking change indicator
  • deprecated: Deprecation flag
  • manifest_file: Path to version-specific manifest
  • changelog: Release notes
  • min/max_framework_version: Framework compatibility

5. PluginVersionRegistry

Location: src/cpex/framework/models.py

Registry of all available versions for a plugin:

  • latest: Latest stable version
  • latest_prerelease: Latest pre-release version
  • versions: List of all available versions
  • Methods:
    • get_version(): Get specific version info
    • get_latest_compatible(): Find compatible version for framework

Relationship Between Components

PluginManifest (Template/Type)
       ↓
  [Installation via PluginPackageInfo]
       ↓
  [Multiple PluginConfig Instances]
       ↓
  pii_filter_production  (mode=enforce, strict settings)
  pii_filter_development (mode=permissive, relaxed settings)

Catalog Structure

plugin-catalog/
├── pii-filter/
│   ├── plugin-manifest.yaml              # Latest version (auto-updated)
│   ├── plugin-manifest-1.0.0.yaml        # v1.0.0 pinned
│   ├── plugin-manifest-2.0.0.yaml        # v2.0.0 pinned
│   ├── plugin-manifest-2.1.0.yaml        # v2.1.0 pinned
│   └── versions.json              # PluginVersionRegistry
├── openai-moderation/
│   ├── plugin-manifest.yaml
│   └── versions.json
└── opa-filter/
    ├── plugin-manifest.yaml
    └── versions.json

Example Workflows

1. Plugin Developer Releases New Version

# 1. Update code and increment version
# 2. Create version-specific manifest
cp plugin-manifest.yaml plugin-manifest-2.1.0.yaml
sed -i 's/version: .*/version: "2.1.0"/' plugin-manifest-2.1.0.yaml

# 3. Update versions.json (add new version entry)
# 4. Update plugin-manifest.yaml to latest
cp plugin-manifest-2.1.0.yaml plugin-manifest.yaml

# 5. Publish to PyPI
python -m build
twine upload dist/*

# 6. Tag in Git
git tag v2.1.0
git push origin v2.1.0

3. User Creates Multiple Plugin Instances

from mcpgateway.plugin.framework.models import PluginManifest, PluginMode
import yaml

# Load manifest
with open("plugin-catalog/pii-filter/plugin-manifest.yaml") as f:
    manifest_data = yaml.safe_load(f)
    manifest = PluginManifest(**manifest_data)

# Create production instance
prod_config = manifest.create_instance_config(
    instance_name="pii_filter_production",
    mode=PluginMode.ENFORCE,
    priority=10,
    config={
        "mask_strategy": "full",
        "detect_ssn": True,
        "detect_credit_card": True
    }
)

# Create development instance
dev_config = manifest.create_instance_config(
    instance_name="pii_filter_development",
    mode=PluginMode.PERMISSIVE,
    priority=50,
    config={
        "mask_strategy": "partial",
        "detect_ssn": True,
        "detect_credit_card": False
    }
)

# Add to config.yaml

Configuration Examples

User's config.yaml with Multiple Instances

plugins:
  # Production instance - strict enforcement
  - name: "pii_filter_production"
    kind: "cpex.plugins.pii.PIIFilterPlugin"
    version: "2.1.0"
    description: "PII filter for production with strict settings"
    hooks:
      - prompt_pre_fetch
      - tool_pre_invoke
    mode: enforce
    priority: 10
    config:
      detect_ssn: true
      detect_credit_card: true
      detect_email: true
      mask_strategy: "full"
      compliance_mode: "gdpr"
    conditions:
      - tenant_ids: ["production"]

  # Development instance - permissive mode
  - name: "pii_filter_development"
    kind: "cpex.plugins.pii.PIIFilterPlugin"
    version: "2.1.0"
    description: "PII filter for development with logging only"
    hooks:
      - prompt_pre_fetch
    mode: permissive
    priority: 50
    config:
      detect_ssn: true
      detect_credit_card: false
      mask_strategy: "partial"
      log_violations: true
    conditions:
      - tenant_ids: ["development", "staging"]

Design Sketch (optional)

Include a diagram, sketch, or flow (use Mermaid if desired):

Metadata

Metadata

Assignees

Labels

Projects

Status

In progress

Relationships

None yet

Development

No branches or pull requests

Issue actions