Skip to main content
ClaudeWave
EN, English
Skill31k repo starsupdated 6d ago

add-signal

The add-signal skill integrates Signal messaging into NanoClaw through a native JSON-RPC adapter that communicates with signal-cli's TCP daemon, requiring only Node.js built-in modules. Use this when you need Signal channel support without relying on Chat SDK bridges, registering either a dedicated phone number or linking as a secondary device to an existing Signal account after installing Java 17+ and signal-cli.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/add-signal && cp -r /tmp/add-signal/.claude/skills/add-signal ~/.claude/skills/add-signal
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

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

```nc:run effect:external
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):

```nc:copy from-branch:channels
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:

```nc:append to:src/channels/index.ts
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`:

```nc:dep
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.

```nc:run effect:build
pnpm run build
```
```nc:run effect:test
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):

```nc:run effect:check
command -v signal-cli >/dev/null 2>&1 || [ -x "$SIGNAL_CLI_PATH" ]
```

Tell the user:

```nc:operator
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:

```nc:run effect:step capture:platform_id=ACCOUNT,owner_handle=ACCOUNT
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:

```nc:env-set
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:

```nc:run effect:restart
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:

```bash
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):

```bash
# 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):

```bash
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 `/setup`, return to the setup flow now. Otherwise wire
this channel with `/init-first-agent` (or `/manage-channels`).

## Channel Info
add-anydocSkill

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when agents need to read attached Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, or text-based PDF files without uploading them to a hosted parser.

add-atomic-chat-toolSkill

Add Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.

add-clidashSkill

Add clidash — a zero-dependency, read-only web dashboard that derives its tabs and tables at runtime from any CLI that lists resources as JSON. Ships pre-wired for NanoClaw's ncl CLI (agent groups, sessions, channels, users, roles), plus message-activity charts, a log tail, and a read-only file viewer for group skills/CLAUDE.md/profiles.

add-codexSkill

Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or instead of Claude. ChatGPT subscription or OpenAI API key, vault-only via OneCLI. Per-group via `ncl groups config update --provider codex`. Distinct from using OpenAI as an MCP tool (where Claude remains the planner).

add-dashboardSkill

Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.

add-deltachatSkill

Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.

add-dialSkill

Add Dial channel integration — a real phone number for SMS and AI voice calls via the Dial platform (getdial.ai). Native adapter — no Chat SDK bridge.

add-dial-numberSkill

Add another phone number to an existing Dial channel — a second (or third) public line for the agent, so one NanoClaw install answers SMS and AI voice calls on multiple numbers. Use when Dial is already installed and the operator wants an additional number (e.g. a personal line plus a support line). Requires the Dial channel to already be installed (see /add-dial).