There are two kinds of scenario to use Lima with AI:
- AI agents inside Lima: running an AI agent inside a VM
- AI agents outside Lima: calling Lima’s MCP tools from an AI agent running outside a VM
This is the multi-page printable view of this section. Click here to print.
There are two kinds of scenario to use Lima with AI:
Lima is useful for running AI agents (e.g., Antigravity, Claude Code, Codex) inside a VM, so as to prevent agents from directly reading, writing, or executing the host files.
See also:
Starting with Lima v2.0, Lima provides Model Context Protocol (MCP) tools for reading, writing, and executing local files using a VM sandbox.
| ⚡ Requirement | Lima >= 2.0 |
|---|
This page describes how to use Lima as a sandbox for Google Antigravity CLI, the successor to Gemini CLI.
In addition to Antigravity CLI and Lima, make sure that limactl mcp plugin is installed:
$ limactl mcp -v
limactl-mcp version 2.0.0-alpha.1
The limactl mcp plugin is bundled in Lima since v2.0, however, it may not be installed
depending on the method of the installation.
limactl start --mount-only "$(pwd):w" default
Drop the :w suffix if you do not want to allow writing to the mounted directory.
agy mcp add lima limactl mcp serve default
This stores the server in ~/.gemini/config/mcp_config.json:
{
"mcpServers": {
"lima": {
"args": [
"mcp",
"serve",
"default"
],
"command": "limactl",
"disabled": false
}
}
}
~/.gemini/antigravity-cli/settings.json so as to deny Antigravity CLI’s
built-in permissions for local command execution and file I/O,
while allowing web access and the MCP tools provided by Lima:{
"permissions": {
"allow": [
"read_url(*)",
"execute_url(*)",
"mcp(lima/*)"
],
"deny": [
"command(*)",
"read_file(*)",
"write_file(*)"
]
}
}
Just run agy in your project directory.
Antigravity CLI automatically recognizes the MCP tools provided by Lima.
Type /mcp in the prompt panel to confirm that the lima MCP server is connected.
Lima implements the “MCP Sandbox Interface” (tentative name): https://pkg.go.dev/github.com/lima-vm/lima/v2/pkg/mcp/msi
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, such as Lima.
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 Google Gemini CLI’s built-in tools.
globFinds files matching specific glob patterns (e.g., src/**/*.ts, *.md)
{
"additionalProperties": false,
"properties": {
"path": {
"description": "The absolute path to the directory to search within. If omitted, searches the tool's root directory.",
"type": [
"null",
"string"
]
},
"pattern": {
"description": "The glob pattern to match against (e.g., '*.py', 'src/**/*.js').",
"type": "string"
}
},
"required": [
"pattern"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"matches": {
"description": "A list of absolute file paths that match the provided glob pattern.",
"items": {
"type": "string"
},
"type": [
"null",
"array"
]
}
},
"required": [
"matches"
],
"type": "object"
}
list_directoryLists the names of files and subdirectories directly within a specified directory path.
{
"additionalProperties": false,
"properties": {
"path": {
"description": "The absolute path to the directory to list.",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"entries": {
"description": "The directory content entries.",
"items": {
"additionalProperties": false,
"properties": {
"is_dir": {
"description": "true for a directory",
"type": [
"null",
"boolean"
]
},
"mode": {
"description": "file mode bits",
"maximum": 4294967295,
"minimum": 0,
"type": [
"null",
"integer"
]
},
"name": {
"description": "base name of the file",
"type": "string"
},
"size": {
"description": "length in bytes for regular files; system-dependent for others",
"type": [
"null",
"integer"
]
},
"time": {
"description": "modification time",
"type": [
"null",
"string"
]
}
},
"required": [
"name"
],
"type": "object"
},
"type": [
"null",
"array"
]
}
},
"required": [
"entries"
],
"type": "object"
}
read_fileReads and returns the content of a specified file.
{
"additionalProperties": false,
"properties": {
"path": {
"description": "The absolute path to the file to read.",
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"content": {
"description": "The content of the file.",
"type": "string"
}
},
"required": [
"content"
],
"type": "object"
}
replaceReplaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when expected_replacements is specified. This tool is designed for precise, targeted changes and requires significant context around the old_string to ensure it modifies the correct location.
{
"additionalProperties": false,
"properties": {
"expected_replacements": {
"description": "The number of occurrences to replace. Defaults to 1.",
"type": [
"null",
"integer"
]
},
"new_string": {
"description": "The exact literal text to replace old_string with.",
"type": "string"
},
"old_string": {
"description": "The exact literal text to replace. It must occur exactly expected_replacements times (once by default). To change a single occurrence, include at least 3 lines of context before and after the target text, matching whitespace and indentation precisely.",
"type": "string"
},
"path": {
"description": "The absolute path to the file to modify.",
"type": "string"
}
},
"required": [
"path",
"old_string",
"new_string"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"replacements": {
"description": "The number of occurrences that were replaced.",
"type": "integer"
}
},
"required": [
"replacements"
],
"type": "object"
}
run_shell_commandExecutes a given shell command.
{
"additionalProperties": false,
"properties": {
"command": {
"description": "The exact shell command to execute. Defined as a string slice, unlike Gemini's run_shell_command that defines it as a single string.",
"items": {
"type": "string"
},
"type": [
"null",
"array"
]
},
"description": {
"description": "A brief description of the command's purpose, which will be potentially shown to the user.",
"type": "string"
},
"directory": {
"description": "The absolute directory in which to execute the command. Unlike Gemini's run_shell_command, this must not be a relative path, and must not be empty.",
"type": "string"
}
},
"required": [
"command",
"directory"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"error": {
"description": "Any error message reported by the subprocess.",
"type": "string"
},
"exit_code": {
"description": "Exit code of the command.",
"type": [
"null",
"integer"
]
},
"stderr": {
"description": "Output from the standard error stream.",
"type": "string"
},
"stdout": {
"description": "Output from the standard output stream.",
"type": "string"
}
},
"required": [
"stdout",
"stderr"
],
"type": "object"
}
search_file_contentSearches for a regular expression pattern within the content of files in a specified directory. Internally calls ‘git grep -n –no-index’.
{
"additionalProperties": false,
"properties": {
"include": {
"description": "A glob pattern to filter which files are searched (e.g., '*.js', 'src/**/*.{ts,tsx}'). If omitted, searches most files (respecting common ignores).",
"type": [
"null",
"string"
]
},
"path": {
"description": "The absolute path to the directory to search within. Defaults to the current working directory.",
"type": [
"null",
"string"
]
},
"pattern": {
"description": "The regular expression (regex) to search for (e.g., 'function\\s+myFunction').",
"type": "string"
}
},
"required": [
"pattern"
],
"type": "object"
}
{
"additionalProperties": false,
"properties": {
"git_grep_output": {
"description": "The raw output from the 'git grep -n --no-index' command, containing matching lines with filenames and line numbers.",
"type": "string"
}
},
"required": [
"git_grep_output"
],
"type": "object"
}
write_fileWrites content to a specified file. If the file exists, it will be overwritten. If the file doesn’t exist, it (and any necessary parent directories) will be created.
{
"additionalProperties": false,
"properties": {
"content": {
"description": "The content to write into the file.",
"type": "string"
},
"path": {
"description": "The absolute path to the file to write to.",
"type": "string"
}
},
"required": [
"path",
"content"
],
"type": "object"
}
{
"additionalProperties": false,
"type": "object"
}