Channel tools
channels tool in package.json, then select it in each agent that should work with external conversations.Channels let a Recipe agent read and answer conversations in a supported chat
service. Declare the provider adapter under pi.channels, then add channels
to each agent that should use it. Slack is the currently available provider.
Declare the Slack provider
From the Recipe directory, install the Slack adapter:
pnpm add @introspection-ai/recipe-channel-slackThe adapter is a dependency, not a peer — and the difference is not a convention to memorise:
@introspection-ai/recipesis a peer because the runtime imports it too. Your agent runs inside the runtime’s module graph, so both must share one instance; a second copy would be a second set of module state. The runtime supplies it and the Recipe links to that copy.- A channel adapter is a dependency because the runtime never imports it. There is one adapter per provider, so the runtime carries none and the Recipe brings the one it uses.
So a peer is what the runtime provides, and a dependency is what the Recipe
brings. Declaring an adapter as a peer fails recipes check, and would not load
even if it passed: the managed install runs pnpm install --prod with
auto-install-peers=false, so a peer the runtime does not carry is never
installed. pnpm add writes the current range; declare Slack under
pi.channels alongside it:
{
"name": "support-agent",
"type": "module",
"dependencies": {
"@introspection-ai/recipe-channel-slack": "^0.3.0"
},
"peerDependencies": {
"@introspection-ai/recipes": "*"
},
"pi": {
"channels": [{ "provider": "slack" }]
}
}Commit package.json and pnpm-lock.yaml together — the managed install
honours the lockfile, and without one resolves the declared ranges afresh on
every install. Recipes install with pnpm, so
package-lock.json, npm-shrinkwrap.json and yarn.lock are rejected, and a
packageManager field must read pnpm@<version> if it is present at all.
Select the tool for an agent
Add channels to the agent’s tools. Give the agent instructions that explain
how it should use the conversation:
name: agent
description: Answer support questions in the channel that requested help.
ai:
model: anthropic/claude-sonnet-4-6
tools: [channels]
system_instructions:
mode: append
content: |
Read the Slack conversation when you need context for the request.
Reply in the same conversation with the completed answer.
Ask for missing information in the same conversation.The runtime supplies the authorized Slack account and the conversation that started the task.
Limit the available actions
The provider declaration can restrict the actions available to every agent in the Recipe:
{
"pi": {
"channels": [
{ "provider": "slack", "commands": ["read", "reply"] }
]
}
}The Slack adapter supports these actions:
| Command | What it lets the agent do |
|---|---|
list | Find Slack channels available to the connected app. |
read | Read messages in a channel or thread. |
reply | Answer in the conversation that started the task. |
send | Send a message to a channel or specified thread. |
react | Add or remove a reaction. |
edit and retract | Change or remove a message the agent sent. |
fetch_file | Download an attachment from a conversation. |
Omit commands to allow every action supported by the adapter. Each agent must
still include channels in its own tools list.
Validate the configuration
Run the Recipe checker from the repository that contains its runtime manifest:
introspection checkUse introspection dev --logs when testing Slack with local Recipe changes.
The channel development workflow explains
how to run the local changes and verify the conversation flow.
See the package.json manifest reference
for every channel field.