# Keyhole — local files for ChatGPT Let ChatGPT read, and carefully edit, only the local folders you choose. No shell, no public port. **Example: turn a note on your computer into a TODO list, without uploading the file by hand.** **1. In your terminal, allow the sample folder to be edited.** [One-time setup](#start-here) creates `~/KeyholeDemo` with a fictional `notes.md` and shares it read-only as `demo`. Editing needs an explicit local command: ```sh keyhole access demo rw ``` **2. In ChatGPT, select your Keyhole app and ask:** > Read `notes.md` in `demo`, turn its three ideas into TODO checkboxes, and save the file. This is the real response from a session with the same fictional note, shared there as `KeyholeDemo`:  **3. Back in your terminal, inspect the same file.** ```sh cat ~/KeyholeDemo/notes.md ``` Its three ideas now contain checkboxes. These lines were checked on disk after the edit: ```markdown - [ ] Read the field guide on Saturday. - [ ] Summarize the chapter about night skies. - [ ] Pack a notebook for Sunday's walk. ``` You can ask ChatGPT to restore the returned change id. When finished, run `keyhole close demo` to stop sharing the folder. [See the complete read → edit → restore → close example, with real screenshots](docs/demo.md). [](https://github.com/L-Jovi/keyhole/actions/workflows/ci.yml) [](https://pypi.org/project/keyhole-mcp/) [](https://github.com/L-Jovi/keyhole/blob/main/LICENSE) Keyhole is a small [MCP](https://modelcontextprotocol.io) server that runs on your Mac, Linux or Windows computer, plus a command-line tool, `keyhole`. You open a folder with `keyhole open`; ChatGPT on the web can then read it through OpenAI's official [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Give a folder `rw`, and ChatGPT can also create and edit text files in it. Every edit is checked against the file's current hash and recorded before it is applied. Individual file replacements are atomic; retained changes can be restored without overwriting later edits. Unofficial project; not affiliated with OpenAI. ## What you get - **Read-only by default.** ChatGPT sees a folder only after you open it, and cannot change a file until you say `--access rw`. Nothing ChatGPT does can widen its own access: grants are managed by the local CLI only. - **Careful edits you can undo.** Writes require the file's current SHA-256; updates based on a stale hash are refused. The previous content is kept in a private local history, and `restore_change` rolls it back. - **Several folders, useful file formats.** Open folders independently with their own ro/rw permissions. Text, PDF, Word, PowerPoint, Excel and images come back with hashes and ranges, so answers can cite what was read. Document parsers have CPU, time and input-size limits, but run with your OS permissions; they are not an OS sandbox. The connection uses OpenAI's official client. It exposes no public endpoint and no remote shell. Close the last folder and the tunnel stops. [Compare related projects](https://github.com/L-Jovi/keyhole/blob/main/docs/alternatives.md). ## Start here **[Follow the complete setup guide →](docs/setup.md)** ```sh uv tool install keyhole-mcp keyhole setup ``` The setup wizard can download the verified official client, resume incomplete configuration and open a read-only example. If PyPI is unavailable, use the exact wheel URL from [GitHub Releases](https://github.com/L-Jovi/keyhole/releases). **On Windows, follow the [PowerShell guide](docs/windows.md) instead.** Its install command requests the x64 Python that Keyhole's dependencies need, on both x64 and ARM PCs. That is the complete first-time path: check your account access, install the tools, connect your own tunnel, create a private ChatGPT app, and read a real demo file. Follow it once, from top to bottom. No Python, Git, Node, Docker or tmux installation is required. You need macOS, Ubuntu Linux or Windows 11, ChatGPT Developer mode and permission to create an OpenAI Platform tunnel and restricted runtime key. Budget about 15 minutes after account access is ready. The GitHub repository supplies the software. **You create your own tunnel and private ChatGPT app**; there is no public Keyhole app to add in one click. OpenAI's Secure MCP Tunnel is for private connections, not public plugin-store distribution. ### What makes it useful Open several folders independently, keep some read-only, and allow recoverable text edits in others. Read documents as well as source code, then close a folder when the task is finished. Folder access always stays under your local control. ### Compatibility | Surface | Verified / limitation | | --- | --- | | macOS | Apple silicon, macOS 15.6 and 15.7.7. Intel and older macOS remain untested. | | Python | 3.11–3.14 in CI; `uv` supplies Python automatically. | | Linux | Supported on Ubuntu x86_64. Real ChatGPT read/edit/restore/close verified on Ubuntu 24.04; Ubuntu 22.04/24.04 have Python 3.11–3.14 CI and artifact coverage. Other distributions and Linux ARM are untested. [Evidence and limits](https://github.com/L-Jovi/keyhole/blob/main/docs/platforms.md). | | Windows | Windows 11 with x64 Python and local NTFS folders, from 0.5.0. Real ChatGPT read/edit/restore/close verified on a hosted Windows 11 ARM machine; Windows Server 2025 x64 has automated coverage. No physical consumer PC has been tested. [Setup guide](docs/windows.md), [evidence and limits](docs/platforms.md#windows-native-support). | | OpenAI client | `tunnel-client` 0.0.14. Newer versions require explicit acceptance at setup. | | ChatGPT | Pro, web, Chat mode. Other eligible plans and fresh-account onboarding have not been tested here. | | Clean install | Release wheel tested with Git/Python developer-tool commands unavailable in a simulated environment; not a freshly erased Mac. | ## How it works ```mermaid flowchart LR C[ChatGPT web] -->|tool call| T[OpenAI tunnel endpoint] T <-->|outbound long-poll only| TC[tunnel-client on your computer] TC -->|stdio JSON-RPC| K[keyhole MCP server] K -->|opened folders only| F[(Your files)] CLI[keyhole CLI] -.->|grants, ro / rw| K ``` `tunnel-client` is OpenAI's open-source client. It opens an outbound connection and forwards each request to the Keyhole server over stdio; no port on your computer is exposed. The server reads and writes only inside folders you opened, and refuses anything else. ## Daily use ```sh keyhole open ~/Documents/notes # read-only keyhole open ~/code/app --access rw --name app # editable, shown to ChatGPT as "app" keyhole open ~/code/app --exclude Private --exclude 'Secret/*' keyhole access app ro # back to read-only keyhole status # configuration, checks, runtime state keyhole close --all # stop sharing; the tunnel stops too keyhole resume notes # after a reboot, resume only an intended folder keyhole history --limit 20 # recent recoverable changes ``` Nothing is shared after a reboot until you run `keyhole resume`. Closing or forgetting a folder never touches its files. Example requests in ChatGPT: > Read `app/src/config.py`, fix the typo in the error message, and read the file back to confirm. > Search `notes` for "invoice", then quote the matching lines with their file paths. For an edit, ChatGPT reads the file and its hash, proposes the change, and calls `apply_text_patch` or `write_file`. Whether ChatGPT asks you before a write is ChatGPT's own setting for the app (it asks by default and can remember your answer for a conversation); check the app's details if you never see a prompt. ## What ChatGPT can do with each file type | File type | Read | Create, replace, patch | Copy, move, rename, delete, restore | | --- | --- | --- | --- | | UTF-8 text: code, Markdown, JSON, YAML, TOML, shell, HTML, CSS, plain text, any other extension not listed below | by line range | yes (`rw`) | yes (`rw`) | | UTF-16 / UTF-32 text with a BOM | by line range | no, convert to UTF-8 first | yes (`rw`) | | PDF | text per page, one page as an image; no OCR | no | yes (`rw`) | | Word `.docx` | body paragraphs and tables | no | yes (`rw`) | | PowerPoint `.pptx` | slide and table text | no | yes (`rw`) | | Excel `.xlsx` | cells, formulas and cached values; no recalculation | no | yes (`rw`) | | PNG, JPEG, WebP | the image, downscaled if large | no | yes (`rw`) | | Archives, executables, databases, media, legacy Office (`.doc`, `.xls`, `.ppt`) | metadata only | no | yes (`rw`) | Copy, move, delete and restore treat every regular file up to 8 MiB as opaque bytes, so they work for binaries too. Keyhole cannot write Office documents, PDFs or images, and does not run code, macros or formulas. Limits: text files up to 8 MiB; documents and images up to 64 MiB; 400 lines or 64 KiB per read; 1 MiB per `write_file`; single files only, no recursive directory operations. Every response says when it was truncated. ## Recovery history Every change ChatGPT makes is written to `~/.config/keyhole/changes.sqlite3` (readable by you only) before the file is touched: the paths, hashes and, by default, the previous content. That is what `restore_change` and `keyhole history` use. ChatGPT can see paths, hashes and change ids, never the stored content. - History is bounded to 1000 records or 450 MiB. When it is full, the oldest completed records are dropped automatically; an interrupted operation is never dropped. Recovery can temporarily reserve one extra record and 48 MiB so a full history does not prevent repair. Retry an interrupted restore with the same request id; successful recovery returns history to the normal limits. - Closing or forgetting a folder keeps its history. `keyhole purge-history --before 2026-01-01 --confirm` deletes completed records before a date. Eviction or purge removes both recovery and replay protection for those records; history is not a permanent audit log. - Prefer your own version control? `keyhole open