Skip to main content
Glama

localmcp

A local MCP server for AI coding workflows. It gives ChatGPT a constrained view of one project directory plus the tools needed to inspect, edit, test, commit, and push code.

What it can do

localmcp exposes 16 tools:

  • workspace_info — server, workspace, mode, and tool diagnostics

  • project_snapshot — bootstrap a coding session with root files, a shallow tree, README content, git status, and diff statistics in one call

  • list_funcs — discover hot-reloadable JavaScript functions from functions/

  • execute_func — execute a discovered dynamic function by name and arguments

  • list_files — list a directory

  • tree — recursively inspect the workspace with depth and entry limits

  • search_files — substring or regex search with globs and context lines

  • read_file — read a whole file or a numbered line range

  • read_files — batch-read up to 50 files/ranges in one MCP round trip

  • read_image — return a workspace PNG, JPEG, GIF, or WebP as MCP image content for vision-capable clients/models

  • write_file — create or replace a file

  • edit_file — guarded exact-text replacement

  • apply_patch — atomically apply multiple guarded edits to one file

  • delete_file — delete a file

  • move_file — move or rename a file

  • run_command — execute a program directly without a shell

project_snapshot is intended as the first call in a coding session. It is language-agnostic: rather than interpreting a particular manifest or build system, it returns root files, a bounded .gitignore-aware tree, the root README (up to a configurable byte limit), and optional read-only git status plus diff statistics. Clients can use those facts to decide what to inspect next. It also returns structured content so clients do not need to parse the human-readable summary.

Dynamic functions live in functions/*.js. For security, list_funcs and execute_func are only registered in yolo mode because workspace files are writable and importing a workspace JavaScript module is equivalent to arbitrary code execution with the localmcp process permissions. Each module exports a default object with name, description, optional inputSchema metadata, and an async run(args, context) function. The included functions/hello.js is a minimal example.

Together these are enough for a coding-agent loop such as:

inspect → search → read → edit → test → diff → commit → push

Workspace traversal respects the root .gitignore by default, and .git is always excluded. tree also accepts explicit exclude globs (for example build* or .cache/**) so generated trees can be omitted without changing .gitignore.

Related MCP server: Kastor

Security model

All localmcp file tools are confined to LOCALMCP_ROOT. Absolute paths, .. traversal, and symbolic-link escapes are rejected.

Command execution has two modes.

Strict mode

strict is the default. run_command only accepts executables listed in LOCALMCP_ALLOWED_COMMANDS. Dynamic workspace JavaScript functions are disabled in this mode so writable files cannot bypass the command allowlist.

LOCALMCP_ROOT="$HOME/src/my-project" \
LOCALMCP_MODE=strict \
LOCALMCP_ALLOWED_COMMANDS="git,node,npm" \
npm start

With an empty allowlist, command execution is effectively disabled.

YOLO mode

For a trusted coding workspace, yolo removes the executable allowlist:

LOCALMCP_ROOT="$HOME/src/my-project" \
LOCALMCP_MODE=yolo \
npm start

localmcp still requires the command cwd to resolve inside LOCALMCP_ROOT.

YOLO mode is not an OS sandbox. An executed program can still read or modify files outside the workspace, access the network, spawn other processes, or execute code with the permissions of the localmcp process. Use an OS/container sandbox if you need process-level isolation.

Commands use Node.js spawn(..., { shell: false }), so localmcp does not wrap command input in a shell. Child processes receive a minimal environment (PATH, home/temp/locale variables as applicable) instead of inheriting all server environment variables, reducing accidental secret leakage. run_command accepts an optional per-call timeout_ms (1–600000 ms), overriding LOCALMCP_TIMEOUT_MS for that invocation. Its MCP result includes structured exit_code, signal, stdout, stderr, timed_out, truncated, and duration_ms fields in addition to the human-readable text result.

Requirements

  • Node.js 18+

  • Any command-line tools you want to execute must be installed and available on PATH

Install

npm install

Run

macOS/Linux:

LOCALMCP_ROOT="$HOME/src/my-project" npm start

PowerShell:

$env:LOCALMCP_ROOT = "C:\src\my-project"
npm start

The default mode is strict.

The MCP endpoint is:

http://127.0.0.1:8787/mcp

Server-side tool logs

Every MCP tool call is logged to stderr with its tool name, status, duration, and summarized input:

[localmcp] 2026-10-01T05:50:55.635Z tool=tree status=ok duration_ms=7.5 input={"path":".","max_depth":1,"max_entries":20,"respect_gitignore":true}

Large edit/file contents are summarized instead of being printed verbatim. These logs make it possible to follow the sequence of actions an AI client performs against the workspace.

Configuration

  • PORT — HTTP port (default 8787)

  • LOCALMCP_ROOT — exposed workspace root (default: current directory)

  • LOCALMCP_MODE — execution mode: strict (default) or yolo

  • LOCALMCP_ALLOWED_COMMANDS — comma-separated executable allowlist used by strict mode (default: empty)

  • LOCALMCP_TIMEOUT_MS — default command timeout (default 120000); individual run_command calls may override it with timeout_ms

  • LOCALMCP_MAX_OUTPUT — maximum chars captured per stdout/stderr stream (default 200000)

  • LOCALMCP_MAX_FILE — maximum text file size in bytes (default 1000000)

  • LOCALMCP_MAX_IMAGE — maximum image size in bytes returned by read_image (default 10000000)

  • LOCALMCP_APPROVAL_CODE — optional fixed code entered on the local OAuth approval page; if omitted, a random code is generated and printed at startup

  • LOCALMCP_PUBLIC_URL — public HTTPS origin used in OAuth metadata, for example https://example.ngrok-free.app; recommended whenever a tunnel or reverse proxy is used

  • LOCALMCP_ALLOWED_ORIGINS — comma-separated exact browser origins permitted to call /mcp (default: none)

Test

npm test

The test suite covers workspace path confinement, symlink escape rejection, command allowlisting, per-call command timeouts and truncation, gitignore/exclude-aware traversal, safe ranged reads, search, line slicing, guarded edits, and multi-edit patching.

Test with MCP Inspector

npx @modelcontextprotocol/inspector@latest

Choose Streamable HTTP and connect to http://127.0.0.1:8787/mcp.

Connect to ChatGPT

ChatGPT needs a reachable HTTPS /mcp URL. For development, expose port 8787 with a tunnel and use the resulting HTTPS URL ending in /mcp.

A public tunnel creates an entry point to your machine. Keep LOCALMCP_ROOT narrow and use strict mode. localmcp now exposes an OAuth 2.1 authorization-code flow with PKCE, protected-resource metadata, dynamic client registration, short-lived access tokens, and rotating refresh tokens.

When using a tunnel, pass its public origin explicitly so OAuth metadata and the MCP resource audience are stable:

localmcp "$HOME/src/my-project" \
  --strict \
  --allow git \
  --public-url "https://your-tunnel.example"

At startup localmcp prints an OAuth approval code. In ChatGPT, create the MCP app using:

https://your-tunnel.example/mcp

Choose OAuth. ChatGPT will open the localmcp authorization page in your browser. Enter the approval code printed by the server and choose Allow. ChatGPT then completes PKCE and stores its OAuth access/refresh tokens.

The OAuth endpoints are:

  • /.well-known/oauth-protected-resource

  • /.well-known/oauth-authorization-server

  • /oauth/register

  • /oauth/authorize

  • /oauth/token

Use --approval-code or LOCALMCP_APPROVAL_CODE only when you intentionally want a stable approval code across restarts. This code is not an MCP bearer token; it is only used by the human authorization page.

Set LOCALMCP_ALLOWED_ORIGINS (or repeat --origin) only when browser-origin access to /mcp is required. OAuth discovery and token exchange do not require a CORS origin entry.

Persistent OAuth sessions

localmcp persists OAuth client registrations, access tokens, refresh tokens, and the local approval code automatically. The default state file lives under your OS user state directory (for example ~/.local/state/localmcp/) and is keyed by the localmcp instance identity, not the workspace. By default the public URL is the instance identity, so switching from one project directory to another keeps the same ChatGPT connection.

This means the normal flow is:

  1. Connect ChatGPT and enter the approval code once.

  2. Stop and restart localmcp whenever needed.

  3. ChatGPT keeps using the existing connection and refreshes tokens without asking for the approval code again.

The state directory is created with owner-only permissions and the state file is written with mode 0600 on POSIX systems. Short-lived authorization codes are never persisted.

Set LOCALMCP_OAUTH_STATE=/path/to/state.json only if you need to override the default state location. Changing the workspace root does not change OAuth identity. Changing the public URL selects a different OAuth identity because tokens are bound to that protected resource. If you intentionally run multiple independent localmcp instances behind the same public URL, use --instance-id <id> or LOCALMCP_INSTANCE_ID to separate their stored credentials. On first startup after upgrading, localmcp automatically merges compatible legacy workspace-scoped OAuth state files for the same public URL into the new instance-scoped state.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets ChatGPT or MCP clients work with files on your machine, with tools for reading, editing, searching, git operations, and safety checks.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables ChatGPT or any MCP client to operate safely on a designated workspace by listing, reading, searching, writing, and trashing files, inspecting Git status/log/diff, and optionally running allowlisted executables without a shell.
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI clients like ChatGPT or Codex to manage files and local Git repositories within an explicitly authorized workspace, with server-enforced path boundary checks and optional remote Git operations.
    18
    1
    MIT