Creating Plugins
January 25, 2026 ยท View on GitHub
๐ Recommended: Use Plugin Templates
The fastest and easiest way to create a plugin is to use the provided templates. Templates include all necessary boilerplate, build configuration, and documentation out of the box.
Check out our example plugins for insight.
Note: Prior versions of hyper-mcp used a different plugin interface (v1). While this plugin interface is still supported, new plugins should use the v2 interface.
Quick Start with Templates (Recommended Method)
The recommended way to create a new plugin:
-
Browse available templates in
templates/plugins/ -
Copy the template for your language:
cp -r templates/plugins/rust/ ../my-plugin/ cd ../my-plugin/ -
Follow the template README - each template includes comprehensive setup instructions, examples, and best practices
-
Customize and implement your plugin logic
-
Build and publish using the provided
Dockerfile
See Plugin Templates Documentation for complete details and language options.
Using XTP (Alternative Method)
If you prefer to use the XTP CLI tool:
-
Install the XTP CLI:
curl https://static.dylibso.com/cli/install.sh -s | bash -
Create a new plugin project:
xtp plugin init --schema-file xtp-plugin-schema.yamlFollow the prompts to set up your plugin. This will create the necessary files and structure.
For example, if you chose Rust as the language, it will create a
Cargo.toml,src/lib.rsand asrc/pdk.rsfile. -
Implement your plugin logic in the language appropriate files(s) created (e.g. -
Cargo.tomlandsrc/lib.rsfor Rust) For example, if you chose Rust as the language you will need to update theCargo.tomlandsrc/lib.rsfiles.Be sure to modify the
.gitignorethat is created for you to allow committing yourCargo.lockfile.
Publishing Plugins
The OCI loader accepts two types of artifacts:
- ORAS artifacts (preferred method) - using
application/vnd.hyper-mcp.plugin.v2artifact type - Docker images - must be
linux/amd64architecture
Both methods must be signed using cosign for supply chain security.
Method 1: ORAS Artifacts (Recommended)
ORAS artifacts are the preferred method as they are more efficient and purpose-built for distributing WebAssembly plugins.
Build the WebAssembly binary separately, then package it as an ORAS artifact
Example workflow (see rstime-plugin):
- name: Install ORAS
uses: oras-project/setup-oras@v1
- name: Install cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad
- name: ORAS login to GHCR
shell: bash
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | oras login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Push ORAS artifact (plugin.wasm)
shell: bash
run: |
oras push "ghcr.io/your-org/your-plugin:$TAG" \
--artifact-type application/vnd.hyper-mcp.plugin.v2 \
./plugin.wasm:application/wasm
- name: Resolve digest
id: digest
shell: bash
run: |
DIGEST="$(
oras manifest fetch "ghcr.io/your-org/your-plugin:$TAG" --descriptor \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["digest"])'
)"
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"
- name: Sign ORAS artifact by digest
shell: bash
run: |
cosign sign --yes "ghcr.io/your-org/your-plugin@${{ steps.digest.outputs.digest }}"
Method 2: Docker Images
Docker images must target linux/amd64 architecture. Build the WebAssembly binary separately, then package it in a minimal container.
Efficient Dockerfile (see time-plugin):
FROM scratch
WORKDIR /
# plugin.wasm must be present in the Docker build context
COPY plugin.wasm /plugin.wasm
Example workflow (see time-plugin release workflow):
- name: Install cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push image (linux/amd64)
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64
provenance: false
tags: ghcr.io/your-org/your-plugin:$TAG
- name: Resolve digest
id: digest
shell: bash
run: |
DIGEST="$(
docker buildx imagetools inspect "ghcr.io/your-org/your-plugin:$TAG" \
--format '{{json .Manifest}}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["digest"])'
)"
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"
- name: Sign by digest
shell: bash
run: |
cosign sign --yes "ghcr.io/your-org/your-plugin@${{ steps.digest.outputs.digest }}"
Building the WebAssembly Binary
For all plugins, build the WebAssembly binary before packaging.
Rust
# Install wasm32-wasip1 target
rustup target add wasm32-wasip1
# Install cargo-auditable for supply chain security
cargo install cargo-auditable
# Build the plugin
cargo fetch
cargo auditable build --release --target wasm32-wasip1
# Copy to build context
cp target/wasm32-wasip1/release/plugin.wasm ./plugin.wasm
Supply Chain Security
All plugins must be signed with cosign. This ensures:
- Authenticity: Verify the plugin came from the claimed source
- Integrity: Detect tampering or corruption
- Transparency: Audit trail via Sigstore's transparency log
Always reference artifacts by digest (not tags) for immutable, verifiable deployments:
ghcr.io/your-org/your-plugin@sha256:abc123...
Users can verify the signature:
cosign verify \
--certificate-identity-regexp "https://github.com/your-org/your-plugin/.github/workflows/release.yml@refs/tags/v*" \
--certificate-oidc-issuer-regexp "https://token.actions.githubusercontent.com" \
ghcr.io/your-org/your-plugin@sha256:...
Next Steps
- ๐ Plugin Templates Documentation - Comprehensive guide to using templates
- ๐ Rust Plugin Template - Complete Rust plugin setup and development guide
- ๐ Example Plugins - Working examples to learn from
- ๐ MCP Protocol Specification - Protocol details and specifications
- โ๏ธ Extism Documentation - Plugin runtime and PDK documentation