npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-claude-cli-bridge

v0.2.3

Published

n8n community node that calls the locally-installed, subscription-authenticated Claude CLI directly — no Anthropic API key, no separate server process

Readme

n8n-nodes-claude-cli-bridge

n8n community node that calls the locally-installed, subscription-authenticated claude CLI directly from inside the n8n process — no Anthropic API key, no separate server to run.

Why

The official Anthropic n8n node requires an API key (pay-per-token billing). This node instead shells out to the claude CLI, authenticated via claude login/claude /login, so usage rides your Claude subscription (Pro/Max/Team) instead.

How it works

There is no bridge/server process. The node's execute() runs claude -p "<prompt>" as a child process of the n8n worker itself and returns { success, output, error }.

  • n8n running on bare metal/VM (no Docker): works out of the box as long as claude is on PATH and logged in as the user running n8n.
  • n8n running in Docker: see the full setup below — this is the path that's actually been tested end-to-end.

Install

npm install n8n-nodes-claude-cli-bridge

Or via the n8n UI: Settings → Community Nodes → Installn8n-nodes-claude-cli-bridge.

Credential: Claude CLI

| Field | Description | |---|---| | CLI Path | Path to the claude binary, or just claude if it's on PATH. Falls back to the CLAUDE_CLI_PATH env var, then "claude". | | Home Directory | Directory containing .claude/ with login credentials. Leave empty to use the process HOME. For the Docker setup below, this is /home/node. |

Node: Claude CLI

| Field | Description | |---|---| | Prompt | Text sent to claude -p | | Model | Optional --model override | | Attach PDF | Extracts text from a binary PDF input (via pdftotext, if installed) and appends it to the prompt | | Input Binary Field | Name of the binary property holding the PDF (default data) | | Timeout (ms) | Kills the claude process if it runs longer than this |

Running n8n in Docker (tested, recommended setup)

Do not bind-mount your host's claude binary or ~/.claude credentials into the container. This was tried and fails in two separate ways:

  1. Architecture/libc mismatch. The official claude binary is typically glibc-linked. The official n8n image is Alpine (musl). A glibc binary will not run on it even if bind-mounted in.
  2. Single-file bind mounts break on rewrite. The CLI rewrites .claude.json and .credentials.json via backup-and-replace (not in-place edit). Docker's file-level bind mount tracks the original inode, so the first time the host rewrites the file, the container's view of it goes stale or disappears.

The setup that actually works: install the CLI natively inside the container (matching its own musl/arch), and log in once, interactively, inside the container, persisting credentials to named Docker volumes — completely independent of any host-side claude login.

1. Dockerfile

FROM n8nio/n8n:latest
USER root
RUN npm install -g @anthropic-ai/claude-code
RUN ln -s $(npm config get prefix)/bin/claude /usr/local/bin/claude
USER node

Notes on each line:

  • FROM n8nio/n8n:latest — use the plain Docker Hub path, not docker.n8n.io/n8nio/n8n:latest. The docker.n8n.io mirror is still backed by Docker Hub's anonymous pull quota and hits 429 Too Many Requests far more easily on shared-IP VPS hosts. If you still hit the rate limit, docker login first — authenticated pulls get a much higher quota.
  • npm install -g @anthropic-ai/claude-codenpm automatically resolves the correct platform build (e.g. @anthropic-ai/claude-code-linux-arm64-musl), so this works natively inside Alpine without any host binary involved.
  • The ln -s line is required. The official n8n image installs Node.js to a custom path (e.g. /opt/nodejs/node-v24.15.0/), not the standard /usr/local. npm install -g puts the claude binary in that custom path's bin/, which isn't necessarily resolved by every shell/PATH context the container or n8n's Execute Command node uses. Symlinking it into /usr/local/bin (which the image does keep on PATH) makes plain claude resolve everywhere reliably. Without this, which claude returns nothing even though the install succeeded — check with npm list -g --depth=0 and look for the @anthropic-ai/claude-code line's containing prefix if you ever need to re-locate it manually.

2. docker-compose.yml

services:
  n8n:
    build:
      context: .                # wherever the Dockerfile above lives
      dockerfile: Dockerfile
    environment:
      - N8N_COMMUNITY_NODES_ENABLED=true
      - DISABLE_AUTOUPDATER=1    # see note below
      # ... your other n8n env vars
    volumes:
      - n8n_data:/home/node/.n8n
      - claude_home:/home/node/.claude
      - claude_data:/home/node/.local/share/claude

volumes:
  n8n_data:
  claude_home:
  claude_data:

Named volumes (not bind mounts) avoid both problems above: they're directories the container fully owns, immune to the host-rewrite/inode issue, and they persist across redeploys.

DISABLE_AUTOUPDATER=1 silences a (harmless but noisy) "Can't auto-update: npm global folder isn't writable" warning from claude /doctor. The CLI normally self-updates in place; inside a container that's pointless since any self-update is wiped out the next time the container is recreated from the image — updates should happen by bumping the version in the Dockerfile's npm install and rebuilding, not by letting the CLI patch itself live.

If you're using a stack manager (Portainer, Dockge, etc.) that pulls images rather than building them, either:

  • point it at a build: block as above (preferred — it builds automatically on deploy), or
  • build the image manually (docker build -t n8n-claude:latest .) and reference image: n8n-claude:latest with pull_policy: never added under it, so the manager doesn't try to pull a same-named image from a registry where it doesn't exist (pull access denied for n8n-claude is the symptom of skipping this).

3. Build and deploy

docker build -t n8n-claude:latest .
docker compose up -d

Rebuilding the image alone does not update an already-running container. Docker pins a running container to the image ID it started with. After any Dockerfile change, recreate the container, not just rebuild the image:

docker compose down && docker compose up -d

(docker inspect <container> --format '{{.Config.Image}}' tells you which image tag a running container actually thinks it's using, if you want to confirm before/after.)

4. Fix volume ownership (one-time)

Docker creates a brand-new named volume's mount point owned by root. The node user n8n runs as can't write to it until you fix this once:

docker exec -u root -it <container_name> chown -R node:node /home/node/.claude /home/node/.local/share/claude

5. Log in, interactively, inside the container

docker exec -it <container_name> sh -c 'HOME=/home/node claude'

Type /login at the prompt, complete the browser-based OAuth flow (it'll give you a URL since there's no browser in the container), then exit cleanly (Ctrl-D).

Verify it persisted with a fresh exec session (important — this confirms it was actually written to disk, not just held in memory for that one session):

docker exec -it <container_name> sh -c 'HOME=/home/node claude -p "say OK"; echo EXIT:$?'

This should print OK followed by EXIT:0.

6. Set up the n8n credential

  • CLI Path: leave empty
  • Home Directory: /home/node

That's it — the node now runs fully self-contained inside the n8n container, authenticated against your Claude subscription, with no host dependency and no separate server.