Deep integration of Sourcegraph Amp with Emacs, inspired by amp.nvim.
amp-emacs is fully functional! All core features have been implemented and tested with Amp CLI v0.0.1763121689.
This implementation uses WebSocket communication (matching amp.nvim) and follows the IDE integration protocol spec.
- ✅ Bidirectional communication with
amp --idevia WebSocket - ✅ Port-based connection with authentication token (auto-finds port 9000-9999)
- ✅ File tracking - Amp knows what files you're viewing
- ✅ Selection notifications - Amp sees selected code
- ✅ User messages - Send messages directly to Amp
- ✅ File reading - Amp can read files from your workspace
- ✅ File editing - Amp can edit files directly in your Emacs buffers (with automatic backups)
- ✅ Region commands - Fix, explain, and improve code selections
- ✅ Path traversal protection - Validates all file paths, prevents access outside workspace
- ✅ Sensitive directory blocking - Blocks access to
.git,.ssh,.gnupgdirectories - ✅ Cryptographically secure tokens - Uses
/dev/urandomon Unix for 256-bit tokens - ✅ Atomic file writes - Uses temporary files + rename to prevent corruption
- ✅ Automatic backups - Creates timestamped backups before editing files
- ✅ Content validation - Checks file size limits (default 10MB), null bytes, UTF-8 encoding
- ✅ Sanitized logging - Removes sensitive data from logs (tokens, passwords, etc.)
- ✅ Symlink protection - Prevents editing symbolic links
- ✅ Rate limiting - DoS protection (configurable requests/second per client)
- ✅ Client connection limits - Configurable maximum concurrent connections
- ✅ Message size limits - Validates WebSocket message sizes (default 15MB)
- ✅ Rollback on error - Restores buffer state if edit fails
- ✅ Read-only buffer respect - Won't edit buffers marked as read-only
⚠️ Diagnostics API - Implemented but returns empty (needs flycheck/flymake integration)
# Install Amp CLI
npm install -g @sourcegraph/amp
# Verify
amp --version- Add to
~/.config/doom/packages.el:
(package! websocket)
;; Option A: Install from GitHub (recommended)
(package! amp
:recipe (:host github :repo "alvarmaciel/amp-emacs"))
;; Option B: Install from local clone
;; (package! amp
;; :recipe (:local-repo "local-packages/amp-emacs"))- If using local clone (Option B), clone the repository:
mkdir -p ~/.config/doom/local-packages
cd ~/.config/doom/local-packages
git clone https://github.com/alvarmaciel/amp-emacs.git- Configure in
~/.config/doom/config.el:
(use-package! amp
:after websocket
:config
(setq amp-auto-start t)
(setq amp-server-log-level 'info))- Sync and restart:
doom sync- Install websocket package:
M-x package-install RET websocket RET- Clone and configure:
git clone https://github.com/yourusername/amp-emacs.git ~/.emacs.d/lisp/amp-emacsAdd to your init.el:
(add-to-list 'load-path "~/.emacs.d/lisp/amp-emacs")
(require 'websocket)
(require 'amp)
(setq amp-auto-start t)- Restart Emacs
cd amp-emacs
emacs -Q --eval "(progn (require 'package) (add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\")) (package-initialize) (unless (package-installed-p 'websocket) (package-refresh-contents) (package-install 'websocket)) (add-to-list 'load-path \"$(pwd)\") (load \"amp\") (amp-start))"-
Open a file in your project:
C-x C-f /path/to/your/project/file.txtThis establishes the project context for Amp.
-
Start Amp server in Emacs:
M-x amp-startYou'll see:
Amp server started on port 9000. Run 'amp --ide' in your project. -
Connect Amp CLI:
cd /your/project amp --ide -
Enable notifications (if not auto-enabled):
M-x amp-client-enable -
Start using Amp:
- Ask about code: Select text, then
M-x amp-client-send-message(orC-c a m/SPC A min Doom) while selection is active - Current context: Send messages - Amp sees your current file, cursor position, and any selected text
- Fix code: Select region, then use the fix command
- Explain code: Select region, then use the explain command
- Custom prompts: Select region, then use the prompt command
See the Commands table below for specific keybindings.
- Ask about code: Select text, then
| Command | Regular Emacs | Doom (evil) | Doom (non-evil) | Description |
|---|---|---|---|---|
amp-start |
C-c a s |
SPC A s |
C-c A s |
Start Amp server |
amp-stop |
C-c a q |
SPC A q |
C-c A q |
Stop Amp server |
amp-status |
C-c a ? |
SPC A ? |
C-c A ? |
Show connection status |
amp-client-send-message |
C-c a m |
SPC A m |
C-c A m |
Send message to Amp |
amp-fix-region |
C-c a f |
SPC A f |
C-c A f |
Fix selected code |
amp-improve-region |
C-c a i |
SPC A i |
C-c A i |
Improve selected code |
amp-explain-region |
C-c a e |
SPC A e |
C-c A e |
Explain selected code |
amp-prompt-for-region |
C-c a p |
SPC A p |
C-c A p |
Send region with custom prompt |
amp-client-enable |
M-x |
M-x |
M-x |
Enable file/selection tracking |
amp-client-disable |
M-x |
M-x |
M-x |
Disable notifications |
Note: Doom Emacs keybindings require the map! configuration shown in the Doom Emacs Configuration section.
;; 1. Start the server
M-x amp-start
;; 2. In terminal: amp --ide
;; 3. Enable notifications
M-x amp-client-enable
;; 4. Send a message
M-x amp-send-message RET hello from emacs! RET
;; 5. Ask Amp about current file
;; In Amp CLI: "what file am I looking at?"
;; 6. Fix some code
;; Select code, then: C-c a f
;; 7. Watch Amp edit the file directly!;; Auto-start Amp server when Emacs starts
(setq amp-auto-start t)
;; Log level: 'debug, 'info, 'warn, or 'error
(setq amp-server-log-level 'info)
;; Throttle notifications (seconds)
(setq amp-client-throttle-interval 0.1)
;; Custom data directory (optional)
;; (setq amp-server-data-home "~/.config/amp");; Create backups before editing files (default: t)
(setq amp-server-backup-on-edit t)
;; Maximum file size for edits (default: 10MB)
(setq amp-server-max-file-size (* 10 1024 1024))
;; Maximum number of concurrent connections (default: 5)
(setq amp-server-max-clients 5)
;; Maximum requests per second per client (default: 100)
(setq amp-server-max-request-rate 100)
;; Maximum WebSocket message size (default: 15MB)
(setq amp-server-max-message-size (* 15 1024 1024))(use-package websocket :ensure t)
(use-package amp
:load-path "~/path/to/amp-emacs"
:after websocket
:config
(setq amp-auto-start t)
(setq amp-server-log-level 'info)
(setq amp-client-throttle-interval 0.1)
:bind-keymap
("C-c a" . amp-mode-map));; In config.el
(use-package! amp
:after websocket
:config
(setq amp-auto-start t)
(setq amp-server-log-level 'info))
;; Amp keybindings (Doom-compatible)
;; For evil-mode users: Use SPC A prefix (SPC A m, SPC A f, etc.)
;; For non-evil users: Use C-c A prefix (C-c A m, C-c A f, etc.)
(map! :leader
:prefix ("A" . "amp")
:desc "Send message" "m" #'amp-client-send-message
:desc "Fix region" "f" #'amp-fix-region
:desc "Improve region" "i" #'amp-improve-region
:desc "Explain region" "e" #'amp-explain-region
:desc "Prompt for region" "p" #'amp-prompt-for-region
:desc "Start server" "s" #'amp-start
:desc "Stop server" "q" #'amp-stop
:desc "Restart" "r" #'amp-restart
:desc "Status" "?" #'amp-status)Note: In Doom Emacs, the minor mode keybindings (C-c a) may not work. Use the map! configuration above instead:
- With evil-mode:
SPC Aprefix (e.g.,SPC A mto send message) - Without evil-mode:
C-c Aprefix (e.g.,C-c A mto send message)
- WebSocket server on TCP localhost
- Port discovery - automatically finds available port (9000-9999)
- Authentication - generates cryptographically secure 256-bit tokens via
/dev/urandom - Lockfile management - creates JSON lockfile with port + token
- Message protocol - handles IDE protocol requests/responses
- Request handlers:
ping- health checkauthenticate- token validationreadFile- read file contents (with path validation)editFile- apply edits to buffers (with backups, validation, atomic writes)getDiagnostics- return diagnostics
- Security layer:
- Path traversal protection (validates relative to project root)
- Symlink resolution and security checks
- Sensitive directory blocking (
.git,.ssh,.gnupg) - Content validation (size, encoding, null bytes)
- Atomic file operations with rollback
- Automatic backups with timestamps
- Safety & reliability:
- Rate limiting (DoS protection)
- Client connection limits
- Message size validation
- Sanitized logging (no sensitive data)
- Read-only buffer respect
- Notifications to Amp:
visibleFilesDidChange- file trackingselectionDidChange- text selectionsuserSentMessage- direct messages
- Event hooks with throttling for performance
- Client enable/disable control
- User interface and commands
- Minor mode (amp-mode) for easy enable/disable
- Keybindings (C-c a prefix)
- Integration with projectile/project.el
Emacs (amp-emacs) Amp CLI
───────────────── ────────
1. Start WebSocket server
2. Create lockfile ──────> Read lockfile
3. Wait for connection <── Connect via WebSocket
4. Authenticate <────────> Send auth token
5. Send notifications ───> Receive file/selection info
6. Receive requests <───── Send readFile/editFile
7. Send responses ──────> Process responses
Communication uses WebSocket with JSON messages in IDE protocol format.
{
"port": 9000,
"authToken": "abc123...",
"pid": 12345,
"workspaceFolders": ["/path/to/project"],
"ideName": "emacs 29.1"
}{"serverNotification": {"visibleFilesDidChange": {"uris": ["file:///path/to/file"]}}}
{"serverNotification": {"userSentMessage": {"message": "Fix this code"}}}{"clientRequest": {"id": "1", "ping": {"message": "hello"}}}
{"clientRequest": {"id": "2", "readFile": {"path": "/path/to/file.py"}}}
{"clientRequest": {"id": "3", "editFile": {"path": "/path/to/file.py", "fullContent": "..."}}}{"serverResponse": {"id": "1", "ping": {"message": "hello"}}}
{"serverResponse": {"id": "2", "readFile": {"content": "file contents..."}}}
{"serverResponse": {"id": "3", "editFile": {"success": true, "message": "File updated"}}}-
Enable debug logging:
M-: (setq amp-server-log-level 'debug) M-x amp-start M-x view-echo-area-messages
-
Check for websocket package:
M-x package-install RET websocket RET
-
Check server status:
M-x amp-statusShould show:
Amp server running on port XXXX (project: /path, 0 clients) -
Verify lockfile:
cat ~/.local/share/amp/ide/*.json
Should show port, authToken, and other fields.
-
Check you're in the right directory: The Amp CLI needs to run in a directory under your project workspace.
-
Restart both sides:
M-x amp-stop M-x amp-start
Then restart
amp --ide
-
Check client is enabled:
M-: amp-client--enabled RET
Should return
t. Ifnil:M-x amp-client-enable -
Test with a simple message:
M-x amp-send-message RET test RETCheck debug messages:
M-x view-echo-area-messages -
Verify connection:
M-x amp-statusShould show "1 clients" if Amp CLI is connected.
The server automatically finds an available port (9000-9999). If all ports are in use, you'll see an error. Check what's using those ports:
netstat -tuln | grep '900[0-9]'Reduce notification frequency:
(setq amp-client-throttle-interval 0.5) ; Default is 0.1Amp creates automatic backups before editing files (e.g., file.txt.amp-backup-20251121-143022). If you want to disable this:
(setq amp-server-backup-on-edit nil)To clean up old backup files:
# Remove all amp backup files in a directory
find . -name "*.amp-backup-*" -deleteamp-emacs/
├── amp-server.el # WebSocket server and protocol
├── amp-client.el # Editor state notifications
├── amp.el # User interface
├── install-deps.el # Dependency installer
├── README.md # This file
├── INSTALL.org # Detailed installation guide
├── QUICKSTART.md # Quick start guide
├── TODO.org # Development roadmap
└── SUMMARY.org # Project summary
Currently manual testing only. Start development environment:
cd amp-emacs
emacs -Q --eval "(progn ...install websocket... (load \"amp\") (setq amp-server-log-level 'debug) (amp-start))"Contributions welcome! Areas of interest:
- Diagnostics integration - Connect flycheck/flymake
- Tests - Automated test suite
- Performance - Optimize notification frequency
- Documentation - Improve guides and examples
- Features - Mode line indicator, better UX
See TODO.org for full roadmap.
| Feature | amp.nvim | amp-emacs | Status |
|---|---|---|---|
| WebSocket server | ✓ | ✓ | ✅ Complete |
| Port + auth token | ✓ | ✓ | ✅ Complete |
| File tracking | ✓ | ✓ | ✅ Complete |
| Selection tracking | ✓ | ✓ | ✅ Complete |
| User messages | ✓ | ✓ | ✅ Complete |
| Read files | ✓ | ✓ | ✅ Complete |
| Edit files | ✓ | ✓ | ✅ Complete |
| Diagnostics | ✓ | Partial | |
| Multi-project | ✓ | Untested | |
| Official support | ✓ | ✗ | Community |
✅ Core functionality:
- Amp CLI connects to Emacs via WebSocket
- Messages sent from Emacs appear in Amp CLI
- Amp knows what file you're viewing
- Amp can read any file in your workspace
- Amp can edit files directly in your buffers
- All user commands work as expected
✅ Security & Safety (enterprise-ready):
- Path traversal protection prevents accessing files outside workspace
- Sensitive directories (
.git,.ssh,.gnupg) are blocked - Cryptographically secure token generation (256-bit)
- Atomic file writes prevent corruption
- Automatic backups created before edits
- Rate limiting prevents DoS attacks
- Sanitized logging prevents credential leaks
- Read-only buffers are respected
✅ Tested with:
- Amp CLI v0.0.1763121689 (2025-11-14)
- Emacs 28.1+
- Doom Emacs
- Regular Emacs with use-package
- Selection display: Amp uses selection notifications silently (doesn't display them in UI)
- Diagnostics: Returns empty array (needs flycheck/flymake integration)
- Multi-project: Untested with multiple simultaneous projects
- QUICKSTART.md - Get started in 5 minutes
- INSTALL.org - Detailed installation guide
- EXAMPLE-WORKFLOW.md - Real-world usage example with a debugging story
- TODO.org - Development roadmap
- SUMMARY.org - Complete project summary
- amp.nvim: https://github.com/sourcegraph/amp.nvim
- Amp Manual: https://ampcode.com/manual
- Amp CLI:
npm install -g @sourcegraph/amp - WebSocket Package: https://github.com/ahyatt/emacs-websocket
MIT License (or GPL-3.0+ to match Emacs conventions)
See LICENSE file for details.
Built by: Alvar (@alvarmaciel) and Claude (Anthropic)
This project was developed through a collaborative partnership between Alvar and Claude (an AI assistant by Anthropic). The implementation, architecture decisions, debugging, and documentation were created through an iterative conversation, combining:
- Alvar's vision: Deep Emacs integration for Amp, matching the functionality of amp.nvim
- Alvar's expertise: Emacs/Doom configuration, workflow requirements, and testing
- Claude's contribution: Code implementation, protocol research, debugging assistance, and documentation writing
- Joint effort: Architecture design, problem-solving, and iterative refinement
The entire development process, from initial concept to working implementation, happened in a single extended conversation where both participants contributed to the design and implementation decisions.
Inspired by: amp.nvim by Sourcegraph
Special thanks to:
- Sourcegraph team for creating Amp
- amp.nvim contributors for the reference implementation
- Emacs community for excellent tools and libraries
- The WebSocket package maintainers
Status: Production-ready! 🎉
Questions? Issues? Contributions? Open an issue on GitHub!