Imported from reason-machines/mcp-skills (
skills/local-mcp-file-editing/SKILL.md). Install upstream withnpx skills add reason-machines/mcp-skills --skill local-mcp-file-editing. Copyright stays with the author.
local-mcp File Editing Skill
Skill by ara.so — MCP Skills collection.
Overview
local-mcp is a Rust-based MCP (Model Context Protocol) server that exposes local filesystem and command execution capabilities to AI agents. It provides:
- File operations: Read, write, and list files
- Image reading: Native MCP image content for PNG, JPEG, GIF, WebP, BMP, TIFF, AVIF
- Sandboxed command execution: Network-isolated commands using Landlock (Linux) or Seatbelt (macOS)
- Session-based permissions: Each project gets its own permission context
- Live activity monitoring: Real-time diffs and command output in the start UI
- Background job management: Long-running commands with polling support
Commands run sandboxed by default (no network access). Unsandboxed commands require explicit approval through the interactive UI.
Installation
From Source (Cargo)
# Clone and build
git clone https://github.com/nakasyou/local-mcp.git
cd local-mcp
cargo build --release
# Binary will be at target/release/local-mcp
# On Linux, also outputs target/release/codex-linux-sandbox
With Nix
# Run directly
nix run github:nakasyou/local-mcp
# Or build locally
nix build
./result/bin/local-mcp
# Development shell
nix develop
System Requirements
- Linux: Requires
bwrap(bubblewrap) in PATH, plus thecodex-linux-sandboxhelper binary - macOS: Uses system
/usr/bin/sandbox-exec, no extra dependencies - Windows: Not yet supported
Starting the Server
1. Start the MCP Server
# Run the persistent MCP server
local-mcp mcp
# Server listens on Unix domain sockets for each session
2. Start a Session
# Start session in your project directory
cd /path/to/your/project
local-mcp start
# Or use a stable session ID
local-mcp start my-project-name
# Session ID is printed - give this to your AI agent
The session working directory is where you ran local-mcp start. All relative paths resolve from there.
Permission Management
In the local-mcp start UI, manage permissions with these commands:
# Allow all unsandboxed commands (for session lifetime only)
/permissions yolo
# Require approval for each unsandboxed command
/permissions ask
# Allow access to specific directory outside working dir
/permissions allow ../another-project
# Revoke directory permission
/permissions revoke ../another-project
# List all permissions
/permissions list
# Show current permission status
/permissions status
Note: /permission (singular) is also accepted.
MCP Tools API
All tools require a session_id parameter (provided by the agent).
session_info
Confirm session configuration and working directory.
// Tool parameters
{
"session_id": "my-project-name"
}
// Returns
{
"working_directory": "/path/to/your/project",
"sandbox_roots": ["/path/to/your/project"],
"permission_mode": "yolo" // or "ask"
}
read_file
Read text file contents.
{
"session_id": "my-project-name",
"path": "src/main.rs" // Relative to working directory
}
// Returns file content as string
get_image
Read image files as native MCP image content. Supports PNG, JPEG, GIF, WebP, BMP, TIFF, AVIF.
{
"session_id": "my-project-name",
"path": "assets/logo.png"
}
// Returns MCP image content
list_directory
List directory contents with file metadata.
{
"session_id": "my-project-name",
"path": "src" // Optional, defaults to working directory
}
// Returns array of file entries with size, modified time, type
write_file
Write or modify a file (sandboxed within working directory).
{
"session_id": "my-project-name",
"path": "config.toml",
"content": "[server]\nport = 8080\n"
}
// Shows unified diff in start UI
execute
Run a command, sandboxed (no network access). Returns immediately for commands under 30 seconds, otherwise returns a job_id.
{
"session_id": "my-project-name",
"command": "cargo build",
"args": ["--release"],
"cwd": "." // Optional, relative to working dir
}
// Quick commands return:
{
"stdout": " Compiling local-mcp v0.1.0\n...",
"stderr": "",
"exit_code": 0
}
// Long commands return:
{
"job_id": "abc123",
"message": "Command started in background"
}
without_sandbox
Execute command with full network and host permissions. Requires approval unless /permissions yolo is set.
{
"session_id": "my-project-name",
"command": "curl",
"args": ["https://api.example.com/data"],
"cwd": "."
}
// Same return format as execute
start_command
Start a background command immediately (sandboxed). Always returns a job_id without waiting.
{
"session_id": "my-project-name",
"command": "cargo",
"args": ["watch", "-x", "test"]
}
// Returns:
{
"job_id": "def456"
}
poll_job
Check status of a background job.
{
"session_id": "my-project-name",
"job_id": "abc123"
}
// Still running:
{
"status": "running"
}
// Completed:
{
"status": "completed",
"stdout": "...",
"stderr": "...",
"exit_code": 0
}
stop_job
Terminate a background job.
{
"session_id": "my-project-name",
"job_id": "abc123"
}
// Returns confirmation
Common Patterns
Multi-File Refactoring
// 1. List files to refactor
list_directory({ session_id: "proj", path: "src" })
// 2. Read each file
read_file({ session_id: "proj", path: "src/main.rs" })
read_file({ session_id: "proj", path: "src/lib.rs" })
// 3. Write updated content
write_file({
session_id: "proj",
path: "src/main.rs",
content: "// Updated code..."
})
// 4. Run tests (sandboxed)
execute({
session_id: "proj",
command: "cargo",
args: ["test"]
})
Building and Deploying
// 1. Build (sandboxed, no network)
execute({
session_id: "proj",
command: "cargo",
args: ["build", "--release"]
})
// 2. Deploy (requires network, needs approval)
without_sandbox({
session_id: "proj",
command: "scp",
args: ["target/release/app", "user@server:/opt/"]
})
Long-Running Dev Server
// Start dev server in background
start_command({
session_id: "proj",
command: "cargo",
args: ["run", "--", "serve"]
})
// Returns: { job_id: "server-xyz" }
// Check if server started
poll_job({
session_id: "proj",
job_id: "server-xyz"
})
// Later, stop it
stop_job({
session_id: "proj",
job_id: "server-xyz"
})
Working with Images
// List images
list_directory({ session_id: "proj", path: "assets/images" })
// Load image for analysis
get_image({
session_id: "proj",
path: "assets/screenshot.png"
})
// Returns native MCP image content for vision analysis
Configuration
Session Configuration
Sessions are configured through the local-mcp start command and the interactive UI. Configuration is session-lifetime only and includes:
- Working directory (set by where
startwas run) - Permission mode (
askoryolo) - Approved directories outside working dir
Environment Variables
The project uses standard Rust environment variables during build:
CARGO_BUILD_TARGET: Target triple for cross-compilationRUSTFLAGS: Compiler flags
No runtime environment variables are required.
MCP Server Configuration
The server runs on Unix domain sockets (one per session). Socket paths are managed internally and communicated to the start UI automatically.
Troubleshooting
"bwrap not found" (Linux)
Install bubblewrap:
# Debian/Ubuntu
sudo apt install bubblewrap
# Fedora
sudo dnf install bubblewrap
# Arch
sudo pacman -S bubblewrap
"codex-linux-sandbox not found" (Linux)
The helper binary must be in the same directory as local-mcp:
# After building
ls target/release/
# Should show: local-mcp codex-linux-sandbox
# When installing, copy both
sudo cp target/release/local-mcp /usr/local/bin/
sudo cp target/release/codex-linux-sandbox /usr/local/bin/
Commands Failing with Permission Denied
Check your permission mode in the start UI:
/permissions status
# If in "ask" mode and you want to auto-approve:
/permissions yolo
For paths outside the working directory, explicitly allow them:
/permissions allow /path/to/other/directory
Session ID Not Working
Ensure the session ID only contains:
- Letters (a-z, A-Z)
- Numbers (0-9)
- Hyphens (
-) - Underscores (
_) - Periods (
.)
Invalid characters will be rejected.
Background Jobs Not Returning Output
Use poll_job to check status:
poll_job({ session_id: "proj", job_id: "job-id" })
Jobs may still be running. Check the status field in the response.
macOS Sandbox Restrictions
macOS sandbox-exec profiles are more restrictive. If sandboxed commands fail unexpectedly, try without_sandbox (requires approval).
Security Considerations
- Sandboxed commands have no network access and can't escape the working directory tree
- Unsandboxed commands run with full host permissions and require explicit approval (unless
yolomode) - YOLO mode only lasts for the session lifetime; restart
local-mcp startto reset toaskmode - Session sockets are permission-restricted Unix domain sockets
- Give session IDs only to trusted agents; anyone with the ID can make tool calls
Integration Example
When integrating with an AI agent:
- Start the MCP server:
local-mcp mcp - Start your project session:
cd /your/project && local-mcp start my-proj - In your agent prompt, include:
I'm working in a local-mcp session with ID "my-proj".
Use session_info to confirm the working directory, then use
the MCP tools to read, edit, and test files.
- Set permissions as needed in the UI
- The agent can now safely interact with your local filesystem