Skip to content
Automation
Skill

/add-signal

Add Signal channel integration via signal-cli device-link. Native adapter — no Chat SDK bridge.

From plugin
nanoclaw
31k61 skills
Install
$ npx -y skills add nanocoai/nanoclaw --skill add-signal --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/add-signal

Context preview

The summary Claude sees to decide when to auto-load this skill.

Add Signal channel integration via signal-cli device-link. Native adapter — no Chat SDK bridge.

SKILL.md

add-signal.SKILL.md
name: add-signal
description: Add Signal channel integration via signal-cli device-link. Native adapter — no Chat SDK bridge.

Add Signal Channel

Adds Signal support via a native adapter that speaks JSON-RPC to a [signal-cli](https://github.com/AsamK/signal-cli) daemon — no Chat SDK bridge, only Node.js builtins. NanoClaw links to Signal as a *secondary device* on your existing phone: no new number, no bot API. Your assistant sends and receives as the number on the phone that scans the link.

Apply

1. Install signal-cli

NanoClaw talks to Signal through signal-cli, which has no bot API of its own. Install it if it isn't on PATH yet — Homebrew on macOS, the native release binary on Linux (neither needs Java). If it's already installed this is a no-op:

command -v signal-cli >/dev/null 2>&1 || bash setup/install-signal-cli.sh

2. Copy the adapter and its registration test

Fetch the `channels` branch and copy the Signal adapter and its registration test into `src/channels/` (overwrite — the branch is canonical):

src/channels/signal.ts
src/channels/signal-registration.test.ts

3. Register the adapter

Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core:

import './signal.js';

4. Install the QR-rendering dependency

The device-link step renders the linking URL as a terminal QR via `qrcode`. Pinned to exact versions — the supply-chain policy rejects ranges and `latest`:

qrcode@1.5.4
@types/qrcode@1.5.6

The adapter itself consumes only Node.js builtins, so there is no adapter package to install — `qrcode` is purely for rendering the link during setup.

5. Build and validate

Build first: it guards the adapter's typed core-API consumption. Then run the one integration test.

pnpm run build
pnpm exec vitest run src/channels/signal-registration.test.ts

`signal-registration.test.ts` imports the real channel barrel and asserts the registry contains `signal`. It goes red if the `import './signal.js';` line is deleted or drifts, or if the barrel fails to evaluate — so the channel genuinely would not register. The adapter has no npm dependency to guard; its typed core-API consumption is covered by the build. End-to-end delivery against a real Signal account is verified manually once the service runs.

Link your Signal account

This is the whole credential step. signal-cli opens a device-link handshake, prints a `sgnl://linkdevice…` URL, and renders it as a scannable QR. You scan it once from the phone that already runs Signal; that phone's number becomes the account NanoClaw sends and receives as — no number is registered.

The device-link runs signal-cli, so it must be reachable first — on `PATH`, or at `$SIGNAL_CLI_PATH`. If step 1's install didn't land, the link step has nothing to drive; confirm it's present before linking (re-run step 1 if this fails):

command -v signal-cli >/dev/null 2>&1 || [ -x "$SIGNAL_CLI_PATH" ]

Tell the user:

Link NanoClaw to your Signal account:
1. On the phone that runs Signal, open Signal → Settings → Linked Devices → Link New Device.
2. Scan the QR code shown below — or open the `sgnl://linkdevice…` link printed under it on that phone.
3. Wait for confirmation. The linking URL expires after ~3 minutes; re-run this step for a fresh one.

Run the device-link. It blocks until you scan, then reports the linked phone number back as the account — that number is both your owner handle and the conversation address the wiring step needs:

pnpm exec tsx setup/index.ts --step signal-auth

`owner_handle` and `platform_id` both come back as the bare phone number (e.g. `+15551234567`). Your assistant reaches you through Signal's Note to Self, so the owner conversation is addressed by your own number — not a per-contact UUID.

Persist the account

Store the linked number so the adapter binds the right account on start, then sync it into the container env:

SIGNAL_ACCOUNT={{platform_id}}

Restart

Restart the service so it loads the Signal adapter and binds the account you just linked, and wait for its CLI socket before wiring:

bash setup/lib/restart.sh

Wiring

DMs

After the service starts, send any message to the Signal number from your personal Signal app. The router auto-creates a `messaging_groups` row. Then:

pnpm exec tsx scripts/q.ts data/v2.db \
  "SELECT id, platform_id FROM messaging_groups WHERE channel_type='signal' ORDER BY created_at DESC LIMIT 5"

Pass the `id` to `/init-first-agent` or `/manage-channels` to wire it to an agent group.

Groups

Add the Signal number to a group from your phone, send any message, then wire the resulting row the same way. Each group gets its own session with the default `shared` mode (one session per agent + messaging group). Create the wiring with `ncl` — **the host service must be running** (`ncl` connects to it over a Unix socket):

# Engage mode/pattern default to the Signal adapter's declared channel defaults
ncl wirings create --messaging-group-id mg-GROUPID --agent-group-id ag-AGENTID

Grant user access

New Signal users (including the owner's Signal identity) are silently dropped with `not_member` until granted access. After the user's first message appears in `messaging_groups` (host service running):

ncl users create --id "signal:UUID" --kind signal --display-name "<name>"
ncl roles grant --user "signal:UUID" --role owner
ncl members add --user "signal:UUID" --group ag-AGENTID

Find the UUID from `messaging_groups.platform_id` or the `users` table.

Next Steps

If you're in the middle of

Read more
Ships withnanoclaw

A lightweight alternative to OpenClaw that runs in containers for security. Connects to WhatsApp, Telegram, Slack, Discord, Gmail and other messaging apps,, has memory, scheduled jobs, and runs directly on Anthropic's Agents SDK

Get the whole plugin
Stats
30,745
Stars
12,836
Forks
Active
Maintenance
TypeScript
Language
MIT
License
3d ago
Last commit
7mo ago
Created

Repo: nanocoai/nanoclaw

Other skills on nanoclaw.