Self Portrait with a Beret, 1886 by Claude Monet. Source: Wikimedia Commons
Monet is an Emacs package that implements the (undocumented) Claude Code IDE protocol, enabling Claude to interact with your Emacs environment through a WebSocket connection.
You can use Monet with Claude Code running in your favorite terminal emulator (Ghostty, Kitty, iTerm2, WezTerm), or with packages like claude-code.el that run Claude Code directly inside Emacs.
(use-package monet :vc (:url "https://github.com/stevemolitor/monet" :rev :newest))
(straight-use-package '(monet :type git :host github :repo "stevemolitor/monet"))
Clone this repository:
git clone https://github.com/stevemolitor/monet.git
Add to your Emacs configuration:
(add-to-list 'load-path "/path/to/monet") (require 'monet)
Enable Monet mode:
Start a Monet server:
C-c m s ; Start server in current project/directory
In Claude Code, start a new chat and use the /ide slash command to connect to your Emacs session.
To have Claude automatically connect to your Monet session set ENABLE_IDE_IDE=t
before starting Claude.
If you have multiple Monet sessions for the same project you can do this to have Claude automatically connect to the desired instance:
ENABLE_IDE_INTEGRATION=t && CLAUDE_CODE_SSE_PORT=123456 && claude
Monet prints a message with the port number when you call monet-start-server
(C-c m s
). You can see the list of all running servers with their ports and directories via monet-list-sessions
(C-c m l
).
You can use Monet with claude-code.el by adding this hook:
(add-hook 'claude-code-process-environment-functions #'monet-start-server-function)
When claude-code.el starts a new session it will start and associate a Monet session with the current claude-code.el instance.
Sessions are automatically cleaned up (killed) when you exit the associated Claude session. When you exit Emacs all sessions are cleaned up. You can stop a session manually via monet-stop-server
(C-c q
).
Here's Monet in action - Claude running in Ghostty terminal communicating with Emacs:
When monet-mode
is enabled, the following key bindings are available (default prefix: C-c m
):
C-c m s
- Start serverC-c m q
- Stop server (with completion)C-c m Q
- Stop all serversC-c m l
- List active sessionsC-c m L
- Enable loggingC-c m D
- Disable loggingWhen Claude proposes code changes, Monet displays them in a diff view:
Simple Diff Tool (default): A read-only diff view showing the proposed changes
y
to accept Claude's changes exactly as shownq
to reject the changesEdiff Tool: An interactive diff view that allows you to edit the changes before accepting
n
(next) and p
(previous)C-c C-c
to accept your edited version (your changes will be sent to Claude)q
to reject all changesImportant: With the ediff tool, any manual edits you make to the proposed changes are captured and sent to Claude when you accept. This allows you to refine Claude's suggestions before applying them.
Monet automatically creates session keys based on your context:
project.el
), uses the project nameproject<2>
)With a prefix argument (C-u C-c m s
), you can manually select a directory.
You can start multiple sessions per project, or have multiple
;; Change the prefix key (default: "C-c m") (setq monet-prefix-key "C-c C-m") ;; Or disable prefix key and use M-x commands only (setq monet-prefix-key nil) ;; Change log buffer name (setq monet-log-buffer-name "*My Monet Log*") ;; Customize diff keybindings (setq monet-ediff-accept-key "C-c C-a") ; Default: "C-c C-c" (setq monet-ediff-quit-key "C-g") ; Default: "q" (setq monet-simple-diff-accept-key "C-c C-c") ; Default: "y" (setq monet-simple-diff-quit-key "C-g") ; Default: "q" ;; Change ediff window split direction (setq monet-ediff-split-window-direction 'vertical) ; Default: 'horizontal
Most MCP tools that Claude uses to interact with Emacs are now customizable. You can replace the default implementations with your own functions:
;; Custom file opener that confirms before opening (defun my-open-file-tool (uri) (when (y-or-n-p (format "Open %s? " uri)) (monet-default-open-file-tool uri))) (setq monet-open-file-tool 'my-open-file-tool) ;; Custom diagnostics that only reports errors (defun my-diagnostics-tool (&optional uri) (let ((result (monet-flymake-flycheck-diagnostics-tool uri))) ;; Filter to only errors... result)) (setq monet-diagnostics-tool 'my-diagnostics-tool)
Available customizable tools:
monet-get-current-selection-tool
- Get current text selectionmonet-get-latest-selection-tool
- Get latest selection from any filemonet-open-file-tool
- Open files in the editormonet-save-document-tool
- Save documents to diskmonet-check-document-dirty-tool
- Check for unsaved changesmonet-get-open-editors-tool
- List open filesmonet-get-workspace-folders-tool
- List project directoriesmonet-diagnostics-tool
- Get diagnostics (defaults to Flymake/Flycheck)Important: to customize the diff tool to use ediff, you must set both the diff tool and the diff cleanup tool:
(setq monet-diff-tool #'monet-ediff-tool) (setq monet-diff-cleanup-tool #'monet-ediff-cleanup-tool)
You can customize how Monet displays diffs by providing your own diff tool functions:
;; Use a custom diff tool (setq monet-diff-tool 'my-diff-tool) (setq monet-diff-cleanup-tool 'my-diff-cleanup)
The diff tool function should take: (old-file-path new-file-path new-file-contents on-accept on-quit)
and return a context object. The cleanup function takes that context object for cleanup.
Monet creates a WebSocket server that Claude Code connects to via MCP. This allows Claude to:
Each session is isolated to a specific directory/project, ensuring Claude only accesses files within the intended scope.
C-c m l
to list all running serversC-c m L
to see all MCP communicationRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4