docs: clarify plugin inheritance in README
Some checks are pending
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / test (push) Waiting to run
CI / build (push) Blocked by required conditions
CI / package (push) Blocked by required conditions

Rewrite the Plugin System section to make the extends/inheritance
mechanism clear — show that default extends gate + content-pipeline,
explain hook inheritance and conflict resolution rules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-03-08 15:05:12 +00:00
parent 13e256aa0c
commit 25903a6d20

View File

@@ -149,29 +149,46 @@ mcpctl apply -f state.yaml
## Plugin System (ProxyModel) ## Plugin System (ProxyModel)
ProxyModel is mcpctl's plugin system. Each project is assigned a **plugin** that controls how Claude interacts with its servers. Plugins are composed from two layers: **TypeScript plugins** (MCP middleware hooks) and **YAML pipelines** (content transformation stages). ProxyModel is mcpctl's plugin system. Each project is assigned a **plugin** that controls how Claude interacts with its servers.
There are two layers:
- **Plugins** — TypeScript hooks that intercept MCP requests/responses (gating, tool filtering, etc.)
- **Pipelines** — YAML-defined content transformation stages (pagination, summarization, etc.)
### Built-in Plugins ### Built-in Plugins
| Plugin | Includes gating | Content pipeline | Description | Plugins compose through inheritance. A plugin can `extend` another plugin and inherit all its hooks:
```
gate → gating only (begin_session + prompt delivery)
content-pipeline → content transformation only (pagination, section-split)
default → extends both gate AND content-pipeline (inherits all hooks from both)
```
| Plugin | Gating | Content pipeline | Description |
|--------|:-:|:-:|---| |--------|:-:|:-:|---|
| **default** | Yes | Yes | Gate + content pipeline. The default for all projects. | | **gate** | Yes | No | `begin_session` gate with prompt delivery |
| **gate** | Yes | No | Gating only — `begin_session` gate with prompt delivery. | | **content-pipeline** | No | Yes | Content transformation (paginate, section-split) |
| **content-pipeline** | No | No | Content transformation only — no gating. | | **default** | Yes | Yes | Extends both — gate + content pipeline combined |
The `default` plugin doesn't reimplement anything — it inherits the gating hooks from `gate` and the content hooks from `content-pipeline`. Custom plugins can extend built-in ones the same way.
**Gating** means Claude initially sees only a `begin_session` tool. After calling it with a task description, relevant prompts are delivered and the full tool list is revealed. This keeps Claude's context focused. **Gating** means Claude initially sees only a `begin_session` tool. After calling it with a task description, relevant prompts are delivered and the full tool list is revealed. This keeps Claude's context focused.
```bash ```bash
# Create a gated project (default behavior) # Gated with content pipeline (default — extends gate + content-pipeline)
mcpctl create project home --server my-ha --proxy-model default mcpctl create project home --server my-ha --proxy-model default
# Create an ungated project (direct tool access, no gate) # Ungated, content pipeline only
mcpctl create project tools --server grafana --proxy-model content-pipeline mcpctl create project tools --server my-grafana --proxy-model content-pipeline
# Gated only, no content transformation
mcpctl create project docs --server my-docs --proxy-model gate
``` ```
### Plugin Hooks ### Plugin Hooks
TypeScript plugins intercept MCP requests/responses at specific lifecycle points: Plugins intercept MCP requests/responses at specific lifecycle points. When a plugin extends another, it inherits all the parent's hooks. If both parent and child define the same hook, the child's version wins.
| Hook | When it fires | | Hook | When it fires |
|------|--------------| |------|--------------|
@@ -186,7 +203,7 @@ TypeScript plugins intercept MCP requests/responses at specific lifecycle points
| `onPromptsList` | `prompts/list` — can filter prompts | | `onPromptsList` | `prompts/list` — can filter prompts |
| `onPromptGet` | `prompts/get` — can intercept prompt reads | | `onPromptGet` | `prompts/get` — can intercept prompt reads |
Plugins compose via `extends` — the `default` plugin extends both `gate` and `content-pipeline`, inheriting all their hooks. When multiple parents define the same hook, lifecycle hooks (`onSessionCreate`, `onSessionDestroy`) chain sequentially. All other hooks require the child to override — otherwise it's a conflict error.
### Content Pipelines ### Content Pipelines