Write a plugin
A plugin extends Speedwave with a containerized MCP worker accessible by Claude or with a bundled collection of resources (skills, commands, agents, and hooks). Plugins are authored, reviewed, and distributed exclusively through Speednet. If your plugin provides an MCP worker, startup conventions and tool definitions are covered in Write an MCP server.
Plugin structure and lifecycle
Section titled “Plugin structure and lifecycle”Developing a plugin involves preparing source files rather than a compiled package. You write a plugin.json manifest and, for MCP plugins, worker source code and container definitions. Speednet reviews the source and produces a signed ZIP archive, from which Speedwave builds container images locally from verified contents.
Plugin components
Section titled “Plugin components”A plugin.json manifest declaring a service_id, a Containerfile, and the worker source code. It may also include a claude-resources directory.
A plugin.json manifest without service_id or Containerfile declarations, accompanied by claude-resources (skills, commands, agents, and hooks). It does not require a worker container.
The manifest requires name, slug, version, and description fields. The slug serves as the primary identifier for installation directories, configuration keys, Docker Compose service names, worker environment variables, and token paths. It must match the pattern ^[a-z][a-z0-9-]{0,63}$ and cannot conflict with built-in services (slack, github, office), generated compose names (mcp-<slug>), or reserved keywords (e.g. claude). For MCP service plugins, service_id must match slug.
Optional fields include credential definitions (auth_fields), a settings schema (settings_schema), setup instructions (instructions), OAuth configuration (oauth), desktop application bridges (host_bridge), and resource constraints (mem_limit, cpu_limit). Validation requirements for all fields are detailed in Plugin mechanism.
Runtime execution model
Section titled “Runtime execution model”For MCP plugins, the Containerfile defines a worker that inherits Speedwave container hardening: dropped Linux capabilities, prevented privilege escalation, a read-only root filesystem, and a noexec tmpfs mounted at /tmp. These constraints are non-configurable, requiring workers to run unprivileged without writing to root filesystems, within maximum resource limits of 16 GiB RAM and 4 CPU cores. Speedwave automatically injects a reserved SPEEDWAVE_VERSION variable that plugins cannot modify.
Two mount points bridge the container boundary: /tokens (mounted read-only, where the worker reads credentials at /tokens/<key>) and /workspace (mounted read-write, providing the only persistent storage for worker state). Non-secret values declared in settings_schema are placed in /tokens/_settings.json in read-only mode; secret fields are excluded.
If a plugin authenticates via OAuth, declare the oauth configuration block. Speedwave’s internal oauth worker manages token acquisition and renewal, keeping long-lived secrets on the host and supplying only short-lived bearer tokens to the container. Speedwave supports three grant types: authorization_code (requires oauth.authorize_url), device_code (requires oauth.device_authorization_url), and client_credentials (requires oauth.client_secret_field). All endpoint URLs are validated before manifest acceptance.
Setup and distribution workflow
Section titled “Setup and distribution workflow”-
Prepare
plugin.json, theContainerfile(for MCP plugins), worker source code, and anyclaude-resources. -
Submit the source repository to Speednet for verification. Speednet builds the ZIP archive, signs it with an Ed25519 private key, and embeds a
SIGNATUREfile. -
Install the signed package in Speedwave, which verifies the cryptographic signature against its embedded Speednet public key.
-
Speedwave executes installation validation and builds the container image locally from verified files.
-
Enable the plugin in your project and provide required credentials. The Desktop interface displays saved non-secret parameters while maintaining secrets as write-only fields.
Before submitting code, test the worker locally: build the Containerfile, mount /tokens in read-only mode and /workspace in read-write mode, and confirm that the worker starts unprivileged against a read-only root filesystem. Speedwave enforces this exact configuration at runtime, so early verification prevents signing revision cycles.
Security boundaries
Section titled “Security boundaries”A plugin container can access its own /workspace and read its /tokens directory. It cannot modify credentials, escalate system privileges, or access token directories belonging to other plugins. Digital signatures are re-verified whenever compose definitions are generated, images are built, or plugins are listed in Desktop, preventing tampered packages from loading. Manifest properties cannot disable these security boundaries.
For complete information on signature verification, schemas, and storage architecture, see Plugin mechanism.