Modulewise Toolbelt: Part 1
Published: 7/8/2025
By: Mark Fisher
Previous Modulewise blog posts covered the Modularity Mindset Shift and a conceptual overview of Composable Integration for Intelligent Systems. Now it’s time to dive into running code, with an introduction to the Modulewise Toolbelt, an open source project announced today!
This is the first of a three-part series and will answer some basic questions about the project and provide an initial look at its core runtime characteristics. The next two posts will cover the least-privilege capability model and tool composition.
If you read the previous posts, you will realize this is just one piece of the puzzle. But tools are enablers for agents, and thus for the advisors and observers described earlier. So, it’s an appropriate place to start this journey toward composable integration for intelligent systems.
What is it?
The Modulewise Toolbelt is a Model Context Protocol (MCP) Server that loads Wasm Components and translates their Wasm Interface Type (WIT) definitions into MCP tool schemas. It then handles each tool call by invoking the corresponding function on a component.
Why “toolbelt”?
A modular approach enables quick access to an efficient and focused solution for a given task. Customization and adaptation are achieved through composition. Likewise, an agent should have quick access to tools that are customized for their tasks and aligned with the scope of their role.
A toolbelt is personalized, and kept as light as possible, with tools curated for the job at hand. Likewise, the Modulewise Toolbelt can host a lightweight set of purpose-built tools that adapt well to the needs of a single agent, rather than being deployed as a monolithic server with all the tools needed by many agents.
How do I use it?
toolbelt hello.wasm calculator.wasm
These are the WIT interfaces for those two example components:
interface greeter {
greet: func(name: string) -> string;
}
interface calculator {
add: func(a: f32, b: f32) -> f32;
subtract: func(a: f32, b: f32) -> f32;
multiply: func(a: f32, b: f32) -> f32;
divide: func(a: f32, b: f32) -> f32;
}
The following MCP Inspector screenshot shows the result of loading those components as tools. You can specify parameter values and click “Run Tool”. You can also inspect the JSON messages sent between the client and server upon initialization, listing tools, and calling tools:
You should also be able to access the Modulewise Toolbelt server via any MCP client that supports the SSE transport (“streamable HTTP” will be available soon).
Given the emphasis on keeping things as light as possible, It’s also worth noticing the size of these components:
Yep, those are Ks not Ms.
Of course, not all components will be quite that small, but the key point is that components do not carry excess baggage. Instead, they require that capabilities be provided to them. It’s inherently an inversion of control model, where the runtime can enforce isolation and limit capabilities. We will focus on the latter in the next post, but let’s quickly discuss the isolated runtime.
Zero-Trust
The origin of WebAssembly for running code in the browser established its prioritization of a zero-trust sandboxed execution model, and that absolutely carries over to non-browser runtimes. The Modulewise Toolbelt server embeds wasmtime which provides a secure sandboxed execution model for components.
In the Modulewise Toolbelt, running components are ephemeral, instantiated per-invocation and discarded upon completion. They are even isolated from subsequent invocations of the same component function. Each instance has a 1:1 relationship with a tool call.
Near-Zero Cold-Start
An instance-per-request runtime execution model surely leads to a significant cold-start tradeoff, right?
Nope. The instantiation of a component is typically sub-millisecond. That’s right. Just like we saw in the component size, the timing is on a different order of magnitude than we are used to measuring.
The takeaway is that the instantiation overhead is negligible within the scope of typical real world function invocation, especially if any I/O is involved.
What’s next?
Hopefully this post has motivated you to clone the repo, run the server, and start considering how this project can play a role in providing tools to your agents. If you do, please add a star!
In addition to the direct wasm file paths shown above, the server also accepts toml files that support more configuration options. We will address that in relation to capability management in the next post.
The hosted components can have rich domain types and can themselves be compositions, for aggregation of functionality or management of cross-cutting concerns. We will address those topics as part of the third and final post in the series (which might segue nicely into another open source project announcement!).