add-emacs
Add Emacs Channel
This skill adds Emacs support to NanoClaw, then walks through interactive setup. Works with Doom Emacs, Spacemacs, and vanilla Emacs 27.1+.
What you can do with this
- Ask while coding — open the chat buffer (
C-c n c/SPC N c), ask about a function or error without leaving Emacs - Code review — select a region and send it with
nanoclaw-org-send; the response appears as a child heading inline in your org file - Meeting notes — send an org agenda entry; get a summary or action item list back as a child node
- Draft writing — send org prose; receive revisions or continuations in place
- Research capture — ask a question directly in your org notes; the answer lands exactly where you need it
- Schedule tasks — ask Andy to set a reminder or create a scheduled NanoClaw task (e.g. "remind me tomorrow to review the PR")
Phase 1: Pre-flight
Check if already applied
Check if src/channels/emacs.ts exists:
test -f src/channels/emacs.ts && echo "already applied" || echo "not applied"
If it exists, skip to Phase 3 (Setup). The code changes are already in place.
Phase 2: Apply Code Changes
Ensure the upstream remote
git remote -v
If an upstream remote pointing to https://github.com/qwibitai/nanoclaw.git is missing,
add it:
git remote add upstream https://github.com/qwibitai/nanoclaw.git
Merge the skill branch
git fetch upstream skill/emacs
git merge upstream/skill/emacs
If there are merge conflicts on package-lock.json, resolve them by accepting the incoming
version and continuing:
git checkout --theirs package-lock.json
git add package-lock.json
git merge --continue
For any other conflict, read the conflicted file and reconcile both sides manually.
This adds:
src/channels/emacs.ts—EmacsBridgeChannelHTTP server (port 8766)src/channels/emacs.test.ts— unit testsemacs/nanoclaw.el— Emacs Lisp package (nanoclaw-chat,nanoclaw-org-send)import './emacs.js'appended tosrc/channels/index.ts
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
Validate code changes
npm run build
npx vitest run src/channels/emacs.test.ts
Build must be clean and tests must pass before proceeding.
Phase 3: Setup
Configure environment (optional)
The channel works out of the box with defaults. Add to .env only if you need non-defaults:
EMACS_CHANNEL_PORT=8766 # default — change if 8766 is already in use
EMACS_AUTH_TOKEN=<random> # optional — locks the endpoint to Emacs only
If you change or add values, sync to the container environment:
mkdir -p data/env && cp .env data/env/env
Configure Emacs
The nanoclaw.el package requires only Emacs 27.1+ built-in libraries (url, json, org) — no package manager setup needed.
AskUserQuestion: Which Emacs distribution are you using?
- Doom Emacs - config.el with map! keybindings
- Spacemacs - dotspacemacs/user-config in ~/.spacemacs
- Vanilla Emacs / other - init.el with global-set-key
Doom Emacs — add to ~/.config/doom/config.el (or ~/.doom.d/config.el):
;; NanoClaw — personal AI assistant channel
(load (expand-file-name "~/src/nanoclaw/emacs/nanoclaw.el"))
(map! :leader
:prefix ("N" . "NanoClaw")
:desc "Chat buffer" "c" #'nanoclaw-chat
:desc "Send org" "o" #'nanoclaw-org-send)
Then reload: M-x doom/reload
Spacemacs — add to dotspacemacs/user-config in ~/.spacemacs:
;; NanoClaw — personal AI assistant channel
(load-file "~/src/nanoclaw/emacs/nanoclaw.el")
(spacemacs/set-leader-keys "aNc" #'nanoclaw-chat)
(spacemacs/set-leader-keys "aNo" #'nanoclaw-org-send)
Then reload: M-x dotspacemacs/sync-configuration-layers or restart Emacs.
Vanilla Emacs — add to ~/.emacs.d/init.el (or ~/.emacs):
;; NanoClaw — personal AI assistant channel
(load-file "~/src/nanoclaw/emacs/nanoclaw.el")
(global-set-key (kbd "C-c n c") #'nanoclaw-chat)
(global-set-key (kbd "C-c n o") #'nanoclaw-org-send)
Then reload: M-x eval-buffer or restart Emacs.
If EMACS_AUTH_TOKEN was set, also add (any distribution):
(setq nanoclaw-auth-token "<your-token>")
If EMACS_CHANNEL_PORT was changed from the default, also add:
(setq nanoclaw-port <your-port>)
Restart NanoClaw
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
# Linux: systemctl --user restart nanoclaw
Phase 4: Verify
Test the HTTP endpoint
curl -s "http://localhost:8766/api/messages?since=0"
Expected: {"messages":[]}
If you set EMACS_AUTH_TOKEN:
curl -s -H "Authorization: Bearer <token>" "http://localhost:8766/api/messages?since=0"
Test from Emacs
Tell the user:
- Open the chat buffer with your keybinding (
SPC N c,SPC a N c, orC-c n c)- Type a message and press
RET- A response from Andy should appear within a few seconds
For org-mode: open any
.orgfile, position the cursor on a heading, and useSPC N o/SPC a N o/C-c n o
Check logs if needed
tail -f logs/nanoclaw.log
Look for Emacs channel listening at startup and Emacs message received when a message is sent.
Troubleshooting
Port already in use
Error: listen EADDRINUSE: address already in use :::8766
Either a stale NanoClaw process is running, or 8766 is taken by another app.
Find and kill the stale process:
lsof -ti :8766 | xargs kill -9
Or change the port in .env (EMACS_CHANNEL_PORT=8767) and update nanoclaw-port in Emacs config.
No response from agent
Check:
- NanoClaw is running:
launchctl list | grep nanoclaw(macOS) orsystemctl --user status nanoclaw(Linux) - Emacs group is registered:
sqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid = 'emacs:default'" - Logs show activity:
tail -50 logs/nanoclaw.log
If the group is not registered, it will be created automatically on the next NanoClaw restart.
Auth token mismatch (401 Unauthorized)
Verify the token in Emacs matches .env:
;; M-x describe-variable RET nanoclaw-auth-token RET
Must exactly match EMACS_AUTH_TOKEN in .env.
nanoclaw.el not loading
Check the path is correct:
ls ~/src/nanoclaw/emacs/nanoclaw.el
If NanoClaw is cloned elsewhere, update the load/load-file path in your Emacs config.
After Setup
If running npm run dev while the service is active:
# macOS:
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist
npm run dev
# When done testing:
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
# Linux:
# systemctl --user stop nanoclaw
# npm run dev
# systemctl --user start nanoclaw
Agent Formatting
The Emacs bridge converts markdown → org-mode automatically. Agents should output standard markdown — not org-mode syntax. The conversion handles:
| Markdown | Org-mode |
|---|---|
**bold** |
*bold* |
*italic* |
/italic/ |
~~text~~ |
+text+ |
`code` |
~code~ |
```lang |
#+begin_src lang |
If an agent outputs org-mode directly, bold/italic/etc. will be double-converted and render incorrectly.
Removal
To remove the Emacs channel:
- Delete
src/channels/emacs.ts,src/channels/emacs.test.ts, andemacs/nanoclaw.el - Remove
import './emacs.js'fromsrc/channels/index.ts - Remove the NanoClaw block from your Emacs config file
- Remove Emacs registration from SQLite:
sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid = 'emacs:default'" - Remove
EMACS_CHANNEL_PORTandEMACS_AUTH_TOKENfrom.envif set - Rebuild:
npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw(macOS) ornpm run build && systemctl --user restart nanoclaw(Linux)
More from qwibitai/nanoclaw-skills
claw
Install the claw CLI tool — run NanoClaw agent containers from the command line without opening a chat app.
1add-gmail
Add Gmail integration to NanoClaw. Can be configured as a tool (agent reads/sends emails when triggered from WhatsApp) or as a full channel (emails can trigger the agent, schedule tasks, and receive replies). Guides through GCP OAuth setup and implements the integration.
1add-ollama-tool
Add Ollama MCP server so the container agent can call local models for cheaper/faster tasks like summarization, translation, or general queries.
1get-qodo-rules
Loads org- and repo-level coding rules from Qodo before code tasks begin, ensuring all generation and modification follows team standards. Use before any code generation or modification task when rules are not already loaded. Invoke when user asks to write, edit, refactor, or review code, or when starting implementation planning.
1add-compact
Add /compact command for manual context compaction. Solves context rot in long sessions by forwarding the SDK's built-in /compact slash command. Main-group or trusted sender only.
1add-whatsapp
Add WhatsApp as a channel. Can replace other channels entirely or run alongside them. Uses QR code or pairing code for authentication.
1