-
Notifications
You must be signed in to change notification settings - Fork 699
Define "MCP Sandbox Interface" and implement limactl mcp serve
#3744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
// - [RunShellCommandParams].Directory must not be empty | ||
// | ||
// Eventually, this package may be split to a separate repository. | ||
package msi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RFC: "MCP Sandbox Interface" might be a misnomer; it might rather sound like an interface for sandboxing MCP servers, e.g., docker run -i --rm example.com/some-mcp-server /usr/bin/some-mcp-server
https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md#docker-based-mcp-server
Alternative names:
- AI Sandbox Interface
- Agent Sandbox Interface
- AI Protection Interface
- ...
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @lima-vm/maintainers
dadfb7c
to
ab6c5dc
Compare
0892d60
to
2967ffe
Compare
I've only browsed the code, but if I understand this correctly, the "protection" relies just on the fact that the VM has mounted the filesystem readonly. AFAICT there is no sandboxing of the filesystem, so the ReadFile tool could still read e.g. credentials from Beyond that, I wonder if this isn't outside the scope of Lima itself. It is an application built on top of Lima, but for some reason compiled into it. It could just as well be built as a separate tool. Or as a So I wonder if it wouldn't be good to include it as an example on how to create plugins for Lima? The reason to keep it in the Lima repo would be that MCP is a hot topic, and having it bundled makes it easier to discover. |
The home directory except the pwd can be hidden with:
Maybe |
$ cat ~/bin/limactl-hello
#!/bin/bash
echo "Hello world from $BASH_SOURCE"
$ limactl hello
Hello world from /Users/jan/bin/limactl-hello We could also look for plugins in |
11ff941
to
d8c61ec
Compare
Reimplemented as |
42eb5c5
to
206003b
Compare
It doesn't seem to be working for me: ❯ l mcp -v
limactl-mcp version 2.0.0-alpha.0-39-gf71031e6
❯ l ls default qemu
NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR
default Stopped 127.0.0.1:0 vz aarch64 4 4GiB 100GiB ~/.lima/default
qemu Running 127.0.0.1:63754 qemu aarch64 4 4GiB 100GiB ~/.lima/qemu
❯ l mcp serve default
FATA[0000] expected status of instance "default" to be "Running", got ""
❯ l mcp serve qemu
FATA[0000] expected status of instance "qemu" to be "Running", got ""
❯ l shell qemu uname -a
Linux lima-qemu 6.14.0-23-generic #23-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 22:12:54 UTC 2025 aarch64 aarch64 aarch64 GNU/Linux |
Works for me. |
No, I have the default setup. My suspicion is that I would have expected to see something like Are you sure you don't have external I think as a plugin the code has to call |
Confirmed: The error goes away after running ADDITIONAL_DRIVERS="qemu vz" make native additional-drivers limactl-plugins install |
And it turns out to be #2668 once again wasting time. We really should fix this non-idiomatic interface. When I add @@ -151,6 +152,9 @@ func mcpServeAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
+ if len(inst.Errors) != 0 {
+ return errors.Join(inst.Errors...)
+ }
if err = ts.RegisterInstance(ctx, inst); err != nil {
return err
} then I get a more meaningful error: ❯ l mcp serve default
FATA[0000] failed to resolve vm for "/Users/jan/.lima/default/lima.yaml": vmType "vz" is not a registered driver |
Is it a bug that |
I guess for a dev env, |
You can just look it up in the
The |
Oh, got it, thanks! I've raised a fix for the same #4034 |
Fixed the incompatibility with built-in drivers |
=== Interface === `pkg/mcp/msi` defines "MCP Sandbox Interface" (tentative) that should be reusable for other projects too. MCP Sandbox Interface defines MCP (Model Context Protocol) tools that can be used for reading, writing, and executing local files with an appropriate sandboxing technology. The sandboxing technology can be more secure and/or efficient than the default tools provided by an AI agent. MCP Sandbox Interface was inspired by Gemini CLI's built-in tools. https://github.com/google-gemini/gemini-cli/tree/v0.1.12/docs/tools === Implementation === `limactl mcp serve INSTANCE` launches an MCP server that implements the MCP Sandbox Interface. Use <https://github.com/modelcontextprotocol/inspector> to play around with the server. ```bash limactl start default brew install mcp-inspector mcp-inspector ``` In the web browser, - Set `Command` to `limactl` - Set `Arguments` to `mcp serve default` - Click `▶️ Connect` === Usage with Gemni CLI === 1. Create `.gemini/extensions/lima/gemini-extension.json` as follows: ```json { "name": "lima", "version": "2.0.0", "mcpServers": { "lima": { "command": "limactl", "args": [ "mcp", "serve", "default" ] } } } ``` 2. Modify `.gemini/settings.json` so as to disable Gemini CLI's built-in tools except ones that do not relate to local command execution and file I/O: ```json { "coreTools": ["WebFetchTool", "WebSearchTool", "MemoryTool"] } ``` Signed-off-by: Akihiro Suda <[email protected]>
|
||
Drop the `:w` suffix if you do not want to allow writing to the mounted directory. | ||
|
||
1. Create `.gemini/extensions/lima/gemini-extension.json` as follows: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Create `.gemini/extensions/lima/gemini-extension.json` as follows: | |
2. Create `.gemini/extensions/lima/gemini-extension.json` as follows: |
} | ||
``` | ||
|
||
1. Modify `.gemini/settings.json` so as to disable Gemini CLI's [built-in tools](https://github.com/google-gemini/gemini-cli/tree/main/docs/tools) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Modify `.gemini/settings.json` so as to disable Gemini CLI's [built-in tools](https://github.com/google-gemini/gemini-cli/tree/main/docs/tools) | |
3. Modify `.gemini/settings.json` so as to disable Gemini CLI's [built-in tools](https://github.com/google-gemini/gemini-cli/tree/main/docs/tools) |
--- | ||
|
||
| ⚡ Requirement | Lima >= 2.0 | | ||
|-------------------|-------------| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|-------------------|-------------| | |
|------------------|-------------| |
serverOpts.Instructions += fmt.Sprintf(` | ||
|
||
NOTE: the guest OS of the VM is Linux, while the host OS is %s. | ||
`, strings.ToTitle(runtime.GOOS)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strings.ToTitle(runtime.GOOS))
capitalizes all chars:
darwin
->DARWIN
windows
->WINDOWS
Do you think it is intentional?
limactl := os.Getenv("LIMACTL") | ||
if limactl == "" { | ||
limactl = "limactl" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be slightly shorter:
limactl := os.Getenv("LIMACTL") | |
if limactl == "" { | |
limactl = "limactl" | |
} | |
limactl := cmp.Or(os.Getenv("LIMACTL"), "limactl") |
|
||
var SearchFileContent = &mcp.Tool{ | ||
Name: "search_file_content", | ||
Description: `searches for a regular expression pattern within the content of files in a specified directory. Internally calls 'git grep -n --no-index'.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description: `searches for a regular expression pattern within the content of files in a specified directory. Internally calls 'git grep -n --no-index'.`, | |
Description: `Searches for a regular expression pattern within the content of files in a specified directory. Internally calls 'git grep -n --no-index'.`, |
ssh := append([]string{sshExe.Exe}, sshExe.Args...) | ||
ssh = append(ssh, "-F", | ||
filepath.Join(inst.Dir, filenames.SSHConfig), | ||
hostname.FromInstName(inst.Name)) | ||
|
||
cmd := exec.CommandContext(ctx, ssh[0], append(ssh[1:], "-s", "sftp")...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's simpler with slices.Concat
:
ssh := append([]string{sshExe.Exe}, sshExe.Args...) | |
ssh = append(ssh, "-F", | |
filepath.Join(inst.Dir, filenames.SSHConfig), | |
hostname.FromInstName(inst.Name)) | |
cmd := exec.CommandContext(ctx, ssh[0], append(ssh[1:], "-s", "sftp")...) | |
args := slices.Concat(sshExe.Args, []string{"-F", filepath.Join(inst.Dir, filenames.SSHConfig), hostname.FromInstName(inst.Name), "-s", "sftp"}) | |
cmd := exec.CommandContext(ctx, sshExe.Exe, args...) |
This PR allows AI agents such as Gemini CLI to wrap local file operations (read/write/execute) inside Lima VM.
It should work with Claude Code, Codex, etc. too, but they might need a modification to disable their built-in local file operation tools. (Help wanted for testing)
This feature will be available in Lima v2.0
Preview of the documentation: https://deploy-preview-3744--lima-vm.netlify.app/docs/config/ai/
Interface
pkg/mcp/msi
defines "MCP Sandbox Interface" (tentative) that should be reusable for other projects too.MCP Sandbox Interface defines MCP (Model Context Protocol) tools that can be used for reading, writing, and executing local files with an appropriate sandboxing technology. The sandboxing technology can be more secure and/or efficient than the default tools provided by an AI agent.
MCP Sandbox Interface was inspired by Gemini CLI's built-in tools. https://github.com/google-gemini/gemini-cli/tree/v0.1.12/docs/tools
Implementation
limactl mcp serve INSTANCE
launches an MCP server that implements the MCP Sandbox Interface.Use https://github.com/modelcontextprotocol/inspector to play around with the server.
In the web browser,
Command
tolimactl
Arguments
tomcp serve default
▶️Connect
Usage with Gemni CLI
.gemini/extensions/lima/gemini-extension.json
as follows:.gemini/settings.json
so as to disable Gemini CLI's built-in tools except ones that do not relate to local command execution and file I/O:TODOs