From 1c4ec8ed5df77deb63242ece8cd22a12384fca8c Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 29 Oct 2026 21:25:58 -0700 Subject: [PATCH 1/4] docs: match the team agent's wording to what it does and warn about crafted messages Co-Authored-By: Claude --- README.md | 3 +++ claude-agent-sdk/README.md | 9 +++++++-- claude-agent-sdk/listeners/views/app_home_builder.py | 4 ++-- openai-agents-sdk/README.md | 9 +++++++-- openai-agents-sdk/listeners/views/app_home_builder.py | 4 ++-- pydantic-ai/README.md | 9 +++++++-- pydantic-ai/listeners/views/app_home_builder.py | 4 ++-- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0774d7b..0565103 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ A sample Slack agent built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) that keeps your team's runbooks current and helps route the requests that come in. Runbooks are Slack canvases titled `Runbook: `. The agent answers from them, and it learns from the messages in your team's channels, so the runbooks it writes are the ones it answers from next time. +> [!WARNING] +> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to the framework README for how the Slack MCP Server is connected. + ## Choose Your Framework This repo contains the same app built with three different AI agent frameworks. Pick the one that fits your stack: diff --git a/claude-agent-sdk/README.md b/claude-agent-sdk/README.md index 849f45e..6a00f37 100644 --- a/claude-agent-sdk/README.md +++ b/claude-agent-sdk/README.md @@ -1,6 +1,9 @@ # Team Agent for Slack (Bolt for Python and Claude Agent SDK) -A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) using models from [Anthropic](https://www.anthropic.com). It keeps your team's runbooks current as threads wrap up and helps route the requests that come in. Runbooks are Slack canvases that the agent reads and writes through the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). +A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) using models from [Anthropic](https://www.anthropic.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). + +> [!WARNING] +> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. ## App Overview @@ -276,6 +279,8 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. +> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. + ### Using the App @@ -324,7 +329,7 @@ Every incoming request is routed to a "listener". This directory groups each lis - `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. - `app_mentioned.py` — Responds to @mentions in channels. -- `message.py` — Responds to direct messages and learns from channel messages by connected users. +- `message.py` — Responds to direct messages and learns from channel messages. **`/listeners/actions`** — Handles interactive components: diff --git a/claude-agent-sdk/listeners/views/app_home_builder.py b/claude-agent-sdk/listeners/views/app_home_builder.py index 49dbc12..129a40c 100644 --- a/claude-agent-sdk/listeners/views/app_home_builder.py +++ b/claude-agent-sdk/listeners/views/app_home_builder.py @@ -23,8 +23,8 @@ def build_app_home_view( "type": "mrkdwn", "text": ( "I keep your team's runbooks current and help route requests.\n\n" - "*Invite me to your team channel* and I'll add what your threads " - "figure out to runbooks as they wrap up. *Mention me* or *send me a " + "*Invite me to your team channel* and I'll add what your messages " + "settle to runbooks. *Mention me* or *send me a " "direct message* to find a runbook or triage a request." ), }, diff --git a/openai-agents-sdk/README.md b/openai-agents-sdk/README.md index 16c9547..ae6a522 100644 --- a/openai-agents-sdk/README.md +++ b/openai-agents-sdk/README.md @@ -1,6 +1,9 @@ # Team Agent for Slack (Bolt for Python and OpenAI Agents SDK) -A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) using models from [OpenAI](https://openai.com). It keeps your team's runbooks current as threads wrap up and helps route the requests that come in. Runbooks are Slack canvases that the agent reads and writes through the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). +A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) using models from [OpenAI](https://openai.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). + +> [!WARNING] +> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. ## App Overview @@ -276,6 +279,8 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. +> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. + ### Using the App @@ -324,7 +329,7 @@ Every incoming request is routed to a "listener". This directory groups each lis - `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. - `app_mentioned.py` — Responds to @mentions in channels. -- `message.py` — Responds to direct messages and learns from channel messages by connected users. +- `message.py` — Responds to direct messages and learns from channel messages. **`/listeners/actions`** — Handles interactive components: diff --git a/openai-agents-sdk/listeners/views/app_home_builder.py b/openai-agents-sdk/listeners/views/app_home_builder.py index 7b69f7e..629d843 100644 --- a/openai-agents-sdk/listeners/views/app_home_builder.py +++ b/openai-agents-sdk/listeners/views/app_home_builder.py @@ -23,8 +23,8 @@ def build_app_home_view( "type": "mrkdwn", "text": ( "I keep your team's runbooks current and help route requests.\n\n" - "*Invite me to your team channel* and I'll add what your threads " - "figure out to runbooks as they wrap up. *Mention me* or *send me a " + "*Invite me to your team channel* and I'll add what your messages " + "settle to runbooks. *Mention me* or *send me a " "direct message* to find a runbook or triage a request." ), }, diff --git a/pydantic-ai/README.md b/pydantic-ai/README.md index 92ea7f2..a2d3bf3 100644 --- a/pydantic-ai/README.md +++ b/pydantic-ai/README.md @@ -1,6 +1,9 @@ # Team Agent for Slack (Bolt for Python and Pydantic AI) -A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [Pydantic AI](https://ai.pydantic.dev/) using models from [Anthropic](https://anthropic.com) or [OpenAI](https://openai.com). It keeps your team's runbooks current as threads wrap up and helps route the requests that come in. Runbooks are Slack canvases that the agent reads and writes through the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). +A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [Pydantic AI](https://ai.pydantic.dev/) using models from [Anthropic](https://anthropic.com) or [OpenAI](https://openai.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). + +> [!WARNING] +> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. ## App Overview @@ -290,6 +293,8 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. +> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. + ### Using the App @@ -338,7 +343,7 @@ Every incoming request is routed to a "listener". This directory groups each lis - `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. - `app_mentioned.py` — Responds to @mentions in channels. -- `message.py` — Responds to direct messages and learns from channel messages by connected users. +- `message.py` — Responds to direct messages and learns from channel messages. **`/listeners/actions`** — Handles interactive components: diff --git a/pydantic-ai/listeners/views/app_home_builder.py b/pydantic-ai/listeners/views/app_home_builder.py index f0dc4c7..7320ed0 100644 --- a/pydantic-ai/listeners/views/app_home_builder.py +++ b/pydantic-ai/listeners/views/app_home_builder.py @@ -23,8 +23,8 @@ def build_app_home_view( "type": "mrkdwn", "text": ( "I keep your team's runbooks current and help route requests.\n\n" - "*Invite me to your team channel* and I'll add what your threads " - "figure out to runbooks as they wrap up. *Mention me* or *send me a " + "*Invite me to your team channel* and I'll add what your messages " + "settle to runbooks. *Mention me* or *send me a " "direct message* to find a runbook or triage a request." ), }, From 3a0aa66c193cabee4426823cdbcf6188cc167394 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 29 Oct 2026 21:29:00 -0700 Subject: [PATCH 2/4] docs: drop the .env note from the OAuth sections Co-Authored-By: Claude --- claude-agent-sdk/README.md | 2 -- openai-agents-sdk/README.md | 2 -- pydantic-ai/README.md | 2 -- 3 files changed, 6 deletions(-) diff --git a/claude-agent-sdk/README.md b/claude-agent-sdk/README.md index 6a00f37..8060bf0 100644 --- a/claude-agent-sdk/README.md +++ b/claude-agent-sdk/README.md @@ -279,8 +279,6 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. -> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. - ### Using the App diff --git a/openai-agents-sdk/README.md b/openai-agents-sdk/README.md index ae6a522..643b221 100644 --- a/openai-agents-sdk/README.md +++ b/openai-agents-sdk/README.md @@ -279,8 +279,6 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. -> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. - ### Using the App diff --git a/pydantic-ai/README.md b/pydantic-ai/README.md index a2d3bf3..0f18606 100644 --- a/pydantic-ai/README.md +++ b/pydantic-ai/README.md @@ -293,8 +293,6 @@ python3 app_oauth.py > **Note:** Each time ngrok restarts, it generates a new URL. You'll need to update the ngrok domain in `manifest.json`, `SLACK_REDIRECT_URI` in your `.env`, and re-install the app. -> **Note:** To go back to Socket Mode with `slack run`, comment out `SLACK_CLIENT_ID` and `SLACK_CLIENT_SECRET` in `.env` first. Bolt turns on OAuth whenever both are set, and `app.py` then ignores `SLACK_BOT_TOKEN`. - ### Using the App From f250ce8753a94f2b115ec04b1ee0d99550fe1d07 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 29 Oct 2026 21:29:15 -0700 Subject: [PATCH 3/4] docs: drop the crafted-message warning for now Co-Authored-By: Claude --- README.md | 3 --- claude-agent-sdk/README.md | 3 --- openai-agents-sdk/README.md | 3 --- pydantic-ai/README.md | 3 --- 4 files changed, 12 deletions(-) diff --git a/README.md b/README.md index 0565103..0774d7b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,6 @@ A sample Slack agent built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) that keeps your team's runbooks current and helps route the requests that come in. Runbooks are Slack canvases titled `Runbook: `. The agent answers from them, and it learns from the messages in your team's channels, so the runbooks it writes are the ones it answers from next time. -> [!WARNING] -> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to the framework README for how the Slack MCP Server is connected. - ## Choose Your Framework This repo contains the same app built with three different AI agent frameworks. Pick the one that fits your stack: diff --git a/claude-agent-sdk/README.md b/claude-agent-sdk/README.md index 8060bf0..bbe20a8 100644 --- a/claude-agent-sdk/README.md +++ b/claude-agent-sdk/README.md @@ -2,9 +2,6 @@ A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) using models from [Anthropic](https://www.anthropic.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). -> [!WARNING] -> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. - ## App Overview The team agent interacts with users through five entry points: diff --git a/openai-agents-sdk/README.md b/openai-agents-sdk/README.md index 643b221..159fe8e 100644 --- a/openai-agents-sdk/README.md +++ b/openai-agents-sdk/README.md @@ -2,9 +2,6 @@ A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) using models from [OpenAI](https://openai.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). -> [!WARNING] -> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. - ## App Overview The team agent interacts with users through five entry points: diff --git a/pydantic-ai/README.md b/pydantic-ai/README.md index 0f18606..856e764 100644 --- a/pydantic-ai/README.md +++ b/pydantic-ai/README.md @@ -2,9 +2,6 @@ A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and [Pydantic AI](https://ai.pydantic.dev/) using models from [Anthropic](https://anthropic.com) or [OpenAI](https://openai.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). -> [!WARNING] -> **This agent reads every message in the channels it's a member of and acts on what they settle.** With the Slack MCP Server connected, a crafted message could steer it into searching the author's DMs and private channels, or into editing any canvas they can open. Only add it to channels you trust, and refer to [Slack MCP Server](#slack-mcp-server) for how it's connected. - ## App Overview The team agent interacts with users through five entry points: From 58eadbc526dabd82df3bb39b7279f133385d5806 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 29 Oct 2026 21:49:02 -0700 Subject: [PATCH 4/4] docs: match the README wording to the JS team agent exactly Co-Authored-By: Claude --- claude-agent-sdk/README.md | 6 +++--- openai-agents-sdk/README.md | 2 +- pydantic-ai/README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/claude-agent-sdk/README.md b/claude-agent-sdk/README.md index bbe20a8..0f42c2b 100644 --- a/claude-agent-sdk/README.md +++ b/claude-agent-sdk/README.md @@ -1,6 +1,6 @@ # Team Agent for Slack (Bolt for Python and Claude Agent SDK) -A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) using models from [Anthropic](https://www.anthropic.com). It keeps your team's runbooks current from what channel messages settle and helps route the requests that come in. Runbooks are Slack canvases the agent reads and writes with the bot token, or as a person who has connected the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server). +A team agent template built with [Bolt for Python](https://docs.slack.dev/tools/bolt-python/) and the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) using models from [Anthropic](https://www.anthropic.com). It keeps your team's runbooks current by learning from channel messages, and helps route the requests that come in. Runbooks are Slack canvases that the agent reads and writes with the bot token, or through the [Slack MCP Server](https://github.com/slackapi/slack-mcp-server) for people who connect it. ## App Overview @@ -24,7 +24,7 @@ Runbooks are Slack canvases titled `Runbook: `. Each one holds how the te This is the loop the template is built to show: the runbooks the agent writes from messages are the runbooks it answers from next time. -When the agent changes a runbook, it tells the message's author with an ephemeral message only they can see. Nothing is posted to the channel. New runbooks are added as a tab in the channel they were learned in, so the whole team can read and edit them. The agent only gets runbook tools, so it can't send messages or read threads. +When the agent changes a runbook, it tells the message's author with an ephemeral message only they can see. Nothing is posted to the channel. New runbooks are added as a tab in the channel they were learned in, so the whole team can read and edit them. The agent is only allowed runbook tools, so it can't send messages or read threads. ### Slack MCP Server @@ -322,7 +322,7 @@ Every incoming request is routed to a "listener". This directory groups each lis **`/listeners/events`** — Handles incoming events: -- `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. +- `app_home_opened.py` — Publishes the App Home view, or pins suggested prompts to the agent DM Messages tab (branches on `event["tab"]`). - `app_mentioned.py` — Responds to @mentions in channels. - `message.py` — Responds to direct messages and learns from channel messages. diff --git a/openai-agents-sdk/README.md b/openai-agents-sdk/README.md index 159fe8e..0413c46 100644 --- a/openai-agents-sdk/README.md +++ b/openai-agents-sdk/README.md @@ -322,7 +322,7 @@ Every incoming request is routed to a "listener". This directory groups each lis **`/listeners/events`** — Handles incoming events: -- `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. +- `app_home_opened.py` — Publishes the App Home view, or pins suggested prompts to the agent DM Messages tab (branches on `event["tab"]`). - `app_mentioned.py` — Responds to @mentions in channels. - `message.py` — Responds to direct messages and learns from channel messages. diff --git a/pydantic-ai/README.md b/pydantic-ai/README.md index 856e764..c3d21ec 100644 --- a/pydantic-ai/README.md +++ b/pydantic-ai/README.md @@ -336,7 +336,7 @@ Every incoming request is routed to a "listener". This directory groups each lis **`/listeners/events`** — Handles incoming events: -- `app_home_opened.py` — Publishes the App Home view with a welcome message and MCP status. +- `app_home_opened.py` — Publishes the App Home view, or pins suggested prompts to the agent DM Messages tab (branches on `event["tab"]`). - `app_mentioned.py` — Responds to @mentions in channels. - `message.py` — Responds to direct messages and learns from channel messages.