|
| 1 | +# Plugin Lifecycle |
| 2 | + |
| 3 | +The plugin framework includes CLI tools to help you create, test, and deploy your plugins. |
| 4 | + |
| 5 | +## Development Flow |
| 6 | + |
| 7 | +```mermaid |
| 8 | +flowchart LR |
| 9 | +
|
| 10 | + A["template"] |
| 11 | + B(["$> bootstrap"]) |
| 12 | + C(["$> build"]) |
| 13 | + D(["$> serve"]) |
| 14 | +
|
| 15 | + subgraph dev |
| 16 | + A -.-> B |
| 17 | + end |
| 18 | +
|
| 19 | + subgraph deploy |
| 20 | + C --> D |
| 21 | + end |
| 22 | +
|
| 23 | + B --> C |
| 24 | +
|
| 25 | + style A stroke-dasharray: 3 3; |
| 26 | +``` |
| 27 | + |
| 28 | +### Bootstrap |
| 29 | + |
| 30 | +Creating a new plugin for Context Forge only takes a few minutes! |
| 31 | + |
| 32 | +Using the `mcpplugins` tool (installed with Context Forge), |
| 33 | + |
| 34 | +```bash |
| 35 | +mcpplugins bootstrap --destination your/plugin/dir |
| 36 | +``` |
| 37 | + |
| 38 | +The interactive prompt you guide you to enter plugin metadata, and will boostrap a complete plugin project for you including everything you need to kick the tires writing your new plugin. |
| 39 | + |
| 40 | +For a full list of options, check: |
| 41 | + |
| 42 | +```bash |
| 43 | +mcpplugins bootstrap --help |
| 44 | +``` |
| 45 | + |
| 46 | +!!! tip |
| 47 | + When prompted for the choosing the plugin type, select `external` to create standalone plugins (with their own lock files and dependency trees). |
| 48 | + Select `native` if you want to create a plugin that embeds and gets loaded directly into the gateway environment. |
| 49 | + |
| 50 | + |
| 51 | +The examples under the `plugins` directory in the gateway repository serve as a guide of how to develop and test `native` plugins. |
| 52 | + |
| 53 | +The following instructions apply to `external` plugins. First, change directory to work with your newly bootstrapped plugin: |
| 54 | + |
| 55 | +```bash |
| 56 | +cd your/plugin/dir |
| 57 | +cp .env.template .env |
| 58 | +``` |
| 59 | + |
| 60 | +### Configuration |
| 61 | + |
| 62 | +There are two main configuration files for your project. |
| 63 | + |
| 64 | +```bash |
| 65 | +./resources |
| 66 | + /plugins/config.yaml # configuration for your plugin and the plugin loader |
| 67 | + /runtime/config.yaml # configuration for the plugin server runtime |
| 68 | +``` |
| 69 | + |
| 70 | +Inspect those two files and get familiar with them. There are many options you can customize, depending on your use case. |
| 71 | + |
| 72 | +### Dependencies |
| 73 | + |
| 74 | +Plugins are Python packages with dependencies managed by `uv`. Just like the gateway, you can add, lock, lint, and ensure that best practices are followed when creating your plugins. To ensure compatibility with the gateway linters, we do not directly install them in the template. Instead, please install the gateway package with the dev extras, which will include all required linters. |
| 75 | + |
| 76 | +### Test |
| 77 | + |
| 78 | +To run all unit tests for your plugins: |
| 79 | + |
| 80 | +```bash |
| 81 | +make test |
| 82 | +``` |
| 83 | + |
| 84 | +### Build |
| 85 | + |
| 86 | +To build a container image (runtime) containing a standardized plugin server, run: |
| 87 | + |
| 88 | +```bash |
| 89 | +make build |
| 90 | +``` |
| 91 | + |
| 92 | +### Serve |
| 93 | + |
| 94 | +To start the plugin server: |
| 95 | + |
| 96 | +```bash |
| 97 | +make start |
| 98 | +``` |
| 99 | + |
| 100 | +By default, this will start a Streamable HTTP MCP server on `http://localhost:8000/mcp`. |
| 101 | + |
| 102 | +You can run `mcp inspector` to check your new server (note, it requires `npm`): |
| 103 | + |
| 104 | +```bash |
| 105 | +npx @modelcontextprotocol/inspector |
| 106 | +``` |
| 107 | + |
| 108 | +## Gateway Integration |
| 109 | + |
| 110 | +Let's assume you have boostrapped the following plugin (`resources/plugins/config.yaml`) with default runtime (`resources/runtime/config.yaml`) options: |
| 111 | + |
| 112 | +```yaml |
| 113 | +plugins: |
| 114 | + - name: "MyFilter" |
| 115 | + kind: "myfilter.plugin.MyFilter" |
| 116 | + description: "A filter plugin" |
| 117 | + version: "0.1.0" |
| 118 | + author: "Frederico Araujo" |
| 119 | + hooks: ["prompt_pre_fetch", "prompt_post_fetch", "tool_pre_invoke", "tool_post_invoke"] |
| 120 | + tags: ["plugin"] |
| 121 | + mode: "enforce" # enforce | permissive | disabled |
| 122 | + priority: 150 |
| 123 | + conditions: |
| 124 | + # Apply to specific tools/servers |
| 125 | + - server_ids: [] # Apply to all servers |
| 126 | + tenant_ids: [] # Apply to all tenants |
| 127 | + config: |
| 128 | + # Plugin config dict passed to the plugin constructor |
| 129 | + |
| 130 | +# Plugin directories to scan |
| 131 | +plugin_dirs: |
| 132 | + - "myfilter" |
| 133 | + |
| 134 | +# Global plugin settings |
| 135 | +plugin_settings: |
| 136 | + parallel_execution_within_band: true |
| 137 | + plugin_timeout: 30 |
| 138 | + fail_on_plugin_error: false |
| 139 | + enable_plugin_api: true |
| 140 | + plugin_health_check_interval: 60 |
| 141 | +``` |
| 142 | +
|
| 143 | +To integrate this plugin with the gateway, all you need to do is copying the following configuration under the `plugins` list in the gateway's `plugins/config.yaml` file: |
| 144 | + |
| 145 | +```yaml |
| 146 | +plugins: |
| 147 | + # External Filter Plugin |
| 148 | + - name: "MyFilter" |
| 149 | + kind: "external" |
| 150 | + priority: 10 # adjust the priority |
| 151 | + mcp: |
| 152 | + proto: STREAMABLEHTTP |
| 153 | + url: http://localhost:8000/mcp |
| 154 | +``` |
| 155 | + |
| 156 | +Then, start the gateway: |
| 157 | + |
| 158 | +```bash |
| 159 | +make serve |
| 160 | +``` |
| 161 | + |
| 162 | +!!! note |
| 163 | + `PLUGINS_ENABLED=true` should be set in your gateway `.env` file. |
0 commit comments