MCP Dev Runtime
Enables ChatGPT to connect to and operate within a local development environment via a secure tunnel, providing tools for shell commands, file management, and execution history.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Dev Runtimerunnpm testin the project root and show me the output"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Dev Runtime
Give your MCP client direct access to your own development environment.
English | 简体中文
Want to connect ChatGPT to your computer? English setup guide · 简体中文图文教程
Shell commands, interactive terminals, file patches, images and execution history through six MCP tools. Connect locally over HTTP or stdio, or connect ChatGPT through the optional OpenAI Secure MCP Tunnel.
This is an independent community project, not an OpenAI product. The runtime executes operations itself: it does not launch Codex, delegate to another agent, or call a model API. It is not a remote-desktop viewer or a mouse/keyboard automation service.
Trust boundary: commands run with the service user's OS permissions. There is no sandbox, command allowlist, additional approval layer or multi-user isolation. Keep the listener on loopback and connect only trusted clients. Returned files, logs and images reach the calling client; local execution does not mean local-only data handling. Read SECURITY.md before connecting a machine.
Precompiled v1.2.0: Download the matching runtime package · Installation and upgrade guide. Includes Node, native dependencies and the pinned Tunnel; no build toolchain is needed. Publisher signing / Apple notarization are skipped for this release.
Contents
Choose a connection · Requirements · Install · Global command / mdr · Local HTTP / stdio · ChatGPT deployment · Tools · History · Configuration · Operations · Logs · Troubleshooting · Validation · Documentation
Related MCP server: ChatGPT MCP Bridge
Choose a connection
Use case | Connection | Startup |
A local MCP client that supports HTTP | Loopback Streamable HTTP |
|
A client that starts an MCP subprocess | stdio | Configure the client to run |
ChatGPT accessing your private computer | OpenAI Secure MCP Tunnel → local HTTP |
|
flowchart TB
subgraph cloud["OpenAI cloud"]
chatgpt["ChatGPT"]
relay["OpenAI Tunnel service"]
chatgpt <-->|"Tool requests and results"| relay
end
subgraph computer["Your computer"]
tunnel["tunnel-client"]
runtime["MCP Dev Runtime"]
local["Local MCP client - alternative connection"]
tools["Shell, files, Git, builds and tests"]
history["Bounded local execution history"]
tunnel <-->|"Loopback HTTP: 127.0.0.1:3001/mcp"| runtime
local <-->|"Local HTTP or stdio"| runtime
runtime <--> tools
runtime <--> history
end
relay <-->|"HTTPS transport initiated by tunnel-client"| tunnelArrows show request/response data flow, not who opens an inbound network connection. The local tunnel-client initiates outbound HTTPS to OpenAI, receives work, forwards it to MCP Dev Runtime over loopback HTTP, and returns the result. ChatGPT does not connect directly to your localhost, and no public inbound port is required. The local-client path bypasses Tunnel entirely; it is an alternative, not an extra required component. Platform and workspace access remain prerequisites. See the official Tunnel guide.
Choose one startup method per instance. npm start starts only MCP; npm run up starts both MCP and Tunnel. Running both on port 3001 causes a port conflict. Local-only use does not require Tunnel credentials or Go.
Requirements
For the recommended precompiled distribution, use a matching macOS/Linux tarball or Windows x64/ARM64 ZIP; no external Node/npm/Go/compiler is required. See binary installation and Windows installation. The table below applies to macOS/Linux source development, not the release installer. Windows source development requires Node/npm and the pinned Go toolchain, without MSVC or WSL.
Requirement | When needed |
Node.js 24 or newer, with npm | Installation, TypeScript build and runtime |
Git | Cloning, source workflows and optional Tunnel source retrieval |
ripgrep ( | Recommended for code search and diagnostic toolchain checks |
Python 3 and a C/C++ toolchain | Native dependency builds when compatible prebuilt packages are unavailable |
Go and | Only when building the pinned Tunnel client from source; this pin declares Go 1.27.0 in |
Verify the basics in the terminal that will launch the service:
node --version
npm --version
git --version
rg --versionOn macOS, install Xcode Command Line Tools with xcode-select --install if native builds require them. On Debian/Ubuntu, the usual native build dependencies are build-essential, python3 and pkg-config; install Node.js separately and confirm it meets the requirement. See node-pty's build prerequisites. Do not run this project with sudo.
Precompiled release verification requires macOS 14 ARM64, macOS 15 Intel, Ubuntu 22.04 x64/ARM64, Windows Server 2025 x64 and Windows 11 ARM64 native runners. Exact package results are published in VERIFICATION.json; mock/local lifecycle tests do not claim real cloud connectivity. Source regression checkpoints remain in VALIDATION.md.
1. Install
Recommended: download a precompiled release, verify its SHA-256, extract it and run ./install.sh on macOS/Linux or .\install.ps1 in Windows PowerShell. The binary guide and Windows guide cover user directories, commands, upgrade and rollback. Release installers do not compile or download dependencies.
v1.0.1 and later: complete uninstall is ./uninstall.sh. It lists every owned path it will remove and proceeds only after the user enters y; precompiled installation also preserves a stable user-level copy so the downloaded archive does not need to be kept. The immutable v1.0.0 archive predates this feature and retains its command-only ./install.sh --unregister.
Source development alternative
The shell commands below target macOS/Linux. For native Windows source setup, use the Windows source guide instead; do not install Bash or WSL merely to run these examples.
Clone the repository below; a private repository requires an account with access. For a fork, use its clone URL instead. For an extracted source archive, skip cloning and enter the extracted project directory.
git clone https://github.com/dolibali/mcp-dev-runtime.git
cd mcp-dev-runtime
./install.shThe setup is intentionally local and repeatable. New installations create only one non-secret config.json plus private runtime.env when missing, then verify or build the Tunnel source pinned by tunnel.lock.json and finish with offline diagnostics. Existing legacy launcher.config.json + config.json installations remain supported and are never rewritten automatically. If a compatible pinned Tunnel binary is already present, it is reused; otherwise setup fetches the exact locked source and builds tunnel-client-runtime into the ignored .runtime/bin/<commit>/ cache. It never installs system packages with sudo, Homebrew or apt, and never overwrites existing configuration or credentials.
For local-only HTTP/stdio use, skip Tunnel preparation:
./install.sh --local-onlyThe equivalent npm entry point is npm run setup; pass setup flags after npm's separator, for example npm run setup -- --local-only. Use ./install.sh --force-tunnel-build only when you deliberately want to rebuild the exact locked Tunnel source. Run ./install.sh --help for the complete setup options.
On a repeated run, a package-lock hash under ignored .runtime/setup/ avoids an unnecessary npm ci when dependencies are already known to match. If dependencies do need refreshing and a launcher-managed runtime appears active, setup refuses to replace node_modules underneath it. Stop owned work first rather than forcing the refresh.
The example config works from the repository root. To work elsewhere, edit config.json and set runtime.cwd to an existing workspace directory. In the unified format, configuration paths are resolved relative to config.json; history.directory is still resolved from the effective workspace. cwd is a default, not a filesystem access restriction. See configuration.
Development dependencies are needed for the build. The install path also prepares this checkout's native PTY helper; native packages may still require the platform build prerequisites listed above when no compatible prebuilt package exists. This repository is currently private: true in package.json to prevent accidental npm publication. It does not prevent GitHub source distribution; do not assume npx mcp-dev-runtime installs this project.
Use the command from any directory
Both installation modes provide the same CLI. Binary packages use their own bundled Node and user-scoped configuration; the source-specific npm run command:* instructions below apply to checkouts. v1.0.1 and later use ./uninstall.sh for complete removal; v1.0.0 retains its earlier command-only ./install.sh --unregister. See binary installation.
After successful setup, a user-level global command is registered at ~/.local/bin/mcp-dev-runtime. Setup also tries to register the short mdr command automatically when that name is free. If mdr conflicts with another program, only the short alias is skipped and the installation still succeeds. Both entries use the same checkout, Node executable, Tunnel cache and configuration; they do not copy a second runtime or require sudo. Keep the checkout and its Node installation in place.
For an already installed instance, register only the command without reinstalling dependencies, changing credentials or restarting services:
npm run command:installOnce the directory is on PATH, these work outside the repository:
mcp-dev-runtime --help
mcp-dev-runtime --version
mcp-dev-runtime status
mcp-dev-runtime doctor
mcp-dev-runtime doctor --json
mcp-dev-runtime smokeStatus has three output levels:
mdr status
mdr status --verbose
mdr status --json
mdr paths
mdr config
mdr toolsPlain status is a short human-readable summary for daily checks. --verbose adds process IDs, instance IDs, latency, memory, retained-session/history sizes and Tunnel version. --json preserves the complete machine-readable supervisor object for scripts and deep troubleshooting. The long mcp-dev-runtime command supports the same flags; from npm use npm run status -- --json or npm run status -- --verbose.
mdr paths shows only the paths actually resolved for the current installation. mdr config shows effective non-secret settings, and mdr tools shows which registered tool policies are enabled. None of these commands prints the contents of runtime.env. Add --json for machine-readable output.
New unified configs set runtime.env_file to runtime.env, so mcp-dev-runtime up --background can be used from any directory without putting a secret on the command line. Existing legacy launcher configs keep their previous env_file behavior. An explicit --env-file FILE remains a temporary override and is resolved from the invoking terminal. Registration itself never reads or changes runtime.env and never starts or stops a service.
Management commands use the installed checkout's configuration and working-directory base, not another project's same-named files. Explicit path flags remain caller-relative. mcp-dev-runtime serve is different: it keeps the caller's working directory for local HTTP/stdio use. Global smoke derives its URL from the selected configuration; the older npm run smoke script still takes an explicit URL for nondefault ports.
If ~/.local/bin is not on PATH, the installer prints the exact export to run. For the default directory:
export PATH="$HOME/.local/bin:$PATH"Add that line to the relevant shell startup file for future terminals; the installer does not modify .zshrc, .bashrc or other profiles. An existing unrelated command is never overwritten. A command earlier on PATH is reported rather than silently replaced. Each registered wrapper uses the Node selected at registration; after intentionally removing/moving that Node version, register again with the desired compatible Node.
Remove just this checkout's command with npm run command:uninstall from the repository. Configurations, Tunnel, history and running services remain untouched. For a complete source uninstall, run ./uninstall.sh; after explicit y confirmation it safely stops this checkout's managed instance and removes its owned commands, local configuration/credentials, runtime/history data, dist and node_modules, while deliberately keeping the Git checkout itself. Unregister before moving the checkout, then register from its new location; an old entry is not silently reassigned to a different source root. Advanced installations can use npm run command:install -- --bin-dir /absolute/path/to/bin and the same --bin-dir when uninstalling. Use ./install.sh --no-global-command for CI or embedded installs that must not register a command.
Short command: mdr
mdr is convenient shorthand for MCP Dev Runtime, but it is not an exclusive command name: Markdown tools such as CleverCloud/mdr and michaelsanford/mdr already use it. The project/package name and canonical command therefore remain mcp-dev-runtime.
During normal ./install.sh / npm run setup, the installer checks mdr automatically. When the name is free, it registers both:
mcp-dev-runtime --version
mdr --versionIf another mdr executable already exists anywhere on the current PATH, or an unrelated file/directory/symlink already occupies the destination, setup prints that the short command was skipped and continues with mcp-dev-runtime. It does not execute, overwrite or delete the other program. Shell aliases/functions are not visible to a child installer, so type -a mdr is still useful when diagnosing an unexpected shell-level conflict. The automatic check describes the PATH at installation time; future installs or different shell environments can still introduce a conflict.
For an older installation, or after a conflicting command has legitimately gone away, retry only the short registration from this repository:
npm run command:install -- --name mdrAfter successful registration and PATH setup, the short command uses the same installation and service as the long command:
mdr --help
mdr --version
mdr status
mdr doctor --json
mdr smokeFor installed MDR, prefer mdr start --bg, mdr status, mdr restart --bg and mdr stop. Existing mdr up / mdr down remain compatibility aliases for start / stop, and --background remains the long form of --bg. mdr --version identifies the project as mcp-dev-runtime, not a renamed package. Do not run npm install -g mdr to install this project; it installs an unrelated Markdown reader.
Remove only the short entry with npm run command:uninstall -- --name mdr. Removing the long entry does not remove the short entry, or vice versa. Specify the same --bin-dir when using a custom directory. Neither removal stops services or deletes configuration, logs or history. Registration options: npm run command:install -- --help.
Why is there a separate --? In npm run doctor -- --json, npm run doctor selects this project's diagnostic script, the standalone -- tells npm to forward the following arguments, and --json is an option for that script. It is not a typo or an extra dash to remove. For normal interactive checks, simply use npm run doctor; add -- --json when you need the script's JSON output. The script invocation is node scripts/doctor.mjs --json; direct Node invocation does not need npm's separator. See the official npm argument-passing reference.
The global command does not go through npm: use mcp-dev-runtime doctor --json, with no extra separator.
2A. Connect a local client
HTTP
Start the server and keep this terminal open:
npm start -- --config config.jsonFrom a second terminal in the repository root:
npm run doctor -- --config config.json
npm run smokeConfigure your local client with transport Streamable HTTP and URL http://127.0.0.1:3001/mcp, using that client's supported configuration format. /healthz is a health check, not the MCP endpoint. smoke verifies tool discovery and a harmless command. Use Ctrl+C in the server terminal to stop this standalone instance; npm run down controls only launcher-managed instances.
stdio
Let the MCP client own the server process instead of starting an HTTP server. A common mcpServers configuration looks like this; the surrounding format is client-specific:
{
"mcpServers": {
"mcp-dev-runtime": {
"command": "/absolute/path/to/node",
"args": [
"/absolute/path/to/mcp-dev-runtime/dist/main.js",
"--transport", "stdio",
"--config", "/absolute/path/to/mcp-dev-runtime/config.json",
"--cwd", "/absolute/path/to/workspace"
]
}
}
}Replace every example path. Find the Node executable with node -p process.execPath; GUI clients may not inherit your terminal's PATH. Use absolute cwd and history paths to avoid client-dependent locations. Do not add banners or other text to the stdio protocol stream. Give concurrent server instances separate history directories. Closing the client can stop its stdio child and that child's active executions.
2B. Deploy for ChatGPT with Secure MCP Tunnel
Complete installation first. Stop any standalone MCP process using the same ports before starting the managed pair. Keep both processes running during tool discovery and subsequent calls. For exact web menu paths, field-by-field instructions and reference images, use the beginner setup guide.
Step 1 — Prepare access and credentials
Use Platform Tunnels to create or select your own tunnel and associate the intended organization/workspace. Creation requires Tunnels Read + Manage; runtime use and selection require Read + Use. ChatGPT developer-mode permission is separate. Consult the official permissions guide when access is missing.
Copy the Tunnel ID from the Tunnels page, not the API keys page. Separately create a Restricted runtime API key on Organization API keys, granting Tunnels Read + Use as described in the official permissions guide. An admin key is not the long-lived runtime credential. The illustrated guide shows where each value comes from and how to link the correct workspace. Availability depends on the account, workspace and current product policy; installing this repository does not grant access.
Step 2 — Verify the pinned Tunnel installation
The recommended ./install.sh already verifies an existing compatible Tunnel or fetches/builds the exact source pinned by tunnel.lock.json. Verify what setup selected:
npm run tunnel:setupIf setup previously used --local-only, or Tunnel preparation stopped because Git/Go/make was missing, install the prerequisite and rerun the normal setup. To deliberately rebuild the locked Tunnel:
./install.sh
# or, only when a rebuild is intentional:
./install.sh --force-tunnel-buildTunnel source builds require Git, make and a Go toolchain satisfying the pinned upstream go.mod. Setup checks these only when a build is actually needed and does not install them system-wide. The launcher verifies the exact source pairing recorded in tunnel.lock.json; matching an upstream version number alone is insufficient. Builds use the narrow tunnel-client-runtime target, not the admin UI or a Codex agent. No unverified latest binary is installed.
Step 3 — Fill in the local credentials file
./install.sh creates runtime.env from the public placeholder file only when it does not already exist and enforces owner-only mode 0600. Edit it locally, replacing both placeholders:
CONTROL_PLANE_TUNNEL_ID=tunnel_00000000000000000000000000000000
CONTROL_PLANE_API_KEY=replace-with-your-own-runtime-keyThe zero-filled ID is an example, not a working tunnel. IDs use tunnel_ followed by 32 lowercase hexadecimal characters. Never put real keys in Git, a public issue, screenshots or command-line arguments.
Exported nonempty credential variables take precedence over the env file. runtime.env is parsed as data: no $HOME expansion, shell sourcing or command substitution. The launcher removes control-plane keys from the MCP child environment; this is hygiene, not a security sandbox.
The unified config already references the adjacent runtime.env through runtime.env_file. A custom Tunnel binary can be configured as tunnel.binary. Keep credential values only in runtime.env, never in JSON.
Step 4 — Start and verify
npm run up -- --env-file runtime.env --background
npm run doctor
npm run smokeExpect doctor to report PASS, with runtime.ok and protocol.ok true and the selected supervisor's health.availability equal to ready. doctor and lifecycle commands use the same --config FILE; --launcher-config FILE remains only for legacy split installations. smoke validates the configured tool allowlist and executes a harmless command when the execution/session tools are enabled. These are local checks, not proof of a successful ChatGPT round trip.
npm run status is available for lifecycle details. The two raw curl probes are optional component-level troubleshooting, not extra required setup steps; see ports and direct probes.
For foreground operation, omit --background; Ctrl+C then stops both managed services. When credentials are intentionally supplied by your login shell, use npm run up -- --shell-env --background instead. Shell loading occurs only when required credentials are missing.
Repeated up reports the existing instance; it does not apply new configuration. Background mode survives closing the launching terminal, but does not install launchd/systemd or a boot service and does not keep a sleeping computer online.
Step 5 — Connect and test in ChatGPT
In ChatGPT on the web, open Settings → Security and login → Developer mode, then visit Plugins and use the plus button to create a developer-mode app. Some workspaces still use Settings → Apps → Advanced Settings, followed by Apps → Create; managed workspaces may require admin approval first. The beginner guide explains both routes with official references.
Set the name to mcp-dev-runtime. Under Connection, choose Tunnel, not Server URL, and select the same Tunnel ID as your local config. For this project's default loopback server, select No Authentication for MCP authentication; the separate runtime API key authenticates the Tunnel connection and must not be pasted into an OAuth field. Choose Scan Tools when the form provides that button, check the six tools, then Create; interfaces with automatic discovery should be checked at that stage instead. The field-by-field walkthrough also explains why the official reference screenshot shows OAuth while this default setup does not use it.
Select the app in a conversation and start with a harmless request:
Use MCP Dev Runtime to run
pwdandprintf 'mcp-ready\n'. Return the actual output and exit code. Do not modify any files.
After upgrading, refresh/review the client's tool definitions. Check for label and capture_output on exec_command, scope on list_exec_sessions, and archive_id, tail_lines, search on write_stdin. Local restart and client schema refresh are separate operations.
Six tools, one development workflow
Tool | Capabilities |
| Shell commands, code/file searches, Git, builds and tests; optional PTY, task label and disk output capture |
| PTY input, incremental output, explicit replay, read-only tail/search and archived log reads |
| Codex-style Add/Update/Delete/Move patches, multiple files and hunks |
| Actual PNG/JPEG/WebP image content, with size limits and optional resizing |
| Current sessions or disk history, filtered by workdir, label and outcome |
| Observed termination of a runtime-owned command; not arbitrary OS process control |
All tools publish input and output schemas. Read command text from structuredContent.output; the same chunk is retained in legacy text content for compatibility. Consume one channel, not both. The duplicate representation adds transport overhead, not a second command execution.
yield_time_ms controls how long a call waits, not how long the command may run. timeout_ms is the separate execution deadline. Continue a running command with its returned session_id, never by launching it again. Nonzero exit codes are genuine command results; inspect isError, state and output as well. Multi-file patches are prevalidated but not atomic across files. See tool details and output contract.
Execution history and focused log reads
Completed sessions do not expire by elapsed time by default. Capacity limits still apply, and disk history is distinct from live process state.
Default | Value |
Active executions / completed in-memory records | 8 / 512 |
In-memory output: per session / total | 8 MiB / 64 MiB |
Time-based eviction | Disabled ( |
Disk history: record count / total bytes | 4,096 / 256 MiB |
Captured log per execution / pending write queue | 16 MiB / 1 MiB |
Command preview / raw output persistence | Both off by default; metadata and explicit labels are saved |
For a build whose output must remain available, pass this to exec_command, replacing the workdir with an existing project:
{
"cmd": "npm test",
"workdir": "/absolute/path/to/project",
"label": "project/tests",
"capture_output": true,
"yield_time_ms": 1000
}Save the returned session_id and archive_id. Find the record later with list_exec_sessions:
{"scope":"history","label":"project/tests","order":"desc","limit":10}Use write_stdin for each query below. 123 and the archive string are placeholders to replace with the actual returned IDs:
{"session_id":123,"tail_lines":100,"max_output_tokens":4000}{"session_id":123,"search":"error","max_matches":20}{"session_id":123,"archive_id":"<returned-archive-id>","tail_lines":100}Tail and literal, case-sensitive search are read-only and do not advance the default log cursor. Search results are in matches; continue with search_next_cursor as output_cursor. For ordinary archived paging, use next_output_cursor explicitly. Metadata-only records have no raw output to read. Capture must be enabled when starting the command; it cannot reconstruct already-lost output.
Inspect output_gap, tail_truncated, archive_truncated and history_warning. A stored log can be an incomplete prefix; has_more: false does not prove completeness. Previous-instance tasks with no confirmed final result are unknown, not successes, failures or resumable terminals. History survives restart within its quotas; old process handles and retry guarantees do not. Details: history and recovery.
Configuration and path rules
File | Purpose | Commit it? |
| Public unified MCP / Tunnel / tools / runtime defaults | Yes |
| Your single non-secret MDR configuration | No |
| Legacy split-config compatibility example | Yes |
| Existing legacy launcher settings; new installs do not create it | No |
| Placeholder credentials and proxy examples | Yes, placeholders only |
| Your runtime credentials | Never |
| Public version and source-pin pairing | Yes |
The unified file groups settings under mcp, tunnel, tools, runtime, exec, history, logging and request_cache. tools.allow is fail-closed: only explicitly listed tools are registered and callable. The six established tools are enabled by default; future experimental tools can be implemented without becoming visible until explicitly allowed. Unknown, duplicate and wildcard tool names are rejected.
Default ports
Listener | Default | Setting to change only when necessary |
Local MCP, including |
|
|
Tunnel health, including |
|
|
These are configurable project defaults, not reserved ports for this project or a guarantee against conflicts. Keep them for an installation that already works. On a conflict, stop only a known duplicate instance or choose unused, distinct local ports; do not change the listener to 0.0.0.0 or open public firewall ports as a workaround. Changing a port is not a security feature.
Check active work before stopping, edit the existing config.json, then restart with the same config. The launcher derives the Tunnel forwarding URL from mcp.*. Changing local ports does not change the Tunnel ID. The global mdr smoke follows the selected config; lower-level URL-based verification still needs the actual endpoint. See the port-change procedure.
CLI flags override JSON. In the unified format, configuration paths such as runtime.cwd, runtime.state_dir, runtime.logs_dir, runtime.env_file and tunnel.binary resolve from the config.json directory; relative history.directory resolves from the effective workspace. Explicit CLI path overrides remain caller-relative. Legacy split files keep their original path rules.
For example, merge these settings into your local runtime configuration after replacing the paths:
{
"schema_version": 1,
"runtime": {
"cwd": "/absolute/path/to/workspace",
"shell": "/bin/bash"
},
"tools": {
"allow": [
"exec_command",
"write_stdin",
"apply_patch",
"view_image",
"list_exec_sessions",
"terminate_exec_session"
]
},
"history": {
"directory": "/absolute/path/to/private-runtime-history",
"record_command": false,
"record_output": false
}
}Keep history outside source control. The default .mcp-dev-runtime/ and .runtime/ directories are ignored, but an arbitrary custom directory is not automatically covered. One active writer owns each history directory. Do not share it between independent HTTP or stdio instances. Unified configuration rejects unknown structural keys; config.example.json is the public user-facing reference. The older internal runtime schema remains in contracts/runtime-config.schema.json for compatibility.
For an outbound proxy, set the appropriate HTTPS_PROXY/HTTP_PROXY variables in runtime.env or the launching environment and set NO_PROXY=localhost,127.0.0.1,::1. Do not disable TLS verification as a workaround. Stop and restart after changing environment or connection settings.
Stop, restart, upgrade and clear history
Before stopping, inspect active work through list_exec_sessions with state: "running" and state: "terminating". Stopping the service also stops its owned active commands.
npm run status
npm run down
# Start again after reviewing any configuration changes:
npm run up -- --env-file runtime.env --backgrounddown affects only the selected managed instance. Prefer keeping custom state/log paths in the same unified config.json; temporary --state-dir overrides still work when supplied consistently. It will not adopt an unrelated listener or kill a process merely because an old PID file names it.
For a binary upgrade, follow the versioned installer and rollback procedure. Do not run npm ci inside a binary installation.
For a source upgrade: review/save local changes, stop active work, back up local configuration and required history privately, and check out the reviewed release or commit. Do not overwrite an existing configuration with the example file. Then run:
npm ci --include=dev
npm run build
npm run test:all
# Only when using the managed Tunnel path:
npm run tunnel:setup
npm run up -- --env-file runtime.env --background
npm run doctor -- --config config.json --jsonWhen an upgrade changes the Tunnel pin, update the submodule and explicitly rebuild/verify the matching binary first. Do not edit the lock to disguise a version mismatch. Refresh client tool definitions after the local checks. For rollback, keep the previous source/configuration and a private history backup; do not assume that an older release understands future history formats.
To deliberately erase this configuration's disk execution history, stop its writer first, then run:
node dist/launcher/cli.js history-clear --config config.json --confirmThis is destructive to the selected history. It refuses an active writer and does not delete source code or unrelated command-generated files. Turning capture off does not erase previously saved data.
Temporary readiness failures update health instead of rerunning commands; an actual managed child exit still triggers coordinated shutdown. See deployment details.
Logs: location, viewing and error investigation
For a launcher-managed installation (up), mdr paths reports the actual Logs directory. Binary packages use ~/Library/Logs/mcp-dev-runtime on macOS or the user XDG state directory on Linux. Source checkouts retain .runtime/ beside the source by default. Unified config uses runtime.logs_dir and runtime.state_dir; legacy split configs retain logs_dir/state_dir. The table below shows source defaults; use the actual Logs path for a binary installation.
Default path, relative to the installation | Contents |
| MCP service diagnostics, startup messages and errors |
| Tunnel connection, readiness and network diagnostics |
| Background launcher output; created by |
| Older MCP log segments, when rotation has occurred |
| Older Tunnel log segments, when rotation has occurred |
There is no separate error.log: service errors share the appropriate component's diagnostic stream. Start with mcp-dev-runtime status and mcp-dev-runtime doctor (or mdr status / mdr doctor after registering the short command), then inspect the relevant file. Background startup failures belong in launcher.log, MCP process/protocol diagnostics in mcp.log, and Tunnel connection/authentication/proxy/TLS diagnostics in tunnel.log when emitted. These files combine the managed child's stdout and stderr rather than separating warnings and errors into another file.
Replace the example path with your installation directory, then view recent service logs:
cd /path/to/mcp-dev-runtime
tail -n 100 .runtime/mcp.log .runtime/tunnel.logTo follow new output across log rotation:
tail -F .runtime/mcp.log .runtime/tunnel.logPress Ctrl+C to stop following the logs; this does not stop MCP or Tunnel. For background-launch failures, also inspect tail -n 100 .runtime/launcher.log. A file may not exist before its component has started or emitted its first log message; launcher.log is not created by a foreground-only launch. tail -F can wait for files to appear. Tunnel runs at warning level by default, so an empty or not-yet-created Tunnel log does not by itself mean a failure.
From the same installation directory, search both current and rotated logs for likely errors, with line numbers and three lines of context on either side:
grep -nEi -C 3 'error|failed|failure|exception|panic|timeout|timed out|ECONN|EADDR|ENOTFOUND|EACCES|401|403' .runtime/*.log*Keyword matching is not an error classifier: no match is not proof of health, and grep normally exits with status 1 when nothing matches. A matching word is not automatically a service outage either. Preserve the surrounding context, compare timestamps with the failing operation, and check the current doctor result. Use the real state-directory paths below instead of .runtime/ when customized. Avoid sharing raw runtime.env or complete private logs; review/redact paths, command content, Tunnel IDs and secrets first.
Custom directory: runtime.logs_dir and runtime.state_dir in unified config.json control diagnostics and supervisor state. Relative unified paths resolve from the config file; explicit CLI path overrides resolve from the caller. Legacy launcher files retain their older rules. Plain mcp-dev-runtime status / mdr status shows the resolved log directory; status --json includes absolute component log paths.
For the current source-checkout installation, .runtime/ is intentionally colocated with the project. Precompiled distributions already keep mutable data outside the installed package tree; mdr paths reports the effective layout in both modes.
Service logs are not command-output history. When a build, test or shell command fails, inspect its returned output and actual exit_code, and continue that session with write_stdin if necessary. Disk execution history separately defaults to .mcp-dev-runtime/history/ under the runtime's configured cwd; history.directory in the runtime configuration can move it elsewhere, for example .runtime/history/. Raw tool stdout/stderr is not saved there by default: enable capture_output: true when starting a task to preserve its bounded archive. Query it through the history tools, not by expecting every build's output in mcp.log.
MCP and Tunnel diagnostic logs rotate during writes: unified logging.max_bytes defaults to 10 MiB and logging.files defaults to three files per stream, including the current file. Legacy launcher configs retain log_max_bytes/log_files. The low-volume background launcher.log has separate startup-time rotation. Standalone npm start / serve output goes to its terminal, and stdio diagnostics to the launching client's stderr. Logs and history can contain private paths, code or credentials: keep them out of Git and review/redact them before sharing.
Troubleshooting
Symptom | Check / next action |
| Some ZIP/extraction paths drop Unix executable bits. From a trusted checkout run |
Missing | From a source checkout, run |
Native PTY/image install failure | Confirm Node version and architecture, then native build prerequisites. Run |
| Run |
| Use a toolchain satisfying the pinned module; Go is not needed for local-only startup. |
Port 3001 or 9098 already in use | Check whether standalone MCP and managed startup are both running. Stop the known owner; do not use blanket process-kill commands. |
Missing credentials / 401 / 403 | Check env-file selection, inherited-variable precedence, runtime-key permissions and organization/workspace association. Never post keys with a bug report. |
Tunnel missing from ChatGPT / tool scan fails | Check Tunnel readiness, the selected workspace and permissions against official setup documentation. Local HTTP cannot replace the cloud-to-host Tunnel connection. |
New arguments missing after an upgrade | Restart the local service to load code, then refresh/review the client's cached tool definitions. |
| Inspect active sessions or disk history. An absent record is not permission to rerun a side-effecting command. |
| Output capture was off, or the archive was rotated away. Enable capture on future important tasks. |
History | Inspect warnings, free space, quotas and writer ownership. Commands may work while archival data is unavailable or incomplete. |
Use npm run doctor -- --json and share a redacted diagnostic summary, not full private logs. More: troubleshooting.
Development and validation
Command | Scope |
| Unit, protocol and launcher regressions in temporary workspaces |
| Isolated production-CLI startup, discovery and shutdown |
| Light check against the running default local endpoint |
| All six tools against a running endpoint; uses temporary test files and owned processes |
| Local runtime/HTTP measurements, not ChatGPT or WAN latency |
For a nondefault endpoint, pass its URL to smoke or verify:deployed, for example npm run smoke -- http://127.0.0.1:3011/mcp. Do not run deployment tests on an endpoint you are not authorized to control.
Release preparation passed 195 source regressions and isolated production-CLI checks. The precompiled release gate verifies each exact archive natively, including 13 package acceptance groups and 20 real-tool checks; final evidence is in the release VERIFICATION.json. Earlier workload/latency observations in VALIDATION.md are historical checkpoints, not a guarantee of reliability or throughput. Physical sleep/wake, real WAN interruption, multi-day soak and power-loss durability are not established by package CI.
Tests use no model APIs or contributor credentials. Launcher lifecycle tests use an explicit mock Tunnel; they are not evidence of real OpenAI connectivity. GitHub Actions workflows are included for Ubuntu/macOS and manual source packaging.
Documentation and license
Document | Content |
Full Chinese installation and deployment guide | |
Web menu paths, developer mode, API key, Tunnel ID and first call | |
Paths, environment, lifecycle and troubleshooting boundaries | |
Inputs, outputs, errors and continuation semantics | |
Storage, privacy, tail/search and restart behavior | |
Implementation and pinned compatibility policy | |
Executed evidence and changes | |
Maintainer reference; not required for installation or use |
Licensed under Apache-2.0. Preserve NOTICE and third-party notices. Codex vocabulary and patch syntax are references, not a Codex backend or an endorsement. See security guidance before distribution.
External setup references were reviewed on 2026-09-20. Provider UI, access and terms may change; use the linked official documentation. The runtime itself makes no model calls and imposes no monthly SaaS call quota, but this does not promise unlimited or free access to any hosting, Tunnel, ChatGPT or API service.
This server cannot be deployed
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Related MCP Servers
- AlicenseAqualityBmaintenanceConnects ChatGPT to a local developer workspace through MCP, enabling bounded repository analysis, file and image inspection, direct edits, command verification, and Git-aware review.22MIT
- AlicenseNot gradedqualityBmaintenanceEnables ChatGPT to read and edit local project files, inspect Git changes, and run approved development scripts through a secure MCP tunnel, with optional Codex Desktop integration.112 npm4Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables ChatGPT to operate authorized local projects through MCP, including reading and modifying code, viewing Git changes, running configured programs, and reading local Codex sessions to continue work.493 npm5MIT
- AlicenseAqualityBmaintenanceEnables MCP-compatible AI clients to securely access explicitly authorized local project files and run approved development commands with bounded execution and audit logging.1MIT