Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 63 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,141 +1,108 @@
# wassette
<div align="center">
<h1 align="center">Wassette</h1>
<p><b>A security-oriented runtime that runs WebAssembly Components via MCP</b></p>

<!-- <a href="https://discord.gg/microsoft-open-source">
<img src="https://dcbadge.limes.pink/api/server/microsoft-open-source" alt="Discord" style="height: 25px;">
</a> -->

Wassette is a secure and open source MCP server that runs on top of WebAssembly (Wasm). It is designed to securely execute untrusted tools by embedding a Wasm runtime and applying capability-based policies to control access to system resources. It uses the sandboxing and abstraction provided by the Wasm [Component Model](https://github.com/WebAssembly/component-model) to ensure tools can be executed safely and easily without compromising the host system.
[Getting started][setup guide] | [Releases] | [Contributing] | [Discord]

Please read the rest of the README for more background, but the TL;DR is this:
</div>

`wassette` essentially acts as a _virtual MCP server_, with built-in observability, resource quotas, and handles infrastructure complexity automatically.
## Why Wassette?

> Note: The name "Wassette" is a play on the word "Wasm" and "Cassette" - a magnetic tape used to store audio, and is pronounced "Wass-ette".
- **Convenience**: Wassette makes it easy to extend AI agents with new tools,
all without ever having to leave the chat window.
- **Reusability**: Wasm Components built for Wassette are generic and reusable;
there is nothing MCP-specific about them.
- **Security**: Wassette is built on the Wasmtime security sandbox, providing
browser-grade isolation of tools.

## 🚩 Purpose
## Installation

### Problem Statement

A popular use scenario for MCP today is to run the server as a standalone process on a machine that talks to clients over stdio or a socket. Running these servers natively poses security risks, such as "my mcp-client calls the tool to read a file, and for some reason the tool writes to a file on my machine", "the tool opens a socket to a remote machine and sends data to it", or "I downloaded this open source mcp-server, but it has a vulnerability that allows an attacker to execute arbitrary code on my machine". This is the same problem as running untrusted code on your machine, but mcp-clients make them much easier to install on your machine and run.

### Who is the target audience?

1. _Developers_ who want to focus on writing the business logic for MCP tools, instead of worrying about the infrastructure.

2. _DevOps engineers_ who want the tools to be able to run everywhere and have a great observability story and tools are secured by design.

3. _Users_ who want to run a trusted mcp-server on their machine that is proven to securely execute untrusted tools.

4. _Platform providers_ who want to provide a serverless experience for their users.

### What are the current solutions?

1. Package and distribute the server as Docker images. 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](https://docs.docker.com/ai/mcp-catalog-and-toolkit/catalog/) runs each MCP server as a container - providing isolation and portability.
2. Running binaries directly using `npx` or `uvx`. 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.
3. Centralized MCP server that runs WebAssembly-based tools locally (think tools like [mcp.run](https://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.

### So why does this exist?

We wanted to build an entirely open source tool that enables developers to define tools via the Component Model, which means they are easy to reuse and compose in addition to running with low memory requirements and in a secure sandbox. They also let anyone see exactly what features the tool is requesting and allows a server to fulfill those requests in a secure way. This is a significant improvement over the current state of MCP servers, which are either arbitrary code or require custom ABIs and libraries, and are not compatible with each other.

So what is this project aiming to be?

1. One centralized open-source mcp-server, written in a memory safe, high performance language that embeds a WebAssembly runtime (e.g. [Wasmtime](https://github.com/bytecodealliance/wasmtime) or [hyperlight-wasm](https://github.com/hyperlight-dev/hyperlight-wasm)), acting as a minimal trusted computing base (TCB).
2. `wassette` will implement allow/deny lists for file paths, network endpoints, and system calls using capability-based policy like [policy-mcp-rs](https://github.com/microsoft/policy-mcp-rs).
3. Untrusted tool code will be distributed as WebAssembly OCI artifacts in OCI registries, and be loaded into the trusted layer upon signature verification. Each tool will have a discrete set of capabilities. For example, tool A needs to read `./data`; not network; tool B needs read/write to `/assets` and outbound HTTP only to `api.company.com:443`.

### What about the developer experience?

Developers will write MCP tools as normal 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.

If you are interested in learning more about what programming language supports WebAssembly, you can check out [this page](https://developer.fermyon.com/wasm-languages/webassembly-language-support).

## Install

### All Platforms (Shell Script)
For Linux and macOS, you can install Wassette using the provided install script:

```bash
curl -fsSL https://raw.githubusercontent.com/microsoft/wassette/main/install.sh | bash
```

This will detect your platform and install the latest `wassette` binary to your `$PATH`.

## Integrate with MCP Clients
This will detect your platform and install the latest `wassette` binary to your `$PATH`. For Windows, you can download the latest release from the [GitHub Releases page][Releases]

### [VSCode](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) / [GitHub Copilot](https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-chat-with-mcp) / [Cursor](https://docs.cursor.com/context/model-context-protocol)
## Using Wassette

Add this to your VSCode or Cursor settings:
With Wassette installed, the next step is to register it with your agent of
choice. We have a complete [complete setup guide][setup guide] for all agents
here, including Cursor, Claude Code, and Gemini CLI. However to get started with
Visual Studio Code, just run the following command:

```json
"mcp": {
"servers": {
"wassette": {
"type": "sse",
"url": "http://127.0.0.1:9001/sse"
}
}
}
```bash
code --add-mcp '{"name":"Wassette","command":"wassette","args":["serve","--stdio"]}'
```

## Quick Start

1. **Start the wassette server:**
Now that your agent knows about Wassette, we are ready to load Wasm Components. To teach your agent to tell the time, we can ask it to load a time component:

```bash
# Run the following cmd in your terminal to start the Wassette MCP server
wassette serve --http --policy-file policy.yaml
```
```text
Please load the time component from oci://ghcr.io/yoshuawuyts/time:latest
```

2. **Dynamically load tools:**
Now that the time component is loaded, we can ask your agent to tell you the current time:

**From OCI Registry:**
<!-- update to point to wassette pkgs -->
```text
What is the current time?
```

```
# Enter the following prompt into your AI client
Load the filesystem tools from oci://ghcr.io/duffney/filesystem:latest
```
The agent will respond with the current time, which is fetched from the time component running in a secure WebAssembly sandbox:

**From Local File:**
```output
The current time July 31, 2025 at 10:30 AM UTC
```

```
# Enter the following prompt into your AI client
Load component from file:///path/to/my-tools.wasm
```
Congratulations! You've just run your first Wasm Component and taught your agent how to tell time!

3. **Use the newly loaded tools immediately:**
## Building for Wassette

```
# Enter the following prompt into your AI client
Use the read-file tool to get the contents of the Justfile at the root of this repo
```
Wasm Components provide fully typed interfaces defined using WebAssembly
Interface Types (WIT). Wassette can take any Wasm Component and load it as an
MCP tool by inspecting the types it exposes. Take for example the following WIT
definition for a time server:

The tools are now available in your AI client's tool list - no restart required! Wassette automatically detects what functions each component exports and makes them available as MCP tools.
```wit
package local:time-server;

**Built-in Tools for Dynamic Loading:**
world time-server {
export get-current-time: func() -> string;
}
```

- `load-component` - Load WebAssembly components from any source
- `unload-component` - Remove components from the runtime
You'll notice that this interface doesn't mention MCP at all; it is just a
regular library interface that exports a function. That means there is no such
thing as a "Wassette-specific Wasm Component". Wassette is able to load any Wasm
Component and expose its functions as MCP tools. Just like Components built for Wassette can be re-used by other Wasm runtimes.

## Examples
See the [`examples/`](./examples/) directory for a complete list of examples. Here is a
selection of examples written in different languages:

| Example | Description |
| ------------------------------------------ | ------------------------------------------------------ |
| [fetch-rs](examples/fetch-rs/) | HTTP client for making web requests |
| [filesystem-rs](examples/filesystem-rs/) | File system operations (read, write, list directories) |
| [eval-py](examples/eval-py/) | Python code execution sandbox |
| [get-weather-js](examples/get-weather-js/) | Weather API client for fetching weather data |
| [time-server-js](examples/time-server-js/) | Simple time server component |
| [gomodule-go](examples/gomodule-go/) | Go module information tool |

See the `examples/` directory for more components you can build and load dynamically.

## Contributing

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to contribute to this project.
Please see [CONTRIBUTING.md][Contributing] for more information on how to contribute to this project.

## License

<sup>
Licensed under the <a href="LICENSE">MIT License</a>.
</sup>
This project is icensed under the <a href="LICENSE">MIT License</a>.

## Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft’s Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies.

[setup guide]: https://github.com/microsoft/wassette/blob/main/docs/mcp-clients.md
[Contributing]: CONTRIBUTING.md
[Releases]: https://github.com/microsoft/wassette/releases
[Discord]: https://discord.gg/microsoft-open-source
81 changes: 81 additions & 0 deletions docs/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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

1. **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](https://docs.docker.com/ai/mcp-catalog-and-toolkit/catalog/) runs each MCP server as a container - providing isolation and portability.
2. **Direct binary execution**. Running binaries directly using `npx` or `uvx`. 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.
3. **WebAssembly platforms**. Centralized MCP server that runs WebAssembly-based tools locally (think tools like [mcp.run](https://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](https://github.com/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](https://github.com/bytecodealliance/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](https://github.com/microsoft/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

```yaml
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](https://developer.fermyon.com/wasm-languages/webassembly-language-support).

Wassette provides examples in JavaScript and Python, which are the most popular languages for MCP server development, see [examples](../examples/).