Nanoclaw add-emacs

Add Emacs as a channel. Opens an interactive chat buffer and org-mode integration so you can talk to NanoClaw from within Emacs (Doom, Spacemacs, or vanilla). Uses a local HTTP bridge — no bot token or external service needed.

install
source · Clone the upstream repo
git clone https://github.com/qwibitai/nanoclaw
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/qwibitai/nanoclaw "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/add-emacs" ~/.claude/skills/qwibitai-nanoclaw-add-emacs && rm -rf "$T"
manifest: .claude/skills/add-emacs/SKILL.md
source content

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
    EmacsBridgeChannel
    HTTP server (port 8766)
  • src/channels/emacs.test.ts
    — unit tests
  • emacs/nanoclaw.el
    — Emacs Lisp package (
    nanoclaw-chat
    ,
    nanoclaw-org-send
    )
  • import './emacs.js'
    appended to
    src/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:

  1. Open the chat buffer with your keybinding (
    SPC N c
    ,
    SPC a N c
    , or
    C-c n c
    )
  2. Type a message and press
    RET
  3. A response from Andy should appear within a few seconds

For org-mode: open any

.org
file, position the cursor on a heading, and use
SPC 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:

  1. NanoClaw is running:
    launchctl list | grep nanoclaw
    (macOS) or
    systemctl --user status nanoclaw
    (Linux)
  2. Emacs group is registered:
    sqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid = 'emacs:default'"
  3. 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:

MarkdownOrg-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:

  1. Delete
    src/channels/emacs.ts
    ,
    src/channels/emacs.test.ts
    , and
    emacs/nanoclaw.el
  2. Remove
    import './emacs.js'
    from
    src/channels/index.ts
  3. Remove the NanoClaw block from your Emacs config file
  4. Remove Emacs registration from SQLite:
    sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid = 'emacs:default'"
  5. Remove
    EMACS_CHANNEL_PORT
    and
    EMACS_AUTH_TOKEN
    from
    .env
    if set
  6. Rebuild:
    npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw
    (macOS) or
    npm run build && systemctl --user restart nanoclaw
    (Linux)