This is a WebAssembly Component that provides QR code generation capabilities as an MCP tool for the Wassette runtime. It demonstrates how to build secure, sandboxed MCP tools using WebAssembly.
Component Name: qr-code
Binary Output: qr_code.wasm
Runtime: Wassette - A secure WebAssembly runtime for MCP tools
Wassette provides a safer way to run MCP tools by leveraging WebAssembly's sandboxing capabilities:
- π Sandboxed Execution: Tools run in isolated WebAssembly environments with no default access to your system
- π Explicit Permissions: Each tool must declare its required permissions (filesystem, network, etc.) in a policy file
- β User Control: You review and approve what resources each tool can access before it runs
- π Cross-Platform: WebAssembly components work consistently across different operating systems
This QR code component demonstrates these security principles - it can only access the specific directories you've approved in the policy file, ensuring your system remains protected while the tool operates.
- Generate QR codes as SVG from text or URLs
- Custom size support (50-1000 pixels)
- Save QR codes to filesystem (with appropriate permissions)
- Minimal sandbox security policy
- Full type safety with WIT interface
# Install Rust if not already installed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install required tools
cargo install cargo-component
rustup target add wasm32-wasip2
This project uses Just as the preferred build system. Install it first:
# Install Just (if not already installed)
cargo install just
Then build the component:
# Build in debug mode (default)
just build
# Build in release mode (optimized)
just build release
# Clean build artifacts
just clean
# Install required tools (wasm-tools)
just install-tools
The component exports three functions:
generate-qr(input: string) -> result<string, string>
- Generate QR with default size (200px)generate-qr-custom(input: string, size: u32) -> result<string, string>
- Generate QR with custom sizesave-qr(input: string, size: u32, filename: string) -> result<string, string>
- Generate and save QR to file
# Install Wassette
curl -fsSL https://raw.githubusercontent.com/microsoft/wassette/main/install.sh | bash
# Configure MCP server for your client (important step!)
# For Claude Code CLI:
claude mcp add -- wassette wassette serve --stdio
# For other MCP clients, see:
# https://github.com/microsoft/wassette/blob/main/docs/mcp-clients.md
# Run the component locally for testing
wassette serve --stdio --plugin-dir .
Once configured, the QR code tools will be available in your MCP client (e.g., Claude Code).
The component runs with controlled permissions, demonstrating Wassette's security-first approach:
- No network access: The QR generator doesn't need internet, so it doesn't get it
- Limited filesystem access: Can only write to explicitly approved directories
- Optional environment variables: Only accesses environment variables you've approved
- Stderr for debugging: Controlled output for development
Unlike traditional MCP tools that run with full system access, this Wassette-based component:
- Starts with zero permissions - The WebAssembly sandbox blocks all system access by default
- Requests only what it needs - The policy file explicitly lists required permissions
- You control the boundaries - Edit the policy file to change what directories it can access
- Runtime enforcement - Wassette enforces these restrictions at runtime, not just on trust
For example, even though this is a QR code generator, it cannot:
- Read your SSH keys or browser cookies
- Access your network or make HTTP requests
- Write files outside the approved directories
- Execute system commands or spawn processes
This makes Wassette ideal for running third-party MCP tools safely, without worrying about malicious or buggy code compromising your system.
IMPORTANT: The default policy uses /home/brian/Downloads
as the output directory. You need to customize this for your system:
-
Edit
qr_code.policy.yaml
before deployment:# Replace 'brian' with your username - uri: "fs:///home/YOUR_USERNAME/Downloads" # Or use the portable /tmp location - uri: "fs:///tmp/qr-output"
-
Create the output directory if using
/tmp/qr-output
:mkdir -p /tmp/qr-output
Note: Wassette does not currently support environment variable expansion (like $USER
or ~
) in policy files. Paths must be absolute and literal
β
Component Status: Fully functional with Wassette MCP server
β
Policy File: Security permissions properly configured
β
Tools Available: All 3 tools working correctly
# Build and stage the component with its policy file
just stage release
This automatically:
- Builds the component in release mode
- Copies
qr_code.wasm
to~/.local/share/wassette/components/
- Copies
qr_code.policy.yaml
to~/.local/share/wassette/components/
# Build the component
just build release
# Copy both files to Wassette's components directory
cp target/wasm32-wasip2/release/qr_code.wasm ~/.local/share/wassette/components/
cp target/wasm32-wasip2/release/qr_code.policy.yaml ~/.local/share/wassette/components/
# Check files are in place
ls -la ~/.local/share/wassette/components/qr_code*
# Should show both:
# qr_code.wasm (124KB)
# qr_code.policy.yaml (646 bytes)
Policy File Naming Convention
- Policy file MUST be named
qr_code.policy.yaml
(not justpolicy.yaml
) - Must be co-located with the
.wasm
file in Wassette's components directory - Without both files present:
- Component loads but has no permissions
- Tools fail with permission errors
- Manual permission grants create auto-generated policies
Returns the QR code as an SVG string in the response (does not save to file):
Tool: mcp__wassette__generate-qr
Input: URL or text to encode (e.g., "https://mcpsearchtool.com")
Output: SVG string data returned to the MCP client
Use case: Display QR code directly or process the SVG data
Returns the QR code as an SVG string in the response (does not save to file):
Tool: mcp__wassette__generate-qr-custom
Inputs:
- URL or text to encode (e.g., "https://mcpsearchtool.com")
- Size in pixels between 50-1000 (e.g., 300)
Output: SVG string data with specified dimensions returned to the MCP client
Use case: Display QR code directly with custom sizing
The only tool that writes to the filesystem:
Important: Before using this tool, update the username in qr_code.policy.yaml
from /home/brian/Downloads
to your actual path (e.g., /home/YOUR_USERNAME/Downloads
)
Tool: mcp__wassette__save-qr
Inputs:
- URL or text to encode (e.g., "https://mcpsearchtool.com")
- Size in pixels (e.g., 250)
- Filename (e.g., "example.svg")
Output: Success message with full file path
Action: Writes SVG file to disk at configured directory
After staging, test the tools work:
The QR code component's functions are exposed through Wassette as MCP tools. In Claude Code and other MCP clients, they appear with the mcp__wassette__
prefix:
mcp__wassette__generate-qr
(wraps the component'sgenerate-qr
function)mcp__wassette__generate-qr-custom
(wraps the component'sgenerate-qr-custom
function)mcp__wassette__save-qr
(wraps the component'ssave-qr
function)
These tools are not directly visible to Claude Code - Wassette acts as a bridge, executing the WebAssembly component functions when these MCP tools are called.
To see what components are loaded and their parameters, ask your MCP client:
- "What Wassette components are loaded?"
- "Show me the details of the qr_code component"
- "List all available Wassette tools"
- "What parameters does the save-qr tool need?"
Your assistant will use the list-components
tool to show you the exact schemas, parameters, and requirements for each tool.
Interested in building or using secure MCP tools? Check out Wassette:
- For Users: Run MCP tools with confidence, knowing they're sandboxed and can only access what you explicitly allow
- For Developers: Build MCP tools that users can trust, with clear permission boundaries
- For Teams: Deploy MCP tools in production without worrying about security vulnerabilities
Visit the Wassette repository to learn more about the future of secure MCP tools.