Releases: L-Jovi/keyhole
Release list
Keyhole 0.5.0 — native Windows and an isolated server
Keyhole 0.5.0 adds native Windows 11 support and hardens how the server starts on every platform.
- Windows 11. A native NTFS backend walks paths through held parent directory handles and refuses
junctions, symbolic links and hard-linked files. Private state uses protected ACLs, grant changes and
writes share a cross-process lock, and text edits stay hash-checked and recoverable. Install with x64
Python on both x64 and ARM PCs; see the
Windows guide. - Security, all platforms. The MCP server now starts with
python -I -X utf8from the private state
directory. Before, a server started afterkeyholeran inside anrwfolder could import a module such
asjson.pycreated in that folder through ChatGPT, instead of the standard library. Upgrade if you
share folders read-write. - First use. The README and demonstration use the setup wizard's sample (
demo,~/KeyholeDemo), so
their commands work unchanged after first-time setup.
The MCP tool definitions are unchanged; an existing ChatGPT app needs no Refresh.
Validation
- CI: macOS 15 and Ubuntu 22.04/24.04 with Python 3.11–3.14; Windows Server 2025 and hosted Windows 11 ARM
with x64 Python 3.11–3.14 as a standard user, including real MCP SDK handshakes with the new server command. - Before uploading, the release workflow installs this exact wheel on Windows Server 2025 and Windows 11 ARM
with the command from the Windows guide. - Real ChatGPT on Windows: read, read-only refusal, edit, restore and a refused read after close, on hosted
Windows 11 ARM with x64 Python (pre-release commit91609da). - Real ChatGPT on macOS after the isolation change: a tool call reached the 0.5.0 server; the running server
used-I -X utf8and the state directory as its working directory.
Limits and upgrades
- Windows scope: Windows 11 and local NTFS folders. Native ARM Python, Windows 10, network shares, cloud
placeholders and case-sensitive folders are outside the tested scope. No physical consumer PC has been
tested. - Upgrade: close the folders you share, run
uv tool upgrade keyhole-mcp, then resume only the folders you
intend to reopen. From 0.3.1, first runuv tool uninstall keyhole, thenuv tool install keyhole-mcp. - The wheel, source archive and their SHA-256 sums are attached below; PyPI publishes the same bytes.
Full list of changes: CHANGELOG.
Keyhole 0.4.0 — guided setup and Linux support
Keyhole 0.4.0 makes the first-run setup resumable: install the verified official tunnel client, save the connection settings, and open an optional read-only example. status --human explains the next step; status --redact produces a bounded diagnostic report.
uv tool install keyhole-mcp
keyhole setupThe package is keyhole-mcp; the command remains keyhole. Follow the first-use guide for uv, PATH, ChatGPT Developer mode, and OpenAI Platform access. Installing the package alone does not create account permissions or a private ChatGPT app. The attached wheel is an alternative to PyPI.
- Official client downloads use fixed versions and SHA-256 checks. Existing externally managed clients remain externally managed.
- Ubuntu x86_64 support: a real Ubuntu 24.04 Tunnel → ChatGPT session passed read, read-only rejection, edit, restore, and a new failed read after close. Ubuntu 22.04 has automated coverage.
- A 59-second demonstration uses fictional notes and shows the actual workflow.
- The MCP tool definitions are unchanged. Existing private ChatGPT apps do not need Refresh. Read-only defaults, local grant control, hash checks, and recovery boundaries are unchanged.
Validation
All 21 CI jobs passed on release preparation, including macOS/Ubuntu 22.04/Ubuntu 24.04 with Python 3.11–3.14, wheel and sdist installation, official client downloads, and the Linux evaluation container. The protected publishing workflow builds once and checks its artifacts on macOS and both Ubuntu versions before publication. PyPI and the GitHub attachments use the same distribution bytes; checksums are attached.
Limits and upgrades
Windows is not supported by this release. Its CI checks the refusal path and separate feasibility probes. Intel Macs, older macOS, Linux ARM, other distributions, and fresh OpenAI-account onboarding remain untested. Document parsers retain the user's OS permissions; process separation is not an OS sandbox.
Close sharing before upgrading and resume only intended folders afterwards. Users of the old keyhole distribution (0.3.1) must uninstall that tool entry before installing keyhole-mcp; this preserves saved keys, grants, and recovery history. Follow the maintenance guide.
v0.3.2 — safer recovery and clearer setup
The MCP tool definitions are unchanged; existing ChatGPT apps need no Refresh.
This release fixes failure paths around permissions and recovery, and provides one first-use guide with real ChatGPT screenshots.
- Read-only downgrades revoke old write access before runtime checks, including after a tunnel-client version change.
- A full recovery history no longer prevents repair. Interrupted restores retry in place with the original request id, and successful recovery returns to the normal retention limits.
- Case and Unicode aliases cannot bypass state-directory protection or pending-operation guards. Parser cleanup is scoped to its owning state directory.
- Source archives contain their test resources. CI tests installed wheels with freshly resolved dependencies and the unpacked source archive.
- Parser documentation states the actual limits: process/resource controls do not constitute an OS sandbox.
Install
On a Mac with uv available:
uv tool install https://github.com/L-Jovi/keyhole/releases/download/v0.3.2/keyhole_mcp-0.3.2-py3-none-any.whlFirst-time users should follow the complete setup guide, including account permissions, the official tunnel client and their own private ChatGPT app.
The distribution is now keyhole-mcp; the CLI and Python module remain keyhole. Do not use pip install keyhole: that name belongs to an unrelated project. Keyhole is not published to PyPI.
Upgrade from 0.3.1
Close the folders you are sharing and confirm shutdown, then run:
uv tool uninstall keyhole
uv tool install https://github.com/L-Jovi/keyhole/releases/download/v0.3.2/keyhole_mcp-0.3.2-py3-none-any.whlRemoving the package preserves grants, keys and recovery history. Keep your actual state directory on every Keyhole command, especially if it differs from ~/.config/keyhole. Resume only the folders you intend to reopen. See maintenance.
Verification and limits
All seven PR CI jobs passed: macOS Python 3.11–3.14, experimental Linux unit tests, installed wheel/source archive tests, and the Windows unsupported-platform CLI check. Local tests passed 69 tests and 19 subtests. Real ChatGPT calls verified text and DOCX reads, read-only write rejection, an authorized edit, restore, and denied access after closing the last folder.
This does not add Windows runtime support or an OS sandbox for document parsers. Intel Macs, older macOS, other ChatGPT plans and fresh-account onboarding remain untested. SHA-256 checksums for both release artifacts are attached.
Keyhole 0.3.1
The MCP tool definitions are unchanged; an existing ChatGPT app needs no Refresh.
Added
- On Windows, every
keyholecommand prints oneunsupported_platformerror instead of a Python
traceback.keyhole setupon Linux says that only the unit tests run there. - Each release ships a wheel; installing from it needs no Git or Xcode command line tools.
Fixed
keyhole setupnow checks the tunnel id format the waytunnel-clientdoes (tunnel_plus 32
lowercase letters or digits), so a typo is caught at setup instead of at the firstopen.keyhole openon a directory that does not exist reportednot_configuredinstead of
path_missing, because the state-directory check also caught errors raised while the state
directory was open. Found by the experimental Linux CI job.
Changed
- Python 3.14 is tested in CI;
uv tool installpicks it on a machine without Python. - The install commands use the release wheel instead of a Git URL, which failed on Macs without Xcode
command line tools. tmuxis not mentioned bykeyholeany more: the tunnel runs in a detached process without it, and that
path was verified end to end (including after closing the terminal).keyhole statusno longer lists it.- Docs: a requirements table states exactly what was verified (macOS 15.6 on Apple silicon, Python
3.11–3.14,tunnel-client0.0.14, a Pro account in Chat mode) and what was not (Intel Macs, older macOS,
Linux end to end, other ChatGPT plans,tunnel-client0.0.15); the no-Homebrew install path is spelled
out and was verified on a machine with nothing installed.
Install
brew install uv openai/tools/tunnel-client
uv tool install https://github.com/L-Jovi/keyhole/releases/download/v0.3.1/keyhole-0.3.1-py3-none-any.whlUpgrading from 0.3.0: uv tool install --reinstall https://github.com/L-Jovi/keyhole/releases/download/v0.3.1/keyhole-0.3.1-py3-none-any.whl.
Verification
- 56 tests and ruff; CI on macOS with Python 3.11-3.14 (and the Linux unit tests); the wheel is built and run in CI.
- Real ChatGPT (web, Chat mode) through tunnel-client 0.0.14 with
tmuxhidden fromPATH: the tunnel ran as a
detached process, kept serving after the launching terminal was closed, andkeyhole close --allleft no
process behind. - Install from this wheel on a simulated Mac without Xcode command line tools (failing
gitandpython3
stubs, empty home): uv downloaded Python andkeyholeran. The previous Git-URL install fails there. - A simulated Windows interpreter gets one
unsupported_platformerror for every command. - Not verified: Intel Macs, macOS older than 15.6, tunnel-client 0.0.15, ChatGPT plans other than Pro.
Keyhole 0.3.0
Tool definitions are unchanged from 0.2.0: an existing ChatGPT app needs no Refresh.
First public release, renamed from the private project "Local Evidence Bridge" (CLI leb). The MCP tool
definitions are unchanged from 0.2.0; an existing app does not need a refresh.
Added
--recovery on|offper folder:offkeeps paths and hashes only instead of the previous file contents.keyhole setup --accept-client-versionandkeyhole setup --rotate-key.keyhole statusreports whether setup was done, the installed and acceptedtunnel-clientversions, and
whethertmuxis present.- Documentation: setup guide, reference, design notes, security policy.
Changed
- Packaging:
src/layout,keyholeconsole script,python -m keyhole.server; install with
uv tool install. The custom symlink installer and launcher are gone. Python 3.11 to 3.13. - Recovery history no longer refuses writes when full: the oldest completed records are evicted;
interrupted operations are never evicted. tunnel-clientversion policy: the version accepted at setup is recorded; a different installed version
blocks new starts until accepted, and never blocksclose.- Error codes for first-day problems are specific and actionable (
not_configured,symlink_in_path,
client_version_changed,native_client_missing,permission_denied). .claudejoined the built-in exclusions; a project-specific name left the list.- Setup is
keyhole setupinstead of a separate script.
Fixed
- Custom
--excludepatterns could be bypassed by reading a path directly or by changing letter case; they
now hide the whole subtree and match after case folding and Unicode normalization. - A folder could be opened through an alias spelling such as
/System/Volumes/Data/Users/…, which also let
a read-write grant reach protected paths. Roots are now stored canonically and protected paths are checked
by device and inode. - The first
keyhole openon a fresh machine failed because the runtime alias did not exist yet.
Verification
- 53 unit tests and ruff on macOS 15 (Apple silicon), Python 3.11; CI on Python 3.11-3.13.
- End-to-end acceptance on 2026-09-26 through ChatGPT on the web (Chat mode, Pro account) with the official tunnel-client 0.0.14: custom exclusions held against direct reads, case variants and Unicode variants; text search returned nothing from hidden folders; a hash-checked
apply_text_patchwas applied, read back and restored to the original hash; a write into a hidden folder was refused; afterkeyhole close --allthe next call failed withtunnel_client_not_connected. - Not yet verified: tunnel-client 0.0.15 and a from-scratch install on a fresh macOS user account.