Skip to content

Guide · Agent skill

How to use the Slack Agent-to-Agent Rooms agent skill

Updated · written with AI from the project's own documentation and checked against our catalogue data

The slack-a2a-rooms skill sets up a shared Slack group DM where a human and two or more NanoClaw Slack bots can read and reply to each other. It is for developers and operators who already run several NanoClaw Slack bots and want them to hand tasks to one another under human supervision. After following this guide you will know how to install the skill, open a room, and tune the limits that keep bot-to-bot traffic under control.

Slack Agent-to-Agent Roomsnanocoai/nanoclaw · MIT

Quick start

  1. 1Check your NanoClaw setup. Confirm the Slack channel is installed with its bot-inbound guard. If the grep check in the skill fails, re-run /add-slack from a channels branch that includes the guard.
  2. 2Install the skill. Unzip the downloaded ZIP into ~/.claude/skills/ or the project's .claude/skills/, or upload it under Settings, Capabilities, Skills in the Claude apps.
  3. 3Apply the skill files. Let the skill copy slack-a2a.ts, its test, and open-a2a-room.ts into your checkout, and add the self-registration import to the channel barrel.
  4. 4Build and run tests. Run pnpm run build, then pnpm exec vitest run src/channels/slack-a2a.test.ts. Fix any failures before continuing.
  5. 5Open the room. Run the opener script with at least two instance names and, optionally, the human's user id. Note the channel id it prints.
  6. 6Set the access policy. After the first human mention, make the room public or approve each bot sender once so their messages are accepted by the router.
  7. 7Test with a message. Post a message from the human in the room and confirm the bots reply. Keep an eye on the hop limit if bots start talking without a person.

What does the skill make the agent do?

By default, the Slack channel in NanoClaw drops every message written by another bot before it reaches the router. This skill changes that for specific rooms only. It registers an admission policy on the Slack channel's bot-inbound guard, so bot-authored messages pass through only in rooms listed in the SLACK_A2A_ROOMS setting.

Messages that pass are attributed to the sender id slack:bot:<botId>. A consecutive-hop limit then applies: after SLACK_A2A_MAX_HOPS bot messages in a row with no human message, further bot messages are dropped until a human speaks. Bots outside the listed rooms stay blocked, as before.

  • Opens a group DM (MPIM) with a human and two or more sibling bots
  • Admits bot messages only in allowlisted rooms
  • Tags bot messages with slack:bot:<botId>
  • Stops bot loops after a set number of consecutive bot messages

What you need before installing

The skill only works inside a NanoClaw checkout. The Slack channel must already be installed with /add-slack, and it must include the slack-a2a-guard.ts bot-inbound guard. The skill checks for this guard first and stops if it is missing.

You also need at least two Slack bot tokens (SLACK_BOT_TOKEN, or SLACK_BOT_TOKEN_<NAME> for named bots). Each Slack app needs the mpim:write, mpim:history and mpim:read scopes and the message.mpim bot event. Apps created through the managed flow already include these. Building, testing and running the opener script use the Node and pnpm toolchain.

  • A NanoClaw checkout with the Slack channel and bot-inbound guard
  • Two or more Slack bot tokens
  • Scopes: mpim:write, mpim:history, mpim:read
  • Bot event: message.mpim
  • Node and pnpm

Install the skill

Download the skill ZIP from this page and unzip it. For a personal setup, place the folder in ~/.claude/skills/. For a single project, place it in that project's .claude/skills/ folder. Claude Code will then find the skill in those locations.

If you use the Claude apps instead, open Settings, go to Capabilities, then Skills, and upload the ZIP there.

The skill's SKILL.md then guides the apply steps: it copies src/channels/slack-a2a.ts, src/channels/slack-a2a.test.ts and scripts/open-a2a-room.ts into the tree, and appends import './slack-a2a.js'; to src/channels/index.ts.

Build and test the change

After the files are copied, run the build first. It catches drift in the typed setBotInboundPolicy call. Then run the test file, which drives the real channel barrel and the bot-inbound guard end to end.

The tests check allowlisted-room admission with slack:bot:<botId> attribution, drops in unlisted rooms, the hop limit with human reset, per-room and per-identity budgets, and that a downstream error does not use up hop budget.

pnpm run build pnpm exec vitest run src/channels/slack-a2a.test.ts

Open a room and register it

Run the opener script with the instance names and the human's Slack user id. The first listed instance opens the conversation, invites the human and the other bots, posts an intro message, and prints the channel id. It also appends that id to SLACK_A2A_ROOMS in .env.

Without --user you get a bots-only room, which needs at least three instances, because Slack turns a two-party open into a one-to-one IM.

  • Set SLACK_A2A_MAX_HOPS in .env to change the hop limit (default 6)
  • Both settings are re-read about every 30 seconds, so no restart is needed
pnpm exec tsx scripts/open-a2a-room.ts --instances dana,eli --user U0AAAAAAA

Let bot senders through the access gate

The room allowlist only gets bot messages to the router. The permissions module still checks each sender. Bot senders appear as slack:bot:<botId>, which starts as unknown. After the first human mention creates the room's messaging group, you can set the room to public, or keep request_approval and approve each bot sender once.

A private A2A room with known humans is a reasonable place for public. The source notes that the botId is the user id (U…) in recent versions of the Slack adapter, while older bots used their B… bot id. Bots approved under a B… id must be approved again after that change.

  • Public: set unknown_sender_policy to public for the room's messaging group
  • Approval: keep request_approval and approve each slack:bot:<botId> sender once
pnpm exec tsx scripts/q.ts data/v2.db "UPDATE messaging_groups SET unknown_sender_policy='public' WHERE platform_id='slack:<channel id>'"

What people use it for

  • Two NanoClaw bots, one for research and one for drafting, pass tasks back and forth while a human watches and steps in.
  • An operator runs a three-bot room with no human present to split a batch job, with the hop limit stopping runaway exchanges.
  • A team keeps a private room with known humans where a triage bot hands off tickets to a specialist bot.
  • A developer tests how two bot identities coordinate in a sandbox workspace before using the pattern elsewhere.

Frequently asked questions

How do I install the slack-a2a-rooms skill?

Download the ZIP from this page and unzip it into ~/.claude/skills/ for personal use or into a project's .claude/skills/ folder. In the Claude apps, you can instead upload the ZIP under Settings, Capabilities, Skills. The skill then guides the file copy and build steps inside your NanoClaw checkout.

Is the slack-a2a-rooms skill free?

The source material for this page lists the skill under the MIT licence. It does not mention pricing, so check the NanoClaw repository for any terms of use. You will still need your own Slack workspace and bot tokens.

What do I need to run slack-a2a-rooms?

You need a NanoClaw checkout with the Slack channel installed through /add-slack, including the bot-inbound guard. You also need at least two Slack bot tokens, the mpim:write, mpim:history and mpim:read scopes, and the message.mpim bot event. Node and pnpm are needed to build and run the scripts.

Why are my bots not hearing each other?

Check that the room's channel id is in SLACK_A2A_ROOMS, that each app has the MPIM scopes and the message.mpim event, and that the senders are approved or the room is set to public. If bots still ignore each other, the hop limit may have been reached, which resets only when a human speaks.

Can I use this with only one bot?

No. The skill requires at least two Slack bot identities. With one bot it adds nothing, because there is no second bot to talk to.

How is this different from Slack's default bot behaviour?

By default, the bot-inbound guard drops all bot-authored messages before they reach the router. This skill keeps that default everywhere except in rooms you list in SLACK_A2A_ROOMS, and it adds a hop limit so bot messages stop after a set number in a row until a human speaks.

New agent skills, repos and AI tools — every week

The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.

Our verdict

Use this skill if you run several NanoClaw Slack bots and want them to coordinate in a room a human can watch and stop. Pick a different approach if you have a single bot, or if your workspace is public or shared, because admitted bot messages are trusted by the router and could expose data or trigger unintended actions.

Download the skill

Find exactly what
you're looking for