Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 163 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CLAUDE.md
# AGENTS.md

## Git

Expand All @@ -8,11 +8,171 @@

This is a monorepo of standalone plugin packages for the ContextForge Plugin Extensibility (CPEX) Framework. Each plugin lives in its own top-level directory with independent build configuration.

- Plugins are Rust+Python (PyO3/maturin) or pure Python.
- Plugins are implemented as **pure Python** or **pure Rust**. Each plugin uses one language for its core logic — there is no dual-path where a plugin ships both Rust and Python implementations with a Rust fallback. For Rust plugins, Python entry points (PyO3/maturin) are a packaging and distribution layer only, not a parallel implementation.
- Each plugin has its own `pyproject.toml`, `Cargo.toml`, `Makefile`, and `tests/`.
- Package names follow the pattern `cpex-<plugin-name>` (e.g., `cpex-rate-limiter`).
- `mcpgateway` is a runtime dependency provided by the host gateway — never declare it in `pyproject.toml`.

## Testing Strategy

### Test Location by Type

- **Unit tests**: Located within each plugin's own directory
- Python: `plugins/rust/python-package/<slug>/tests/` (current hybrid) or `plugins/python/<slug>/tests/` (pure Python)
- Rust: inline `mod tests` within source files (e.g., `src/lib.rs`)
- Test individual plugin functionality in isolation
- Fast, deterministic tests
- Run during plugin development and CI
- Scope: Plugin logic, Rust functions, Python bindings

- **Plugin-framework integration tests**: Located in `plugins/rust/python-package/<slug>/tests/`
- Test plugin integration with the local plugin framework (PyO3 bindings, Python ↔ Rust interface)
- Run via `make test-integration` within the plugin directory
- Scope: PyO3 entry points, plugin loading by the Python framework, hook dispatch

- **Gateway integration tests**: Located in `mcp-context-forge/tests/integration/`
- Test plugin integration with the full gateway
- Test cross-plugin interactions
- Test plugin lifecycle management
- Scope: Plugin loading in gateway context, hook execution, framework interaction

- **E2E tests**: Located in `mcp-context-forge/tests/e2e/`
- Test complete workflows with plugins enabled
- Test plugin behavior in realistic scenarios
- Test multi-gateway plugin coordination
- Scope: Full request/response cycles, real-world usage patterns

### Cross-Repository Testing Coordination

When developing a plugin:

1. Write unit tests in the plugin's own directory (Rust: inline `mod tests`; Python: `plugins/rust/python-package/<slug>/tests/`) and plugin-framework integration tests in `plugins/rust/python-package/<slug>/tests/`
2. Run local tests: `make test-all` and `make test-integration` from plugin directory
3. After plugin PR is merged, coordinate with `mcp-context-forge` team
4. Write gateway integration/E2E tests in `mcp-context-forge/tests/`
5. Ensure both repositories' CI passes before release

See `mcp-context-forge/tests/AGENTS.md` for integration/E2E test conventions.

## Plugin Development Workflows

### Current Workflow: Rust + Python Hybrid

**Architecture:**
- Plugin logic implemented entirely in Rust — no Python fallback implementation
- Python entry points (PyO3/maturin) are a packaging and distribution layer only
- Published as Python packages to PyPI
- Loaded by Python-based plugin framework in gateway

**Why Python Entry Points?**
The plugin framework is currently implemented in Python (`mcpgateway/plugins/framework/`). Python entry points allow the framework to discover and load plugins dynamically. This is a transitional packaging layer — all plugin logic remains in Rust. This is not a dual-path architecture.
Comment thread
msureshkumar88 marked this conversation as resolved.

**Development Steps:**

1. **Create Plugin** (in `cpex-plugins`):
```bash
cd cpex-plugins
make plugin-scaffold # Interactive plugin generator
```

2. **Implement Plugin** (in `cpex-plugins/plugins/rust/python-package/<slug>/`):
- Write Rust core logic in `src/`
- Implement Python bindings in `cpex_<slug>/plugin.py`
- Update `plugin-manifest.yaml`

3. **Write Tests**:
```bash
cd plugins/rust/python-package/<slug>
# Add Rust unit tests inline in src/ using mod tests
# Add Python unit tests in tests/
# Add plugin-framework integration tests in tests/ (run via make test-integration)
make test-all # Run Rust + Python unit tests
make test-integration # Run plugin-framework integration tests
```

4. **Build and Install**:
```bash
uv sync --dev
make install # Build Rust extension and install
```

5. **Create PR in cpex-plugins**:
- Include unit tests and plugin-framework integration tests
- Ensure `make ci` passes
- Tag release: `<slug>-v<version>`

6. **Gateway Integration Testing** (in `mcp-context-forge`):
- Install plugin: `pip install cpex-<slug>`
- Configure in `plugins/config.yaml`
- Write integration tests in `tests/integration/`
- Write E2E tests in `tests/e2e/`

7. **Release**:
- Tag in cpex-plugins triggers PyPI publish
- Update mcp-context-forge dependencies
- Deploy with new plugin version

### Future Workflow: Pure Rust

**Architecture (Post-Framework Migration):**
- Plugins implemented in pure Rust
- Plugin framework migrated to Rust
- No Python entry points needed
- Direct Rust-to-Rust plugin loading
- Published to Cargo registry

**What Changes:**
- Remove `pyproject.toml` and maturin configuration
- Remove Python entry points (`cpex_<slug>/plugin.py`)
- Remove PyO3 bindings
- Pure Rust crate structure: `plugins/rust/<slug>/`
- Cargo-based dependency management

**Development Steps (Future):**

1. **Create Plugin** (in `cpex-plugins`):
```bash
cd cpex-plugins
cargo new --lib plugins/rust/<slug>
```

2. **Implement Plugin** (in `cpex-plugins/plugins/rust/<slug>/`):
- Write Rust plugin in `src/lib.rs`
- Implement plugin traits from Rust framework
- Update `Cargo.toml`

3. **Write Unit Tests** (inline `mod tests` in source files):
```bash
cd plugins/rust/<slug>
cargo test # Run Rust tests
```

4. **Build**:
```bash
cargo build --release
```

5. **Create PR in cpex-plugins**:
- Include unit tests
- Ensure `cargo test` passes
- Version in `Cargo.toml`

6. **Integration Testing** (in `mcp-context-forge`):
- Add plugin as Cargo dependency
- Configure in Rust plugin framework
- Write integration tests in `tests/integration/`
- Write E2E tests in `tests/e2e/`

7. **Release**:
- Publish to Cargo registry
- Update mcp-context-forge `Cargo.toml`
- Deploy with new plugin version

**Migration Timeline:**
- Current: Hybrid Rust + Python (transitional)
- Future: Pure Rust (after framework migration)
- Python components will be removed in future releases

## Build & Test

From within a plugin directory (e.g., `rate_limiter/`):
Expand Down Expand Up @@ -41,4 +201,4 @@ When bumping a plugin version, update all of these:
2. `cpex_<plugin>/plugin-manifest.yaml` — the `version` field.
3. `Cargo.lock` — updates automatically on the next build.

Tag releases as `<plugin>-v<version>` (e.g., `rate-limiter-v0.0.2`) on `main` to trigger the PyPI publish workflow.
Tag releases as `<plugin>-v<version>` (e.g., `rate-limiter-v0.0.2`) on `main` to trigger the PyPI publish workflow.
78 changes: 78 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,42 @@ Python integration tests live under `plugins/tests/<slug>/`; Rust unit tests liv

Rust crates are owned by the top-level workspace in `Cargo.toml`. Python package names follow `cpex-<slug>`, Python modules follow `cpex_<slug>`, plugin manifests must declare a top-level `kind` in `module.object` form, and `pyproject.toml` must publish the matching `module:object` reference under `[project.entry-points."cpex.plugins"]`. Release tags use the hyphenated slug form `<slug-with-hyphens>-v<version>`, for example `rate-limiter-v0.0.2`.

## Testing Strategy

Testing spans two repositories:

- **Unit tests**: within each plugin's own directory — Python in `plugins/rust/python-package/<slug>/tests/`, Rust inline via `mod tests` in source files
- **Plugin-framework integration tests**: `plugins/rust/python-package/<slug>/tests/` — test PyO3 bindings and plugin loading by the Python framework (`make test-integration`)
- **Gateway integration tests**: `mcp-context-forge/tests/integration/` — test plugin integration with the full gateway
- **E2E tests**: `mcp-context-forge/tests/e2e/` — test complete workflows with plugins

Unit tests and plugin-framework integration tests live in the plugin's own directory. Gateway integration and E2E tests live in `mcp-context-forge`.

See [TESTING.md](TESTING.md) for detailed testing guidelines and cross-repository coordination.

## Plugin Development

### Current Architecture (Transitional)

Plugins are implemented as **pure Python** or **pure Rust** — each plugin uses one language for its logic. There is no dual-path where a plugin ships both Rust and Python implementations with a Rust fallback.

For Rust plugins, the current approach wraps the Rust implementation with PyO3/maturin bindings as a packaging layer:
- Plugin logic implemented entirely in Rust
- Python entry points (PyO3/maturin) are a packaging and distribution layer only, not a parallel implementation
- Published as Python packages to PyPI
- Loaded by Python-based plugin framework in `mcp-context-forge`

### Future Architecture

After the plugin framework is migrated to Rust:
- Plugins will be **pure Rust** implementations
- No Python entry points needed
- Direct Rust-to-Rust plugin loading
- Published to Cargo registry

See [DEVELOPING.md](DEVELOPING.md) for detailed workflows for both current and future development.


## Creating a New Plugin

Use the plugin scaffold generator to create a new plugin with all required files and structure:
Expand Down Expand Up @@ -68,3 +104,45 @@ make plugin-scaffold # Create new plugin (interactive)
```

The catalog and validator used by CI live in `tools/plugin_catalog.py`.

## Quick Start

### Develop a Plugin

```bash
cd plugins/rust/python-package/<slug>
uv sync --dev # Install dependencies
make install # Build Rust extension
make test-all # Run unit tests
```

### Plugin-Framework Integration Testing

After unit tests pass, run plugin-framework integration tests within `cpex-plugins`:

```bash
cd plugins/rust/python-package/<slug>
make test-integration # Test PyO3 bindings and framework loading
```

### Gateway Integration Testing

After the plugin PR is merged, coordinate with `mcp-context-forge`:

```bash
cd mcp-context-forge
pip install /path/to/cpex-plugins/plugins/rust/python-package/<slug>
# Configure plugin in plugins/config.yaml
pytest tests/integration/ # Run gateway integration tests
pytest tests/e2e/ # Run E2E tests
```

See [TESTING.md](TESTING.md) for cross-repository testing workflow.

## Documentation

- [AGENTS.md](AGENTS.md) - AI coding assistant guidelines
- [DEVELOPING.md](DEVELOPING.md) - Plugin development workflows
- [TESTING.md](TESTING.md) - Testing strategy and guidelines
- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines
- [SECURITY.md](SECURITY.md) - Security policy
Loading
Loading