What is Wassette?
Overview
Wassette is a secure, open-source Model Context Protocol (MCP) server that leverages WebAssembly (Wasm) to provide a trusted execution environment for untrusted tools. MCP is a standard how LLMs access and share data with external tools. By embedding a WebAssembly runtime and applying fine-grained security policies, Wassette enables safe execution of third-party MCP tools without compromising the host system.
Key Features
Wassette provides the following key features:
- Sandboxed tools using the WebAssembly Component Model
- Fine-grained permissions for file system, network, and system resources
- Developer-friendly approach that simplifies tool development by focusing on business logic rather than infrastructure complexity
Note: The name “Wassette” is a portmanteau of “Wasm” and “Cassette” (referring to magnetic tape storage), and is pronounced “Wass-ette”.
Problem Statement
The current landscape of MCP server deployment presents significant security challenges. Today’s common deployment patterns include standalone processes communicating via stdio or sockets, direct binary execution using package managers like npx
or uvx
, and container-based isolation providing basic security boundaries.
These approaches expose users to various security risks including unrestricted file system access where tools can read and write arbitrary files, network vulnerabilities through uncontrolled outbound connections to external services, code execution risks from malicious or vulnerable tools, and limited visibility making it difficult to monitor and audit tool behavior.
The fundamental issue is that current MCP servers run with the same privileges as the host process, creating an unacceptable attack surface for untrusted code execution.
Target Audience
Wassette serves four primary user groups:
- Application Developers who want to focus on business logic implementation with reduced infrastructure complexity and simplified deployment
- DevOps Engineers who benefit from platform-agnostic deployment capabilities, comprehensive observability and monitoring, and security-by-design architecture
- End Users who gain a trusted execution environment for third-party tools with transparent security policies and protection against malicious or vulnerable tools
- Platform Providers who can leverage Wassette’s serverless-ready architecture, consistent runtime environment, and scalable multi-tenant capabilities
Current Solutions Analysis
- Container-based isolation. This is perhaps the most common way to run MCP servers securely today, because it works with existing tooling and infrastructure and requires no changes to the server code. One could argue that containers are not a secure boundary, but they are a good starting point. The harder problem is how to apply security policies to the container like “how do I know what HTTP domain is this tool calling to?”. The Docker MCP Catalog runs each MCP server as a container - providing isolation and portability.
- Direct binary execution. Running binaries directly using
npx
oruvx
. This is a simple way to run MCP servers (and often the default way MCP servers document how to use it), but it is not secure. It is easy to run a tool that has a vulnerability or malicious code that can read/write files on your machine, open sockets, or even execute arbitrary code. - WebAssembly platforms. Centralized MCP server that runs WebAssembly-based tools locally (think tools like mcp.run). This has the advantage of running tools in tiny sandboxes which incur less memory overhead than containers. However, most of these tools still require custom ABIs and libraries and are not compatible with each other.
Wassette Solution
Design Philosophy
Wassette addresses the security and interoperability challenges of current MCP deployments by leveraging the WebAssembly Component Model. This approach provides strong security boundaries through WebAssembly’s sandboxed execution environment, capability-based access control with fine-grained permission management, tool interoperability via standardized component interfaces, transparent security through explicit capability declarations, and low resource overhead with efficient memory usage compared to containers.
Architecture Goals
Wassette implements a centralized trusted computing base (TCB) through a single, open-source MCP server implementation built with memory-safe, high-performance runtimes like Wasmtime, maintaining a minimal attack surface through reduced complexity.
The system enforces capability-based security with allow/deny lists for file system paths, network endpoint access control, system call restrictions, and a policy engine similar to policy-mcp-rs.
For secure distribution, WebAssembly components are distributed as OCI artifacts with cryptographic signature verification, registry-based tool distribution, and granular capability declarations per tool.
Example Permission Policy
version: "1.0"
description: "An example policy"
permissions:
storage:
allow:
- uri: "fs://workspace/**"
access: ["read", "write"]
- uri: "fs://config/app.yaml"
access: ["read"]
network:
allow:
- host: "api.openai.com"
Developer Experience
Developers will write MCP tools as functions that can be compiled to WebAssembly Components, instead of developing servers. This is a significant paradigm shift and offers a completely different experience than writing MCP servers as it currently stands. We are fully aware that current MCP server code would need to be rewritten for retargeting to Wasm but the security benefits and flexibility of the Component Model are worth it.
We are exploring AI tools that make porting existing MCP servers to Wasm easier, removing the biggest barrier to adoption.
Language Support
Wassette supports tools written in any language that can compile to WebAssembly Components. For current language support, see the WebAssembly Language Support Guide.
Wassette provides examples in JavaScript and Python, which are the most popular languages for MCP server development, see examples.
Install Wassette with Homebrew
This guide explains how to install wassette
using Homebrew.
This uses the Formula in Formula/wassette.rb
, which is setup to download and install the latest release of wassette
from GitHub.
You must have Homebrew installed on your macOS or Linux system. If you don’t, you can install it by following the instructions on the official Homebrew website.
Installation
You can install wassette
with a single command:
brew tap microsoft/wassette https://github.com/microsoft/wassette
brew install wassette
This command will automatically tap the microsoft/wassette
repository and install the wassette
formula.
Verifying the Installation
To make sure everything worked, you can run:
wassette --version
Upgrading
To upgrade wassette
to the latest version, first update Homebrew’s package list and then upgrade the wassette
package.
brew update
brew upgrade wassette
Nix
You can install Wassette using Nix flakes:
# Run directly without installation
nix run github:microsoft/wassette -- serve --stdio
# Install to your profile
nix profile install github:microsoft/wassette
# Or in a development shell
nix develop github:microsoft/wassette
This provides a reproducible environment for using and developing Wassette.
The flake provides a wassette
package and a development shell with all
the necessary dependencies.
Installing Wassette with WinGet
Wassette provides a WinGet package manifest for easy installation on Windows systems.
Installation
Since WinGet doesn’t support installing directly from URLs, you need to download the manifest first:
# Download the manifest
Invoke-WebRequest -Uri https://raw.githubusercontent.com/microsoft/wassette/main/winget/Microsoft.Wassette.yaml -OutFile Microsoft.Wassette.yaml
# Install from the downloaded manifest
winget install --manifest Microsoft.Wassette.yaml
If the installation fails, it is probably because the local installation feature is not enabled. You can activate it with the following command in an administrator shell:
winget settings --enable LocalManifestFiles
Verification
After installation, verify that Wassette is available:
wassette --version
Uninstall
To uninstall Wassette, use one of these commands:
# Try the simple name first
winget uninstall Wassette
If that doesn’t work, list installed packages to get the exact ID:
# List to find the exact package ID
winget list Wassette
# Use the exact ID (example output may vary)
winget uninstall "Wassette ARP\User\Arm64\Microsoft.Wassette__DefaultSource"
Next Steps
After installation, follow the MCP clients setup guide to configure Wassette with your AI agent of choice.
Model Context Protocol (MCP) Clients
If you haven’t installed Wassette yet, follow the installation instructions first.
Visual Studio Code
Add the Wassette MCP Server to GitHub Copilot in Visual Studio Code by clicking the Install in VS Code or Install in VS Code Insiders badge below:
Alternatively, you can add the Wassete MCP server to VS Code from the command line using the code
command in a bash/zsh or PowerShell terminal:
bash/zsh
code --add-mcp '{"name":"Wassette","command":"wassette","args":["serve","--stdio"]}'
PowerShell
code --% --add-mcp "{\"name\":\"wassette\",\"command\":\"wassette\",\"args\":[\"serve\",\"--stdio\"]}"
You can list and configure MCP servers in VS Code by running the command MCP: List Servers
in the command palette (Ctrl+Shift+P or Cmd+Shift+P).
Cursor
Click the below button to use the one-click installation to add Wassette to Cursor.
Claude Code
First, install Claude Code (requires Node.js 18 or higher):
npm install -g @anthropic-ai/claude-code
Add the Wassette MCP server to Claude Code using the following command:
claude mcp add -- wassette wassette serve --stdio
This will configure the Wassette MCP server as a local stdio server that Claude Code can use to execute Wassette commands and interact with your data infrastructure.
You can verify the installation by running:
claude mcp list
To remove the server if needed:
claude mcp remove wassette
Gemini CLI
First, install Gemini CLI (requires Node.js 20 or higher):
npm install -g @google/gemini-cli
To add the Wassette MCP server to Gemini CLI, you need to configure it in your settings file at ~/.gemini/settings.json
. Create or edit this file to include:
{
"mcpServers": {
"wassette": {
"command": "wassette",
"args": ["serve", "--stdio"]
}
}
}
Quit the Gemini CLI and reopen it.
Open Gemini CLI and verify the installation by running /mcp
inside of Gemini CLI.
Wassette CLI Reference
The Wassette command-line interface provides comprehensive tools for managing WebAssembly components, policies, and permissions both locally and through the MCP server. This document covers all CLI functionality and usage patterns.
Overview
Wassette offers two primary modes of operation:
- Server Mode: Run as an MCP server that responds to client requests
- CLI Mode: Direct command-line management of components and permissions
The CLI mode allows you to perform administrative tasks without requiring a running MCP server, making it ideal for automation, scripting, and local development workflows.
Installation
For installation instructions, see the main README. Once installed, the wassette
command will be available in your PATH.
Quick Start
# Check available commands
wassette --help
# List currently loaded components
wassette component list
# Load a component from an OCI registry
wassette component load oci://ghcr.io/yoshuawuyts/time:latest
# Load a component from a local file
wassette component load file:///path/to/component.wasm
# Start the MCP server (traditional mode)
wassette serve --stdio
Command Structure
Wassette uses a hierarchical command structure organized around functional areas:
wassette
├── serve # Start MCP server
├── component # Component lifecycle management
│ ├── load # Load components
│ ├── unload # Remove components
│ └── list # Show loaded components
├── policy # Policy information
│ └── get # Retrieve component policies
└── permission # Permission management
├── grant # Add permissions
├── revoke # Remove permissions
└── reset # Clear all permissions
Server Commands
wassette serve
Start the Wassette MCP server to handle client requests.
Stdio Transport (recommended for MCP clients):
# Start server with stdio transport
wassette serve --stdio
# Use with specific configuration directory
wassette serve --stdio --plugin-dir /custom/components
HTTP Transport (for development and debugging):
# Start server with HTTP transport
wassette serve --http
# Use Server-Sent Events (SSE) transport
wassette serve --sse
Options:
--stdio
: Use stdio transport (recommended for MCP clients)--http
: Use HTTP transport on 127.0.0.1:9001--sse
: Use Server-Sent Events transport--plugin-dir <PATH>
: Set component storage directory (default:$XDG_DATA_HOME/wassette/components
)
Component Management
wassette component load
Load a WebAssembly component from various sources.
Load from OCI registry:
# Load a component from GitHub Container Registry
wassette component load oci://ghcr.io/yoshuawuyts/time:latest
# Load with custom plugin directory
wassette component load oci://ghcr.io/microsoft/gomodule:latest --plugin-dir /custom/components
Load from local file:
# Load a local component file
wassette component load file:///path/to/component.wasm
# Load with relative path
wassette component load file://./my-component.wasm
Options:
--plugin-dir <PATH>
: Component storage directory
wassette component unload
Remove a loaded component by its ID.
# Unload a component
wassette component unload my-component-id
# Unload with custom plugin directory
wassette component unload my-component-id --plugin-dir /custom/components
Options:
--plugin-dir <PATH>
: Component storage directory
wassette component list
Display all currently loaded components.
Basic JSON output:
wassette component list
# Output: {"components":[...],"total":1}
Formatted output options:
# Pretty-printed JSON
wassette component list --output-format json
# YAML format
wassette component list --output-format yaml
# Table format (human-readable)
wassette component list --output-format table
Example outputs:
JSON format:
{
"components": [
{
"id": "time-component",
"schema": {
"tools": [
{
"name": "get-current-time",
"description": "Get the current time",
"inputSchema": {
"type": "object",
"properties": {}
}
}
]
},
"tools_count": 1
}
],
"total": 1
}
Table format:
ID | Tools | Description
---------------|-------|----------------------------------
time-component | 1 | Provides time-related functions
Options:
--output-format <FORMAT>
: Output format (json, yaml, table) [default: json]--plugin-dir <PATH>
: Component storage directory
Policy Management
wassette policy get
Retrieve policy information for a specific component.
# Get policy for a component
wassette policy get my-component-id
# Get policy with pretty formatting
wassette policy get my-component-id --output-format json
# Get in YAML format
wassette policy get my-component-id --output-format yaml
Example output:
{
"component_id": "my-component",
"permissions": {
"storage": [
{
"uri": "fs://workspace/**",
"access": ["read", "write"]
}
],
"network": [
{
"host": "api.openai.com"
}
]
}
}
Options:
--output-format <FORMAT>
: Output format (json, yaml, table) [default: json]--plugin-dir <PATH>
: Component storage directory
Permission Management
wassette permission grant
Grant specific permissions to a component.
Storage permissions:
# Grant read access to a directory
wassette permission grant storage my-component fs://workspace/ --access read
# Grant read and write access
wassette permission grant storage my-component fs://workspace/ --access read,write
# Grant access to a specific file
wassette permission grant storage my-component fs://config/app.yaml --access read
Network permissions:
# Grant access to a specific host
wassette permission grant network my-component api.openai.com
# Grant access to a localhost service
wassette permission grant network my-component localhost:8080
Environment variable permissions:
# Grant access to an environment variable
wassette permission grant environment-variable my-component API_KEY
# Grant access to multiple variables
wassette permission grant environment-variable my-component HOME
wassette permission grant environment-variable my-component PATH
Memory permissions:
# Grant memory limit to a component (using Kubernetes format)
wassette permission grant memory my-component 512Mi
# Grant larger memory limit
wassette permission grant memory my-component 1Gi
# Grant memory limit with different units
wassette permission grant memory my-component 2048Ki
Options:
--access <ACCESS>
: For storage permissions, comma-separated list of access types (read, write)--plugin-dir <PATH>
: Component storage directory
wassette permission revoke
Remove specific permissions from a component.
Storage permissions:
# Revoke storage access
wassette permission revoke storage my-component fs://workspace/
# Revoke with custom plugin directory
wassette permission revoke storage my-component fs://config/ --plugin-dir /custom/components
Network permissions:
# Revoke network access
wassette permission revoke network my-component api.openai.com
Environment variable permissions:
# Revoke environment variable access
wassette permission revoke environment-variable my-component API_KEY
Options:
--plugin-dir <PATH>
: Component storage directory
wassette permission reset
Remove all permissions for a component, resetting it to default state.
# Reset all permissions for a component
wassette permission reset my-component
# Reset with custom plugin directory
wassette permission reset my-component --plugin-dir /custom/components
Options:
--plugin-dir <PATH>
: Component storage directory
Common Workflows
Local Development
# 1. Build and load a local component
wassette component load file://./target/wasm32-wasi/debug/my-tool.wasm
# 2. Check it loaded correctly
wassette component list --output-format table
# 3. Grant necessary permissions
wassette permission grant storage my-tool fs://$(pwd)/workspace --access read,write
wassette permission grant network my-tool api.example.com
wassette permission grant memory my-tool 512Mi
# 4. Verify permissions
wassette policy get my-tool --output-format yaml
# 5. Test via MCP server
wassette serve --stdio
Component Distribution
# 1. Load component from OCI registry
wassette component load oci://ghcr.io/myorg/my-tool:v1.0.0
# 2. Configure permissions based on component needs
wassette permission grant storage my-tool fs://workspace/** --access read,write
wassette permission grant network my-tool api.myservice.com
wassette permission grant memory my-tool 1Gi
# 3. Start server for clients
wassette serve --sse
Permission Auditing
# List all components and their tool counts
wassette component list --output-format table
# Check permissions for each component
for component in $(wassette component list | jq -r '.components[].id'); do
echo "=== $component ==="
wassette policy get $component --output-format yaml
done
Cleanup Operations
# Reset permissions for a component
wassette permission reset problematic-component
# Remove a component entirely
wassette component unload problematic-component
# List remaining components
wassette component list --output-format table
Configuration
Wassette can be configured using configuration files, environment variables, and command-line options. The configuration sources are merged with the following order of precedence:
- Command-line options (highest priority)
- Environment variables prefixed with
WASSETTE_
- Configuration file (lowest priority)
Configuration File
By default, Wassette looks for a configuration file at:
- Linux/macOS:
$XDG_CONFIG_HOME/wassette/config.toml
(typically~/.config/wassette/config.toml
) - Windows:
%APPDATA%\wassette\config.toml
You can override the default configuration file location using the WASSETTE_CONFIG_FILE
environment variable:
export WASSETTE_CONFIG_FILE=/custom/path/to/config.toml
wassette component list
Example configuration file (config.toml
):
# Directory where components are stored
plugin_dir = "/opt/wassette/components"
Environment Variables
WASSETTE_CONFIG_FILE
: Override the default configuration file locationWASSETTE_PLUGIN_DIR
: Override the default component storage locationXDG_CONFIG_HOME
: Base directory for configuration files (Linux/macOS)XDG_DATA_HOME
: Base directory for data storage (Linux/macOS)
Component Storage
By default, Wassette stores components in $XDG_DATA_HOME/wassette/components
(typically ~/.local/share/wassette/components
on Linux/macOS). You can override this with the --plugin-dir
option:
# Use custom storage directory
export WASSETTE_PLUGIN_DIR=/opt/wassette/components
wassette component load oci://example.com/tool:latest --plugin-dir $WASSETTE_PLUGIN_DIR
Integration with MCP Clients
The CLI commands complement the MCP server functionality. You can:
- Use CLI commands to pre-configure components and permissions
- Start the MCP server with
wassette serve
- Connect MCP clients to the running server
- Use CLI commands for administrative tasks while the server runs
Example VS Code configuration:
{
"name": "wassette",
"command": "wassette",
"args": ["serve", "--stdio"]
}
Error Handling
The CLI provides clear error messages for common issues:
# Component not found
$ wassette component unload nonexistent
Error: Component 'nonexistent' not found
# Invalid path
$ wassette component load invalid://path
Error: Unsupported URI scheme 'invalid'. Use 'file://' or 'oci://'
# Permission denied
$ wassette permission grant storage my-component /restricted --access write
Error: Permission denied: cannot grant write access to /restricted
Output Formats
All commands that return structured data support multiple output formats:
- JSON (default): Machine-readable, suitable for scripting
- YAML: Human-readable structured format
- Table: Formatted for terminal display
Use the --output-format
or -o
flag to specify the desired format:
wassette component list -o table
wassette policy get my-component -o yaml
See Also
- Main README - Installation and basic usage
- MCP Client Setup - Configuring MCP clients
- Architecture Overview - Understanding Wassette’s design
- Examples - Sample WebAssembly components
Frequently Asked Questions (FAQ)
General Questions
What is Wassette?
Wassette is a secure, open-source Model Context Protocol (MCP) server that leverages WebAssembly (Wasm) to provide a trusted execution environment for untrusted tools. It enables safe execution of third-party MCP tools without compromising the host system by using WebAssembly’s sandboxed execution environment and fine-grained security policies.
Note: The name “Wassette” is a portmanteau of “Wasm” and “Cassette” (referring to magnetic tape storage), and is pronounced “Wass-ette”.
How is Wassette different from other MCP servers?
Traditional MCP servers run with the same privileges as the host process, creating security risks. Wassette addresses this by:
- Sandboxed execution: Tools run in WebAssembly’s secure sandbox, not directly on the host
- Fine-grained permissions: Explicit control over file system, network, and system resource access
- Component-based architecture: Uses the standardized WebAssembly Component Model for tool interoperability
- Centralized security: Single trusted computing base instead of multiple potentially vulnerable servers
What are WebAssembly Components?
WebAssembly Components are a standardized way to build portable, secure, and interoperable software modules. Unlike traditional WebAssembly modules, Components use the WebAssembly Component Model which provides:
- Standardized interfaces defined using WebAssembly Interface Types (WIT)
- Language interoperability - components can be written in any language that compiles to Wasm
- Composability - components can be combined and reused across different environments
Language and Development
What programming languages are supported?
Wassette supports tools written in any language that can compile to WebAssembly Components. For current language support, see the WebAssembly Language Support Guide.
The project includes examples in several popular languages:
- JavaScript (time-server-js, get-weather-js)
- Python (eval-py)
- Rust (fetch-rs, filesystem-rs)
- Go (gomodule-go)
Can I use existing WebAssembly modules with Wassette?
Wassette specifically requires WebAssembly Components (not just modules) that follow the Component Model. Existing Wasm modules would need to be adapted to use the Component Model’s interface system.
How do I create a Wasm component?
- Define your interface using WebAssembly Interface Types (WIT)
- Implement the functionality in your preferred supported language
- Compile to a Component using appropriate tooling for your language
- Test with Wassette by loading the component
See the examples directory for complete working examples in different languages.
Do I need to rewrite existing MCP servers?
Yes, existing MCP servers would need to be rewritten to target wasip2
(WebAssembly Components). This is a significant paradigm shift from writing servers to writing functions that compile to Wasm Components. However, the security benefits and flexibility of the Component Model make this worthwhile.
The project is exploring AI tools to help port existing MCP servers to Wasm, which should reduce the migration effort.
Security and Permissions
How does Wassette’s security model work?
Wassette implements a capability-based security model with:
- Sandbox isolation: All tools run in WebAssembly’s secure sandbox
- Explicit permissions: Components must declare what resources they need access to
- Allow/deny lists: Fine-grained control over file system paths, network endpoints, etc.
- Principle of least privilege: Components only get the permissions they explicitly need
What is a policy file?
A policy file (policy.yaml
) defines what permissions a component has. Example:
version: "1.0"
description: "Permission policy for filesystem access"
permissions:
storage:
allow:
- uri: "fs://workspace/**"
access: ["read", "write"]
- uri: "fs://config/app.yaml"
access: ["read"]
network:
allow:
- host: "api.openai.com"
Can I grant permissions at runtime?
Yes, Wassette provides built-in tools for dynamic permission management:
grant-storage-permission
: Grant file system accessgrant-network-permission
: Grant network accessgrant-environment-variable-permission
: Grant environment variable access
What happens if a component tries to access unauthorized resources?
The WebAssembly sandbox will block the access attempt. Wassette enforces permissions at the runtime level, so unauthorized access attempts are prevented rather than just logged.
Installation and Setup
What platforms does Wassette support?
Wassette supports:
- Linux (including Windows Subsystem for Linux)
- macOS
- Windows (via WinGet package)
How do I install Wassette?
Linux/macOS:
curl -fsSL https://raw.githubusercontent.com/microsoft/wassette/main/install.sh | bash
macOS (Homebrew): See the Homebrew installation guide
Windows (WinGet): See the WinGet installation guide
Nix: See the Nix installation guide
How do I configure Wassette with my AI agent?
Wassette works with any MCP-compatible AI agent. See the MCP clients setup guide for specific instructions for:
- Visual Studio Code
- Cursor
- Claude Code
- Gemini CLI
Usage and Troubleshooting
How do I load a component in Wassette?
You can load components from OCI registries or local files:
Please load the component from oci://ghcr.io/microsoft/time-server-js:latest
Or for local files:
Please load the component from ./path/to/component.wasm
What built-in tools does Wassette provide?
Wassette includes several built-in management tools:
load-component
: Load WebAssembly componentsunload-component
: Unload componentslist-components
: List loaded componentssearch-components
: Search available components from registryget-policy
: Get policy informationgrant-storage-permission
: Grant storage accessgrant-network-permission
: Grant network accessgrant-environment-variable-permission
: Grant environment variable accessrevoke-storage-permission
: Revoke storage access permissionsrevoke-network-permission
: Revoke network access permissionsrevoke-environment-variable-permission
: Revoke environment variable access permissionsreset-permission
: Reset all permissions for a component
How do I debug component issues?
- Check the logs: Run Wassette with
RUST_LOG=debug
for detailed logging - Verify permissions: Ensure your policy file grants necessary permissions
- Test component separately: Validate that your component works outside Wassette
- Check the interface: Ensure your WIT interface matches what Wassette expects
Are there performance implications of using WebAssembly?
WebAssembly Components in Wassette have:
- Lower memory overhead compared to containers
- Fast startup times due to efficient Wasm instantiation
- Near-native performance for CPU-intensive tasks
- Minimal runtime overhead thanks to Wasmtime’s optimizations
Can I use Wassette in production?
Wassette is actively developed and used by Microsoft. However, as with any software, you should:
- Test thoroughly in your specific environment
- Review the security model for your use case
- Keep up with updates and security patches
- Consider your specific requirements for stability and support
Getting Help
Where can I get support?
- GitHub Issues: Report bugs or request features
- Discord: Join the
#wassette
channel on Microsoft Open Source Discord - Documentation: Check the docs directory for detailed guides
- Examples: Review working examples for common patterns
How can I contribute to Wassette?
See the Contributing Guide for information on:
- Setting up the development environment
- Submitting bug reports and feature requests
- Contributing code and documentation
- Following the project’s coding standards
Where can I find more examples?
The examples directory contains working examples in multiple languages:
- Time server (JavaScript)
- Weather API (JavaScript)
- File system operations (Rust)
- HTTP client (Rust)
- Code execution (Python)
- Go module info (Go)
sequenceDiagram
participant Client as MCP Client
participant Server as Wassette MCP Server
participant LM as LifecycleManager
participant Engine as Wasmtime Engine
participant Registry as Component Registry
participant Policy as Policy Engine
Client->>Server: load-component(path)
Server->>LM: load_component(uri)
alt OCI Registry
LM->>LM: Download from OCI
else Local File
LM->>LM: Load from filesystem
else HTTP URL
LM->>LM: Download from URL
end
LM->>Engine: Create Component
Engine->>Engine: Compile WebAssembly
Engine->>Engine: Extract WIT Interface
LM->>Registry: Register Component
Registry->>Registry: Generate JSON Schema
Registry->>Registry: Map Tools to Component
LM->>Policy: Apply Default Policy
Policy->>Policy: Create WASI State Template
LM-->>Server: Component ID + LoadResult
Server-->>Client: Success with ID
Note over Client,Policy: Component is now loaded and ready
Client->>Server: call_tool(tool_name, args)
Server->>LM: execute_component_call(id, func, params)
LM->>Policy: Get WASI State for Component
Policy->>Policy: Apply Security Policy
Policy->>Engine: Create Store with WASI Context
LM->>Engine: Instantiate Component
Engine->>Engine: Call Function with Args
Engine->>Engine: Execute in Sandbox
Engine-->>LM: Results
LM-->>Server: JSON Response
Server-->>Client: Tool Result
Permission System Design
- Author: @Mossaka
- Date: 2025-07-11
Overview
The permission system provides fine-grained, per-component capability controls in the Wassette MCP server. This document describes the architecture,implementation, and future development plans.
Architecture Overview
Core Components
graph TB
Client[MCP Client] --> Server[Wassette MCP Server]
Server --> LM[LifecycleManager]
LM --> PR[PolicyRegistry]
LM --> CR[ComponentRegistry]
LM --> Engine[Wasmtime Engine]
LM --> Resources[Resources]
PR --> Permissions[Permissions]
subgraph "Resources"
PolicyFile[Component Policy Files]
ComponentFile[Component.wasm]
end
subgraph "Permissions"
Network[Network Permissions]
Storage[Storage Permissions]
Environment[Environment Permissions]
end
Key Design Principles
- Per-Component Policies: Each component has its own permission policy, co-located with the component binary under the
plugin_dir
directory - Principle of Least Privilege: Components only get permissions they need
- Dynamic Control: Permissions can be granted at runtime using the
grant-permission
tool
Current Implementation Status
1. Per-Component Policy System
Status: ✅ Implemented
Each component can have its own policy file stored as {component_id}.policy.yaml
co-located with the component binary.
#![allow(unused)] fn main() { // Current Implementation struct PolicyRegistry { component_policies: HashMap<String, Arc<WasiStateTemplate>>, } impl LifecycleManager { async fn get_wasi_state_for_component(&self, component_id: &str) -> Result<WasiState> { // Returns component-specific WASI state or default restrictive policy } } }
2. Policy Lifecycle Management
Status: ✅ Implemented
Built-in tools for managing component policies:
attach-policy
: Attach policy from file:// or https:// URIdetach-policy
: Remove policy from componentget-policy
: Get policy information for component
3. Granular Permission System
Status: ✅ Implemented
The grant_storage_permission
method allows atomic permission grants:
#![allow(unused)] fn main() { pub async fn grant_storage_permission( &self, component_id: &str, details: &serde_json::Value, ) -> Result<()> }
The grant_network_permission
method allows atomic permission grants:
#![allow(unused)] fn main() { pub async fn grant_network_permission( &self, component_id: &str, details: &serde_json::Value, ) -> Result<()> }
Supported permission types:
- Network:
{"host": "api.example.com"}
- Storage:
{"uri": "fs:///path", "access": ["read", "write"]}
4. Policy Persistence
Status: ✅ Implemented
- Policies are stored co-located with components
- Policy associations are restored on server restart
- Metadata tracking for policy sources
Built-in Tools
get-policy
: Get policy informationgrant-storage-permission
: Grant storage accessgrant-network-permission
: Grant network accessgrant-environment-variable-permission
: Grant environment variable accessrevoke-storage-permission
: Revoke storage access permissionsrevoke-network-permission
: Revoke network access permissionsrevoke-environment-variable-permission
: Revoke environment variable access permissionsreset-permission
: Reset all permissions for a componentload-component
: Load WebAssembly componentunload-component
: Unload componentlist-components
: List loaded componentssearch-components
: Search available components from registry
Permission Types and Structure
Policy File Format
version: "1.0"
description: "Component-specific security policy"
permissions:
network:
allow:
- host: "api.example.com"
- host: "cdn.example.com"
environment:
allow:
- key: "API_KEY"
- key: "CONFIG_URL"
storage:
allow:
- uri: "fs:///tmp/workspace"
access: ["read", "write"]
- uri: "fs:///var/cache"
access: ["read"]
Future Development Roadmap
- Policy Signing: Verify policy integrity with signatures
- Policy Checksums: Verify downloaded policy integrity
- Policy Caching: Optimize policy loading and parsing