nerve MCP server
Commit Oct 27, 2026Enables AI agents to control Android and iOS devices through tools for screenshots, UI element inspection, tapping, swiping, and app management.
Also known as LincForge/nerve
- Stars
- 1
- Tools
- 49
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Oct 27, 2026
- License
- Apache-2.0
What is nerve MCP?
nerve enables AI agents to control Android and iOS devices through tools for screenshots, UI element inspection, tapping, swiping, and app management. It exposes 49 tools, such as nerve_capabilities, nerve_discover, nerve_pool.
Summary generated from the project's README
About nerve MCP server
Controlling Android and iOS devices through AI agents is what nerve enables. This MCP server provides 49 tools that allow agents to perform actions like taking screenshots, inspecting UI element trees, tapping, swiping, typing, and managing applications. It is designed for developers using AI coding agents, offering a way to interact with physical devices or emulators directly from an MCP client like Claude Code.
Users can set up the server locally using Python 3.13+ and the uv package manager. For Android, it utilizes adb and can run on emulators without extra configuration. iOS support is available via WebDriverAgent on macOS. The server includes specialized logic to handle common hardware issues, such as unresponsive adb servers or leaked UiAutomation sessions. To manage token usage, screenshots sent to agents are automatically rescaled to approximately 300k pixels. For advanced visual grounding, users can opt-in to use Meta's SAM 3.1 model by providing a Meta AI API key.
What you can do with it
- 1Inspect mobile UI structuresAn agent can retrieve the current foreground application and a full list of UI elements to understand the screen layout.
- 2Identify unlabelled interface elementsWhen the standard UI tree fails to identify a button, the agent can use visual grounding to find controls on custom canvases.
- 3Debug device connectivity issuesThe server can diagnose the health of the connection between the host and the mobile device.
Written from the project's README. Every use case is checked against a quote from it.
nerve MCP tools 49
Detected from the READMEnerve_capabilitiesnerve_discovernerve_poolnerve_screenshotnerve_stream_screenshotnerve_stream_startnerve_stream_statusnerve_stream_stopnerve_diffnerve_elementsnerve_groundnerve_state
| nerve_capabilities | — | |
| nerve_discover | — | |
| nerve_pool | — | |
| nerve_screenshot | — | |
| nerve_stream_screenshot | — | |
| nerve_stream_start | — | |
| nerve_stream_status | — | |
| nerve_stream_stop | — | |
| nerve_diff | — | |
| nerve_elements | — | |
| nerve_ground | — | |
| nerve_state | — |
Show all 49 toolsShow fewer tools
nerve_navigatenerve_navigate_screenshotnerve_densitynerve_keynerve_long_pressnerve_swipenerve_tapnerve_typenerve_appsnerve_clear_app_datanerve_grant_permissionnerve_installnerve_killnerve_launchnerve_uninstallnerve_emulator_listnerve_emulator_startnerve_emulator_stopnerve_inject_sensornerve_extract_framesnerve_record_fixednerve_record_startnerve_record_stopnerve_actionlog_startnerve_actionlog_stopnerve_replaynerve_ensure_readynerve_networknerve_inspectnerve_logcatnerve_metricsnerve_session_statsnerve_stream_logsnerve_usage_statsnerve_releasenerve_reservenerve_device_state
| nerve_navigate | — | |
| nerve_navigate_screenshot | — | |
| nerve_density | — | |
| nerve_key | — | |
| nerve_long_press | — | |
| nerve_swipe | — | |
| nerve_tap | — | |
| nerve_type | — | |
| nerve_apps | — | |
| nerve_clear_app_data | — | |
| nerve_grant_permission | — | |
| nerve_install | — | |
| nerve_kill | — | |
| nerve_launch | — | |
| nerve_uninstall | — | |
| nerve_emulator_list | — | |
| nerve_emulator_start | — | |
| nerve_emulator_stop | — | |
| nerve_inject_sensor | — | |
| nerve_extract_frames | — | |
| nerve_record_fixed | — | |
| nerve_record_start | — | |
| nerve_record_stop | — | |
| nerve_actionlog_start | — | |
| nerve_actionlog_stop | — | |
| nerve_replay | — | |
| nerve_ensure_ready | — | |
| nerve_network | — | |
| nerve_inspect | — | |
| nerve_logcat | — | |
| nerve_metrics | — | |
| nerve_session_stats | — | |
| nerve_stream_logs | — | |
| nerve_usage_stats | — | |
| nerve_release | — | |
| nerve_reserve | — | |
| nerve_device_state | — |
Configuration
META_AI_API_KEYNERVE_GROUNDINGWDA_PROJECT_DIRWDA_TEAM_ID
| Name | Description | |
|---|---|---|
| META_AI_API_KEY | — | |
| NERVE_GROUNDING | — | |
| WDA_PROJECT_DIR | — | |
| WDA_TEAM_ID | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachablelincforge/nerve is public and reachablegithub.com/lincforge/nerve ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-10-27github.com/lincforge/nerve ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model49 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHublinc-nerve
Field-tested device control for AI coding agents — the self-healing tricks we learned keeping a physical Android/iOS bench alive, as an MCP server and a plain CLI.
nerve exposes 49 tools — screenshots, the UI
element tree, tap/swipe/type, app install/launch, logs, recording — to any MCP client, and the same
tools as nerve <tool> commands that print JSON.
Field notes
A device bench fails in ways a single emulator never shows you. Each of these is a behaviour you can read in the code:
- adb can wedge while looking alive. After a wireless device drops, the adb server can sit in a
busy-spin: every
adbcall hangs, andadb kill-serverhangs too because it talks to the same wedged socket. A watchdog treats "unresponsive and server at ≥ 80% CPU" as the wedge signature and recovers by killing the server's PID, never byadb kill-server; an unresponsive server with an idle CPU is left alone. →src/linc_nerve/core/adb_health.py - A leaked UiAutomation session silently breaks the element tree.
uiautomator dumpis killed while another process (a leaked test driver) holds the device's single UiAutomation connection. Recovery is evidence-gated and escalates in tiers under one 45 s deadline, force-stopping only a known allowlist of test drivers — the Pixel Watch companion app, whose package name looks similar, is never touched. An empty element list therefore always means an empty screen, never a failed dump. →src/linc_nerve/core/android_ui.py - Readiness checks fail toward "unknown", not "ready". Wake/lock state is parsed from
dumpsys, whose format varies by OEM and Android version; an unrecognised format reads asunknown, so a caller skips rather than tapping a locked screen. →src/linc_nerve/core/device_state.py - Screenshots handed to an agent are budgeted. Inline images for MCP agents are rescaled to
about 300k pixels (≈ 400 vision tokens); the full-resolution file on disk is left untouched for
everything else. →
src/linc_nerve/mcp/_core.py
Quickstart
Android emulator first — no physical device, Xcode or WebDriverAgent needed.
Prerequisites: Python 3.13+ (uv fetches it for you; with plain pip you need it installed),
uv, the Android SDK command-line tools, and platform-tools and
emulator on your PATH (adb and emulator; with Homebrew's android-commandlinetools add
$(brew --prefix)/share/android-commandlinetools/emulator to PATH). Then create an emulator.
On Apple silicon, replace x86_64 with arm64-v8a in the first two lines below.
avdmanager asks whether to create a custom hardware profile; answer no.
sdkmanager "platform-tools" "emulator" "system-images;android-35;google_apis;x86_64"
avdmanager create avd -n nerve -k "system-images;android-35;google_apis;x86_64"
emulator -avd nerve -no-window &
adb wait-for-device
adb wait-for-device returns before Android has finished booting. Wait until
adb shell getprop sys.boot_completed prints 1 (usually a minute or so on first boot) before
step 1, or the first state call can hit a half-booted device.
Install: pipx install --python python3.13 linc-nerve (or python3.13 -m pip install linc-nerve inside a venv),
after which the same commands run as nerve doctor, nerve discover and
nerve state --device <serial>; and for Claude Code claude mcp add nerve -- nerve bellows.
1. Check the environment. The daemon, WebDriverAgent and $LINC_HOME (default ~/.linc) are
optional, so on a fresh Android-only machine nothing fails (exit code 0); missing optional pieces
show as ! warnings with an indented hint: line. The exact set of lines depends on your machine
(macOS runs the xcode-clt check, a running daemon shows ✓). Sample from a fresh Linux machine,
trimmed:
uvx linc-nerve doctor
✓ adb: adb responsive (/usr/local/bin/adb)
✓ device-auth: no unauthorized devices
✓ scrcpy-server: …/linc_nerve/vendor/scrcpy-server-v3.3.4
! wda-project: WDA_PROJECT_DIR not set — iOS tap/swipe/elements unavailable (Android works without it)
hint: git clone https://github.com/appium/WebDriverAgent.git ~/.linc/wda/src && export WDA_PROJECT_DIR=~/.linc/wda/src
! wda-team-id: WDA_TEAM_ID not set — physical-iOS WDA signing will fail
hint: …
- xcode-clt: skipped — not macOS
! daemon: no nerve daemon on 127.0.0.1:8111 — CLI calls run in-process (the daemon is optional)
hint: …
! linc-layout: missing directories: /home/you/.linc, /home/you/.linc/nerve/recordings — nerve creates them on first use
hint: …
8 checks: 0 failed, 4 warned
2. Find the emulator.
uvx linc-nerve discover
{"devices": [{"serial": "emulator-5554", "platform": "android", "device_type": "emulator", …, "state": "online"}], "count": 1, "android": 1, "ios": 0}
With several devices attached, devices lists all of them; pass the emulator's serial to the
later commands.
3. Read the screen — foreground app, element tree and a screenshot path in one call. Your
launcher package and element count depend on the system image, and the screenshot lands in your
temp directory ($TMPDIR on macOS, not /tmp):
uvx linc-nerve state --device emulator-5554
{"device": "emulator-5554", "platform": "android", "foreground": {"package": "com.google.android.apps.nexuslauncher", …}, "element_count": 31, "elements": [ … ], "screenshot": "<temp dir>/nerve-output/…png", …}
4. Give it to your agent. For Claude Code:
claude mcp add nerve -- uvx linc-nerve bellows
Run claude mcp list and check that nerve shows as connected, then paste a first prompt:
Take a screenshot of the emulator and tell me what app is in the foreground.
Every MCP tool is also a CLI command: the tool name minus nerve_, with _ → -
(nerve_clear_app_data → nerve clear-app-data). Output is JSON on stdout; for text, put --human
before the command (nerve --human discover, not nerve discover --human). Exit 0 success, 1
tool error, 2 usage error. nerve schema --json prints the full command tree.
iOS (experimental)
iOS simulators and physical devices work through WebDriverAgent
(WDA), which you build once. nerve doctor prints the same steps as hints:
git clone https://github.com/appium/WebDriverAgent.git ~/.linc/wda/src
export WDA_PROJECT_DIR=~/.linc/wda/src
export WDA_TEAM_ID=<Apple Developer Team ID> # physical devices only; simulators don't need it
Needs macOS with Xcode. Expect rough edges: WDA always binds port 8100, first start takes ~4 s on a simulator and 15–30 s on a physical device, physical devices need code signing, and watchOS is not supported.
Visual grounding (optional, Meta SAM 3.1)
nerve_ground and nerve_tap(prompt=...) find controls that the UI tree cannot label, such as
custom canvases or unlabelled icons. They do this by sending the current screenshot to Meta's
sam-3.1 model. Grounding is off by default, and it needs three things:
pip install 'linc-nerve[grounding]' # adds meta-sam-parser
export NERVE_GROUNDING=1 # opt in: screenshots are uploaded to api.meta.ai
export META_AI_API_KEY=... # or NERVE_KEYCHAIN_SERVICE=<macOS Keychain service>
- License:
meta-sam-parseris distributed under Meta's SAM License, not Apache-2.0. It restricts some fields of use, including ITAR-controlled, military and weapons applications. Read it before you install the extra. Core nerve never imports it. - Privacy: never enable grounding on a device that shows personal data.
- Tap safety: a prompt tap fires only on one clear match, meaning confidence ≥ 0.5 and at least 0.1 ahead of the next match on a known screen size. Otherwise it taps nothing and returns the candidates.
Reference
Configuration
| Environment variable | Default | Effect |
|---|---|---|
NERVE_USAGE_LOG |
redacted |
Local usage log mode: off, redacted or full (see Trust) |
LINC_HOME |
~/.linc |
Where the usage log and recordings live; when set, the device-state database also moves to $LINC_HOME/.local/share/linc-nerve/devices.db (default ~/.local/share/linc-nerve/devices.db) |
NERVE_ACTIONLOG_ROOTS |
$LINC_HOME/nerve/actionlogs |
Colon-separated list of allowed host directory roots for nerve_actionlog_start and nerve_replay files |
WDA_PROJECT_DIR |
(none) | WebDriverAgent checkout (iOS only) |
WDA_TEAM_ID |
(none) | Apple Developer Team ID (physical iOS only) |
NERVE_HTTP_PORT |
8111 |
Port of the optional HTTP daemon: the port the daemon started by nerve bellows listens on and the port nerve doctor probes (nerve daemon takes --port instead) |
LINC_NERVE_DAEMON |
http://127.0.0.1:8111 |
Daemon URL that CLI commands call before falling back to in-process |
ANDROID_ADB_SERVER_PORT / ADB_SERVER_SOCKET |
127.0.0.1:5037 |
adb server nerve talks to (ADB_SERVER_SOCKET as tcp:<port> or tcp:<host>:<port> wins; loopback hosts only) — isolates nerve from the host's devices |
NERVE_ALLOWED_HOSTS / NERVE_ALLOWED_ORIGINS |
(none) | Extra Hosts / browser Origins the daemon accepts |
NERVE_GROUNDING |
(off) | 1 enables SAM 3.1 visual grounding (nerve_ground, nerve_tap(prompt=...), visual_grounding_hint); needs the [grounding] extra |
META_AI_API_KEY |
(none) | Meta API key for grounding (META_API_KEY also accepted) |
NERVE_KEYCHAIN_SERVICE |
(none) | macOS Keychain service to read the Meta API key from when it is not in the environment |
NERVE_OUTPUT_KEEP |
200 |
Maximum number of output files retained per process nerve-output-* temp directory (0 or invalid falls back to 200) |
NERVE_OUTPUT_MAX_AGE_S |
86400 |
Maximum age in seconds (24h default; 0 or invalid falls back to 86400) before an idle nerve-output-* directory is swept on the next process's first output |
Output files
Screenshots (nerve_screenshot, nerve_stream_screenshot, nerve_navigate_screenshot), state/diff captures (nerve_state, nerve_diff), and large nerve_logcat dumps are written to a per-process private (0700) directory <temp dir>/nerve-output-<random>/<serial>_<NNNN>_<tool>.<ext> (under $TMPDIR on macOS, /tmp on Linux), created lazily on first output and kept on process exit so callers can read returned paths after a CLI invocation finishes:
- Retention cap: Each process directory keeps at most
NERVE_OUTPUT_KEEP(default200)<serial>_<NNNN>_<tool>.<ext>files, pruning the oldest (by counter, then mtime) before writing a new one. - Owner lock: Each process holds an exclusive
flockon<dir>/.nerve-output.lockfor its lifetime (the OS drops it when the process exits). A directory whose lock is held — or whose lock state cannot be read — is never removed by the sweep or bynerve cleanup, however long its process (an idle daemon or MCP server) has gone without writing. If a process's directory is deleted anyway, nerve creates a fresh one on the next output. - Stale sweep: On the first output directory creation in a process, nerve sweeps
<temp dir>/nerve-output-*directories owned by the current UID (never following symlinks) that no live process holds and whose newest entry is older thanNERVE_OUTPUT_MAX_AGE_Sseconds (default86400). SetNERVE_OUTPUT_SWEEP=0to disable it (it is also off under pytest unlessNERVE_OUTPUT_SWEEP=1). - On-demand cleanup:
nerve cleanupremoves all current-UID, non-symlinknerve-output-*directories in the temp root except those held by a running nerve process and those modified in the last 60 seconds (nerve cleanup --allremoves the recently modified ones too, never a live process's), printing JSON{"removed": [...], "skipped": [...], "bytes_freed": N}(or text withnerve --human cleanup).
HTTP daemon (optional)
nerve daemon (or nerve bellows, which also serves MCP over stdio) runs an HTTP server on
127.0.0.1:8111: GET /health, GET /devices, POST /tools/<tool_name> with a JSON body, and
GET /stream?device=<serial> for a server-sent-events log stream. CLI commands use the daemon when
one is running and otherwise run the tool in-process. A few stateful tools (recording, streaming,
reservations, diff, session-stats) need the daemon, and say so instead of answering wrongly.
MCP Tools (49)
Tools are registered via @device_tool (requires a device serial) or @global_tool (no device needed) in src/linc_nerve/mcp/*_tools.py. This section — including the count — is generated from those registrations by python -m linc_nerve.docs_gen; tests/test_docs_sync.py fails CI when it is stale. Call nerve_capabilities for the per-platform support matrix.
Discovery & Capabilities
| Tool | Type | Description |
|---|---|---|
nerve_capabilities |
global | Per-platform support matrix for nerve's capability groups |
nerve_discover |
global | List all connected devices (Android + iOS) |
nerve_pool |
global | Show device pool status — who has what reserved |
Screenshots & Streaming
| Tool | Type | Description |
|---|---|---|
nerve_screenshot |
device | Capture one screenshot — a stateless PNG of the current device display |
nerve_stream_screenshot |
device | Pull the current frame from an active screen-mirror streaming session |
nerve_stream_start |
device | Open a live screen-mirror session for warming up fast screenshots |
nerve_stream_status |
global | Report status and health of active screen-mirror streaming sessions |
nerve_stream_stop |
device | Tear down the live mirror session opened by nerve_stream_start |
UI Inspection
| Tool | Type | Description |
|---|---|---|
nerve_diff |
device | Return UI changes since the last nerve_state snapshot on this device |
nerve_elements |
device | Return the UI element tree only (clickable + text widgets) — no image bytes |
nerve_ground |
device | Locate UI controls visually by natural-language concept prompt using Meta SAM 3.1 |
nerve_state |
device | Capture full device state in one call (screenshot + UI elements + foreground) |
Navigation
| Tool | Type | Description |
|---|---|---|
nerve_navigate |
device | Navigate to a named screen of a REGISTERED app (route registry) by its deep link |
nerve_navigate_screenshot |
device | Navigate to a screen and capture a screenshot after the UI settles |
Input
| Tool | Type | Description |
|---|---|---|
nerve_density |
device | Read display density — dpi and the dp-to-px multiplier — for a device |
nerve_key |
device | Press a hardware/system key |
nerve_long_press |
device | Long press at screen coordinates |
nerve_swipe |
device | Two-point gesture from one xy coordinate to another — swipe, drag, or scroll |
nerve_tap |
device | Tap a single point on the device display at known x/y coordinates or by visual prompt |
nerve_type |
device | Type text into the currently focused input field via the soft keyboard |
App Management
| Tool | Type | Description |
|---|---|---|
nerve_apps |
device | List installed apps on the device |
nerve_clear_app_data |
device | Wipe an app's data + cache → first-install state |
nerve_grant_permission |
device | Grant a runtime permission to an app (Android pm grant) — no dialog |
nerve_install |
device | Install an app on the device |
nerve_kill |
device | Force-stop / terminate an app |
nerve_launch |
device | Launch an app by package/bundle ID, optionally opening a deep link URI |
nerve_uninstall |
device | Uninstall an app from the device |
Emulator / Simulator
| Tool | Type | Description |
|---|---|---|
nerve_emulator_list |
global | List available Android emulators (AVDs) and iOS Simulators, and their running state |
nerve_emulator_start |
global | Start an Android emulator (by AVD name) or iOS Simulator (by UDID/Name) |
nerve_emulator_stop |
device | Stop a running Android emulator or iOS Simulator |
nerve_inject_sensor |
device | Inject sensor data into an Android emulator via its telnet console |
Recording
| Tool | Type | Description |
|---|---|---|
nerve_extract_frames |
global | Extract PNG frames at given timestamps from a host-side MP4 recording |
nerve_record_fixed |
device | Record a fixed-length screen video — self-terminating MP4 capture |
nerve_record_start |
device | Begin recording video to disk — open-ended MP4 capture on the device |
nerve_record_stop |
device | Finalise the MP4 file and end the durable recording session |
Action Log
| Tool | Type | Description |
|---|---|---|
nerve_actionlog_start |
device | Start an action log — a JSONL record of every nerve tool call on a device |
nerve_actionlog_stop |
device | Stop the action log on a device and report the file and entry count |
nerve_replay |
device | Replay an action log on a device and report whether its steps ran |
Device Readiness
| Tool | Type | Description |
|---|---|---|
nerve_ensure_ready |
device | Ensure a device is awake + unlocked before UI interaction, and report readiness |
nerve_network |
device | Report whether a device is online — default network transport + validated internet |
Diagnostics & Observability
| Tool | Type | Description |
|---|---|---|
nerve_inspect |
device | Non-invasive post-mortem snapshot of a process — pid, RSS, crash signature |
nerve_logcat |
device | Tail the last N lines from a device's logcat buffer or iOS system log |
nerve_metrics |
global | Performance metrics for nerve commands |
nerve_session_stats |
global | Get state tracking statistics for all devices |
nerve_stream_logs |
device | Get the SSE subscription URL for continuous real-time log streaming |
nerve_usage_stats |
global | Usage analytics over the shared MCP call log (~/.linc/mcp-calls.jsonl) |
Reservation
| Tool | Type | Description |
|---|---|---|
nerve_release |
device | Release a device reservation |
nerve_reserve |
device | Reserve a device exclusively for this session |
Other
| Tool | Type | Description |
|---|---|---|
nerve_device_state |
device | Control Android device power/idle/standby state for adversarial testing |
Trust
- No telemetry, no phone-home. nerve talks to your devices, your local adb server, and — for iOS — the WebDriverAgent it starts. Nothing else.
- A local usage log, under your control. Each MCP tool call is appended to
$LINC_HOME/mcp-calls.jsonl(default~/.linc/mcp-calls.jsonl, rotated at 10 MB) with the tool name, timing, success and parameters. SetNERVE_USAGE_LOG=off|redacted|full:redacted(default) — values of sensitive parameters (text,password,passcode,pin,secret,token,otp) and every value underextrasanduriare replaced by their length only (no hash), including inside nested dicts and lists; binary values become their size, and long strings are truncated. The log file is created owner-only (0600).off— nothing is written.full— raw parameter values, including typed text (exceptnerve_typetext sent withsecret=true, which is length-only in every mode). Opt in only on a machine you trust.
- The daemon is loopback-only. It binds
127.0.0.1, rejects non-loopback Hosts (DNS rebinding) and any browser Origin, and accepts tool calls only asapplication/json. Every value that reaches a device shell is validated or shell-quoted where it is used. Details and how to report a vulnerability: SECURITY.md.
Related projects
| Package | Role |
|---|---|
linc-crucible |
Quality gates, build-and-deploy routing, and visual/a11y baselines (delegates device I/O to nerve) |
linc-spectra |
Runtime debugger (Android JDWP via kotlin-debug-adapter or zero-config jdb; iOS Simulator lldb-dap) |
mobile-agent-bench |
Pre-registered 600-cell benchmark comparing nerve + crucible + spectra against Maestro, mobile-mcp, and agent-device (lincforge.com) |
How this repo works
This is a release mirror of LINC's private repository. The code is built by LINC's AI software factory under human review; each release lands as one commit. Issues are welcome; pull requests by arrangement — see CONTRIBUTING.md.
Built by LINC Innovations — we diagnose flaky device test suites.
Licensed under the Apache License 2.0. Bundles scrcpy-server (Apache-2.0) — see NOTICE.
nerve MCP questions
What tools does nerve MCP provide?
It exposes 49 tools, including nerve_capabilities, nerve_discover, nerve_pool, nerve_screenshot, nerve_stream_screenshot.
How does nerve handle large screenshots for MCP agents?
To manage token usage, inline images for MCP agents are rescaled to approximately 300k pixels, while the full-resolution file is preserved on disk.