Skip to main content
Glama
local-agent-mcp
by ezra-y

Local Agent MCP

English · Permissions · Architecture

Let ChatGPT Pro work directly on your local computer

You assign tasks in ChatGPT, and it can call local MCP tools: read projects, modify files, run tests, check Git Diff, create Commits.

Complex tasks can be handed off to local Codex. ChatGPT continues to handle breaking down steps, checking progress, adding requirements, and final review.

ChatGPT Pro
→ Local Agent MCP
→ 本地文件 / 测试 / Git / Codex

No need to repeatedly copy code, and no need to route every task through Codex.

This is an unofficial community project. It is not an OpenAI product and does not represent OpenAI.

Related MCP server: chatgpt-codex-tools-mcp

Quick Start

Prerequisites

Prepare the following:

  • macOS or Linux

  • Python 3.11 or later

  • Git

  • uv

  • OpenAI official tunnel-client

  • A ChatGPT environment that supports custom MCP Apps

  • A Tunnel ID

  • A corresponding Tunnel Runtime Key

On macOS, you can install the basic tools first:

brew install uv tmux
brew install openai/tools/tunnel-client

One sentence to hand it to AI

Send this sentence to an AI that can operate a local terminal:

Install https://github.com/ezra-y/local-agent-mcp on my computer, and follow the README to complete configuration, startup, and verification.

Manual installation: see Install to ChatGPT.

Highlights

Highlight

Description

ChatGPT directly operates local projects

Common file, test, and Git operations are done by ChatGPT calling local tools directly.

ChatGPT acts as the overall director

Simple tasks are completed directly; complex tasks can be handed off to local Codex.

Agents can be extended further

Codex is the first Adapter; future Agents go into the same control layer.

Task status is queryable

Workflow, Step, and Job are saved to local SQLite and remain viewable after restart.

Prevents duplicate execution

The same workflow_id + step_id + attempt returns the original Job.

Clear Git process

Check status and Diff first, then commit explicitly listed files; no automatic Push.

Transparent permissions

Both Tools and Resources can return current permission information.

28 Tools

Category

Tools

Purpose

Permissions

get_permissions

View the current root directory, hard limits, and high-permission entry points.

Files

list_files, read_file, write_file, apply_patch

List, read, create, overwrite, or partially modify text files.

Commands & Tests

run_command, run_tests, get_job, cancel_job

Run commands or tests, and view or stop background Jobs.

Git

git_status, git_diff, git_commit

View status, view Diff, commit explicitly listed files; safe Commit disables Hooks and signing, and rejects Git Filters.

Workflows

create_workflow, create_step, start_step, get_workflow

Create a Workflow, create a Step, start a Job, query overall status.

One-shot read-only Codex

ask_codex, start_codex_job, get_codex_job, cancel_codex_job

Have local Codex do a one-time read-only check.

Codex Threads / Turns

list_codex_threads, read_codex_thread, resume_codex_thread, start_codex_turn, steer_codex_turn, interrupt_codex_turn, get_codex_turn_status

Read old Threads, start, resume, supplement, stop, and check Codex Turns.

Health check

ping

View service status, active Job count, and Artifact capacity warnings.

A direct delete_file Tool is not exposed. apply_patch also refuses to delete entire files.

git_commit disables repository Hooks and commit signing by default. When a clean / process Git Filter is detected, it refuses to commit to avoid structured Commits implicitly running repository programs. git_diff also disables external Diff and textconv.

Permissions Resource

In addition to the get_permissions Tool, the service also provides:

local-agent://permissions

The content includes:

当前允许访问哪里
哪些目录和文件被禁止
读写是否开启
有没有直接删除工具
高权限入口有哪些

get_permissions will continue to be kept for clients that do not yet display MCP Resources.

Permissions and Privilege Reduction

Default Scope

Structured file and Git tools can access the current user's Home by default:

$HOME

This usually includes Desktop, Downloads, Documents, and other projects in personal directories.

Things Forbidden by Code

Structured file tools will refuse:

.ssh
.aws
.azure
.codex
.docker
.gnupg
.kube
.Trash
Library
.env 和 .env.*
常见凭据文件
.pem / .key / .p12 / .pfx 私钥文件
符号链接路径

Additionally:

  • There is no direct file deletion Tool.

  • apply_patch cannot delete entire files.

  • There is no Git Push Tool.

  • git_commit only commits explicitly listed paths.

Narrowing the Structured Scope

Set before startup:

export LOCAL_AGENT_MCP_ROOT="$HOME/Projects"

The old config name CODEX_MCP_ROOT remains compatible.

After that, these tools can only access $HOME/Projects:

list_files
read_file
write_file
apply_patch
git_status
git_diff
git_commit

Foreground startup example:

export LOCAL_AGENT_MCP_ROOT="$HOME/Projects"
./scripts/run_tunnel.sh

High-Permission Entry Points

Capability

Actual Scope

run_tests

Will execute project code. Test code can create, modify, or delete files.

run_command

The invoked local program may access locations outside the structured root directory.

Full Codex Turn

Can read/write, run commands, and access the network, and may also access locations outside the structured root directory.

LOCAL_AGENT_MCP_ROOT is the hard boundary for structured file and Git tools, not a system sandbox for the entire process.

When repository Hooks, Git LFS, or other Filters are needed, commit manually, or use the high-permission run_command after explicitly checking the repository configuration.

v0.5.1 does not yet have per-Tool hide or disable configuration. For stronger isolation, use a separate system user, virtual machine, container, or maintain a version with trimmed Tools.

Full details: docs/permissions.md.

Install to ChatGPT

1. Download and test

git clone https://github.com/ezra-y/local-agent-mcp.git
cd local-agent-mcp
uv sync --locked --all-groups
uv run pytest -q

Local Codex lookup order:

  1. The path specified by CODEX_BIN.

  2. codex in PATH.

  3. The Codex built into the macOS ChatGPT App.

2. Save the Runtime Key

macOS:

./scripts/save_tunnel_key.sh

Linux:

export CONTROL_PLANE_API_KEY="<你的 Runtime Key>"

3. Generate Tunnel configuration

export CONTROL_PLANE_TUNNEL_ID="tunnel_<32位小写十六进制>"
./scripts/configure_tunnel.sh

Local configuration is saved at:

.runtime/profiles/

4. Start the Tunnel

Foreground:

./scripts/run_tunnel.sh

Background:

tmux new-session -d \
  -s local-agent-mcp-tunnel \
  -c "$PWD" \
  ./scripts/run_tunnel.sh

Wait for the service to be ready:

for i in {1..30}; do
  curl -fsS http://127.0.0.1:8741/readyz && break
  sleep 1
done

On success it returns:

ready

Local status page:

http://127.0.0.1:8741/ui

5. Connect in ChatGPT

  1. Open Settings → Apps.

  2. Enable Developer Mode.

  3. Create or connect the corresponding custom MCP App.

  4. After the Tunnel starts, click Refresh / Scan tools.

  5. Start a new chat and select @Local Agent.

6. Verify

Send in a new chat:

@Local Agent

调用 get_permissions。
报告当前工具总数、版本和 allowed_root。

Expected result for v0.5.1:

工具总数:28
版本:0.5.1
allowed_root:你的 Home,或你设置的 LOCAL_AGENT_MCP_ROOT

If the client supports Resources, try reading:

local-agent://permissions

Run Local stdio MCP Only

When not using the ChatGPT Tunnel:

./scripts/run_mcp.sh

You can also install it as a global command:

uv tool install .
local-agent-mcp

The old command local-codex-mcp still works.

Daily Use

The project parameter in tools is usually a path relative to $HOME:

Documents/Codex/local-agent-mcp
Downloads/my-project
Desktop/example-project

Absolute paths inside Home are also supported. project="." represents the entire structured root directory; with default settings, that is the entire Home.

A Common Task

@Local Agent

在 Downloads/my-project 修复登录失败问题。
检查相关代码和 Git 状态,完成修改、测试、Diff 和 Commit。

Common flow:

get_permissions
→ git_status / list_files / read_file
→ write_file / apply_patch
→ run_tests
→ git_diff
→ git_commit

For complex tasks, you can add an explicit Workflow or local Codex.

How Workflows Run

Five Concepts

Concept

Meaning

Workflow

The whole thing the user asks for.

Step

A stable, explicit action within a Workflow.

Job

One actual execution of a Step.

Codex Thread

The chat and work context saved by Codex.

Codex Turn

One round of work within a Thread.

Execution Order

create_workflow
→ create_step
→ start_step
→ get_job / get_workflow

create_step currently supports four execution types:

executor_kind

Purpose

tests

Run tests.

command

Run a local command in argument-array form.

codex_exec_readonly

Have Codex do a one-time read-only check.

codex_turn

Start a Codex Turn that keeps working.

File reading and modification are still done directly by read_file, write_file, and apply_patch.

Example: Creating a Test Step

create_workflow(
  project="Downloads/my-project",
  title="验证登录修复"
)
→ workflow_id
create_step(
  workflow_id=workflow_id,
  position=1,
  name="运行测试",
  executor_kind="tests",
  spec={
    "argv": ["uv", "run", "pytest", "-q"],
    "cwd": ".",
    "timeout_seconds": 900
  },
  write_scope="worktree"
)
→ step_id
start_step(
  workflow_id=workflow_id,
  step_id=step_id,
  attempt=1
)
→ job_id
get_job(job_id)
get_workflow(workflow_id)

The execution identity is:

workflow_id + step_id + attempt

Starting again with the same number returns the original Job and does not execute again. For an explicit rerun, use a new attempt, e.g. attempt=2.

Parallel Rules

同一个 Codex Thread:同一时间一个活动 Turn
同一个 Worktree:同一时间一个写入者
同一个仓库:不同 Worktree 可以并行

Use steer_codex_turn to add requirements to an active Turn, and interrupt_codex_turn to stop it.

Local State and Logs

When running from source:

.runtime/state.sqlite3
.runtime/artifacts/<job_id>/

The installed command uses by default:

$HOME/.local/state/local-agent-mcp/state.sqlite3

Custom location:

export LOCAL_AGENT_MCP_STATE_PATH="/自定义位置/state.sqlite3"

The old config name CODEX_WORKFLOW_STATE_PATH remains compatible. Existing old state databases will continue to be read.

Long logs are stored in Artifact files. SQLite saves the path, size, and SHA-256.

Artifacts are not deleted automatically. When the total recorded amount exceeds 1 GiB, ping returns a warning.

Updates

git pull
uv sync --locked --all-groups
uv run pytest -q

Then restart the Tunnel and click Refresh / Scan tools in ChatGPT.

Project Structure

src/local_agent_mcp/
├── server.py                 MCP 入口与公共 Tool / Resource
├── adapters/                 本地 Agent Adapter;当前包含 Codex
├── workflow_*.py             Workflow、Step、Job、锁和 SQLite
├── command_jobs.py           后台命令与测试
├── workspace_tools.py        文件读写与 Patch
└── git_tools.py              Git 状态、Diff 和 Commit

tests/                        单元测试与集成测试
docs/                         权限和架构说明
scripts/                      MCP 与 Tunnel 启动脚本

Test files are kept in the repository. They are used to verify permission boundaries, cross-platform operation, packaging, and compatibility; the installed wheel only contains runtime code.

Development Checks

uv run pytest -q
uv run python scripts/check_public_release.py
zsh -n scripts/*.sh
uv build

The main MCP entry point is src/local_agent_mcp/server.py. src/codex_bridge.py is kept as a compatibility alias for old imports and old startup methods.

Uninstall and Local Data

The uninstaller does not automatically delete SQLite, Artifacts, Tunnel profiles, or the source directory. Please check first and decide which data to keep.

License

MIT, see LICENSE.

⚠️ The default configuration opens fairly broad local permissions: ChatGPT can read and write most projects under the current user's Home, and can run tests, commands, and local Agents; only use this on computers, accounts, and projects you trust.

Available Tools

28 tools
apply_patchApply project patchB
Destructive

Apply an authorized Begin Patch block transactionally.

Inputs: patch (required), project (required). Returns: result

ask_codexAsk local CodexA
Read-only

Start a read-only local Codex job and return its job ID immediately.

The project is a path relative to the configured Codex root. The server rejects paths outside that root and always runs Codex in read-only mode. Use get_codex_job to retrieve the final result.

Inputs: prompt (required), attempt, project, step_id, +1 more. Returns: result

cancel_codex_jobCancel local Codex jobB
Idempotent

Cancel a local Codex job; force only releases unconfirmed state.

Inputs: job_id (required), force. Returns: result

cancel_jobCancel command jobC
DestructiveIdempotent

Cancel a unified job; force only releases unconfirmed state.

Inputs: job_id (required), force. Returns: result

create_stepCreate workflow stepC
Idempotent

Create an immutable executable Step inside one Workflow.

Inputs: name (required), spec (required), position (required), workflow_id (required), +3 more. Returns: result

create_workflowCreate workflowB

Create a durable Workflow for a multi-Step task.

Inputs: title (required), project (required), metadata. Returns: result

get_codex_jobGet local Codex jobB
Read-onlyIdempotent

Get the status and result of a local Codex job.

Inputs: job_id (required). Returns: result

get_codex_turn_statusGet local Codex turn statusA
Read-onlyIdempotent

Get status, items, and final agent message for one Codex turn.

Inputs: turn_id (required), thread_id (required). Returns: result

get_jobGet command jobA
Read-onlyIdempotent

Get unified command, test, Codex, or Codex Turn job status.

Inputs: job_id (required). Returns: result

get_permissionsGet effective permissionsA
Read-onlyIdempotent

Return the effective root, hard boundaries, and tool-use policy.

Inputs: no named parameters. Returns: result

get_workflowGet workflowB
Read-onlyIdempotent

Get a durable Workflow with its Steps and Job attempts.

Inputs: workflow_id (required). Returns: result

git_commitCreate Git commitB
Destructive

Commit authorized paths without hooks, signing, filters, or pushing.

Inputs: paths (required), message (required), project (required). Returns: result

git_diffGet Git diffA
Read-onlyIdempotent

Return a bounded workspace or staged diff and its stat.

Inputs: project (required), path, scope. Returns: result

git_statusGet Git statusA
Read-onlyIdempotent

Return branch, HEAD, modified, staged, and untracked files.

Inputs: project (required). Returns: result

interrupt_codex_turnInterrupt local Codex turnC
DestructiveIdempotent

Interrupt an active local Codex turn.

Inputs: turn_id (required), thread_id (required). Returns: result

list_codex_threadsList local Codex threadsB
Read-onlyIdempotent

List local Codex app-server threads, optionally filtered by project.

Inputs: limit, cursor, project, archived, +1 more. Returns: result

list_filesList project filesA
Read-onlyIdempotent

List readable files in a project under the configured structured root.

Set include_all to true to include dependencies, runtime state, Git internals, and caches. Credential files and credential directories are always excluded. Paths are relative to the selected project.

Inputs: project, include_all. Returns: result

pingCheck local MCP bridgeA
Read-onlyIdempotent

Return bridge process health without accessing project files.

Inputs: no named parameters. Returns: result

read_codex_threadRead local Codex threadB
Read-onlyIdempotent

Read thread metadata and a bounded, paginated page of turns.

Inputs: thread_id (required), cursor, turn_limit, include_turns. Returns: result

read_fileRead project fileA
Read-onlyIdempotent

Read one UTF-8 text file from a selected project.

Both the project and file path are constrained to the configured root. Common credential files and credential directories are excluded; Git files, dependencies, and runtime configuration are readable.

Inputs: path (required), project (required). Returns: result

resume_codex_threadResume local Codex threadA
Destructive

Load an existing local Codex thread with unattended full access.

This is a high-privilege entry point. Use it only after explicit user authorization under the permission policy returned by get_permissions.

Inputs: thread_id (required), project. Returns: result

run_commandRun project commandA
Destructive

Start an argv-based command job and return its ID immediately.

This is a high-privilege entry point. No shell is inserted, but the chosen executable can access paths outside the structured root. Use it only under the explicit policy returned by get_permissions. Use get_job for output and cancel_job to stop it.

Inputs: argv (required), project (required), cwd, attempt, +3 more. Returns: result

run_testsRun project testsA
Destructive

Start authorized project tests as a background job.

Test code can create files and execute project-controlled code.

Inputs: project (required), cwd, argv, attempt, +4 more. Returns: result

start_codex_jobStart local Codex jobC
Read-only

Start a read-only Codex inspection job and return immediately.

Inputs: prompt (required), attempt, project, step_id, +1 more. Returns: result

start_codex_turnStart local Codex turnA
Destructive

Start a persistent app-server turn and return its IDs immediately.

Omit thread_id to create a new local Codex thread. Poll with get_codex_turn_status; the turn continues after this MCP call returns. This is a high-privilege entry point and may access paths outside the structured tool root.

Inputs: prompt (required), model, effort, attempt, +4 more. Returns: result

start_stepStart workflow stepA
Idempotent

Start one explicit Step attempt or return its existing Job.

Inputs: attempt (required), step_id (required), workflow_id (required). Returns: result

steer_codex_turnSteer local Codex turnB
Destructive

Send additional instructions to an authorized active Codex turn.

Inputs: prompt (required), turn_id (required), thread_id (required). Returns: result

write_fileWrite project fileC
DestructiveIdempotent

Create or replace one UTF-8 file after explicit user authorization.

Inputs: path (required), content (required), project (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3/5.0

    Scored across 28 tools

    Disambiguation2/5

    Several tools have near-identical purposes: ask_codex and start_codex_job both start read-only Codex jobs, and get_codex_job/cancel_codex_job duplicate functionality already covered by the unified get_job/cancel_job. The distinction between Codex jobs, Codex turns, and workflows is also fuzzy, making selection error-prone.

    Naming Consistency3/5

    Most tools follow verb_noun snake_case (e.g., list_files, cancel_job), but there are inconsistencies: 'ask_codex' uses an unconventional verb, 'ping' is a bare noun, and the mix of ask/start/steer/intrerupt for Codex operations lacks a clear pattern. Still, the majority are consistent enough to be readable.

    Tool Count2/5

    With 28 tools, the surface is heavy, especially given the redundant job/turn management tools. Several tools could be merged or eliminated (e.g., ask_codex/start_codex_job, get_codex_job/get_job), suggesting the count is inflated beyond what the domain requires.

    Completeness4/5

    The surface covers core local agent operations well: file read/write/patch/list, git status/diff/commit, command and test execution, workflow management, and Codex interactions (jobs, turns, threads). Minor gaps exist (no delete file or git push), but the main workflows are supported.

    Related MCP Connectors

    Related MCP Servers