claude-threads 1.18.1 β 1.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +78 -57
- package/dist/index.js +11 -44
- package/docs/CONFIGURATION.md +98 -13
- package/docs/MCP-TOOLS.md +107 -0
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.18.2] - 2026-07-17
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **New visual identity: the thread-spine mark.** The β΄-star ASCII logo (a leftover of the Claude Code Christmas logo) is replaced everywhere by a mark of our own: heavy box-drawing CT letters with a light thread gutter showing a root node, a reply branch, and a closing arc. Applied consistently to the terminal header, the favicon, a rebuilt pure-vector `logo.svg` with no font dependency, the README, and the website. (#431)
|
|
12
|
+
- **README overhaul.** Screenshots for both platforms directly under the pitch, a How it works section, a table of all nine MCP tools with their guardrails (seven were previously undocumented), and a command table synced with the registry. Corrected copy along the way: multi-account selection is usage-balanced since 1.18.0 (the README still said round-robin), the resume reaction is π (the documented β©οΈ was never accepted), and the `send_dm` guardrail is approved from the session thread, not by the recipient. Cross-file links are now absolute so they no longer break on the npm package page, and the configuration link points at `docs/CONFIGURATION.md` instead of the internal `CLAUDE.md`. (#431)
|
|
13
|
+
- **Docs sync.** `docs/CONFIGURATION.md` audited against the real config schema: the `limits` block, `threadLogs`, sticky text customization, permission modes, `outboundFiles`, usage-balanced accounts, and the env var list. New `docs/MCP-TOOLS.md` documents every MCP tool with inputs and guardrails. `SETUP_GUIDE.md` drops stale version pins and deprecated permission vocabulary; `CONTRIBUTING.md` gains dev commands and a pointer to the platform implementation guide. (#431)
|
|
14
|
+
- **Website redesign: the page is a thread.** claude-threads.run rebuilt on the same terminal identity with the thread as its structure: a rail runs down the content and every section attaches to it as a reply, the last one closing the arc. Content synced with 1.18 (MCP tools table, full command list, a Mattermost showcase section), OpenGraph/Twitter cards with a generated social image, and the Node prerequisite corrected from 18+ to 20+. (#432)
|
|
15
|
+
- **npm metadata.** The package description finally mentions Slack, keywords gain `slack`, `chatops`, `pair-programming`, and `collaboration`, and the homepage points at claude-threads.run. Takes effect with this release. (#431)
|
|
16
|
+
|
|
8
17
|
## [1.18.1] - 2026-07-17
|
|
9
18
|
|
|
10
19
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Claude Threads
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/anneschuth/claude-threads/main/website/assets/logo.svg" alt="claude-threads logo: a chat-thread spine next to the letters CT" width="200">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center"><sub>Claude Code Γ Slack & Mattermost</sub></p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://claude-threads.run"><strong>claude-threads.run</strong></a>
|
|
@@ -18,28 +18,64 @@
|
|
|
18
18
|
[](https://nodejs.org/)
|
|
19
19
|
[](https://github.com/anneschuth/claude-threads/pulls)
|
|
20
20
|
|
|
21
|
-
**
|
|
21
|
+
**Run Claude Code from your team's chat.** The bot lives on your machine, next to your checkout and your local tools. Sessions stream live into Slack or Mattermost threads where teammates watch and steer what Claude does. No cloud sandbox and no enterprise plan required: it works with the Claude subscription or API key you already have.
|
|
22
22
|
|
|
23
23
|
> _Think of it as screen-sharing for AI pair programming, but everyone can type._
|
|
24
24
|
|
|
25
|
+
<table>
|
|
26
|
+
<tr>
|
|
27
|
+
<td width="50%" valign="top"><img src="https://raw.githubusercontent.com/anneschuth/claude-threads/main/website/assets/screenshots/slack-thread.png" alt="A Claude Code session streaming into a Slack thread, with session header badges and live tool output"></td>
|
|
28
|
+
<td width="50%" valign="top"><img src="https://raw.githubusercontent.com/anneschuth/claude-threads/main/website/assets/screenshots/mattermost-thread.png" alt="The same bot in a Mattermost thread, showing the session header table and Claude's reply"></td>
|
|
29
|
+
</tr>
|
|
30
|
+
<tr>
|
|
31
|
+
<td align="center"><sub>Slack</sub></td>
|
|
32
|
+
<td align="center"><sub>Mattermost</sub></td>
|
|
33
|
+
</tr>
|
|
34
|
+
</table>
|
|
35
|
+
|
|
36
|
+
## How it works
|
|
37
|
+
|
|
38
|
+
1. Mention the bot in a channel: `@claude fix the flaky test in ci.yml`
|
|
39
|
+
2. It spawns a real Claude Code session in a working directory on your machine.
|
|
40
|
+
3. Everything streams into the thread: output, diffs, task lists, permission prompts.
|
|
41
|
+
4. Steer by replying in the thread or reacting with emoji. Anyone you invite can do the same.
|
|
42
|
+
|
|
25
43
|
## Features
|
|
26
44
|
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
45
|
+
- **Live streaming** - Responses, tool calls, diffs, and a sticky task list render in the thread as the session runs
|
|
46
|
+
- **Slack and Mattermost** - Connect multiple workspaces at once. Mattermost support means this also works where chat is self-hosted and cloud assistants cannot go
|
|
47
|
+
- **A session per thread** - Concurrent sessions, each with its own working directory, resumed automatically after a bot restart
|
|
48
|
+
- **Your machine, your setup** - Sessions use your local checkout plus whatever MCP servers and plugins you already configured
|
|
49
|
+
- **Your existing subscription** - Any Claude Pro/Max account or API key works. An optional multi-account pool routes each new session to the account with the most subscription headroom and cools down rate-limited ones ([docs](https://github.com/anneschuth/claude-threads/blob/main/docs/CONFIGURATION.md#claude-accounts-optional-multi-account-mode))
|
|
50
|
+
- **Permission control by emoji** - `default` prompts the thread for every tool use (π/β
/π), `auto` lets Claude's classifier approve low-risk actions, `bypass` skips prompts entirely. Switch per session with `!permissions`
|
|
51
|
+
- **Collaboration** - `!invite` teammates into a session; commits Claude makes get `Co-Authored-By:` trailers for everyone involved
|
|
52
|
+
- **A real chat citizen** - Nine MCP tools let Claude post files, follow permalinks, react, and DM, each behind its own guardrail (see [What Claude can do in your chat](#what-claude-can-do-in-your-chat))
|
|
53
|
+
- **Git worktrees** - `!worktree feature/foo` isolates Claude's changes on a branch
|
|
54
|
+
- **Files both ways** - Drop any file into the chat for Claude to read, with full multimodal for images and PDFs; Claude posts screenshots, plots, or PDFs back with `send_file` (100 MB cap)
|
|
55
|
+
- **Quiet mode and verbosity dials** - `!mentions on` makes a session respond only when mentioned; session headers and the channel sticky each have `full`/`minimal`/`hidden` modes
|
|
56
|
+
- **Runs on macOS, Linux, and Windows** - Windows via Git Bash or WSL
|
|
57
|
+
- **Auto-update** - The bot watches npm for new versions; `!update now` applies one from chat
|
|
58
|
+
|
|
59
|
+
## What Claude can do in your chat
|
|
60
|
+
|
|
61
|
+
Each session runs its own MCP server, giving Claude tools that act on the chat platform. Every tool carries its own guardrail; nothing reaches beyond the channels the bot can already see.
|
|
62
|
+
|
|
63
|
+
| Tool | What Claude does with it | Guardrail |
|
|
64
|
+
| :--------------------- | :---------------------------------------------------- | :------------------------------------------------------------ |
|
|
65
|
+
| `send_file` | Post a file from the working directory into the thread | Path validated against the session working directory |
|
|
66
|
+
| `read_post` | Resolve a Slack or Mattermost permalink to its content | Bot's channel plus public channels only |
|
|
67
|
+
| `list_thread` | Read the current thread, or a permalinked one | Same channel scoping |
|
|
68
|
+
| `read_channel_history` | Read recent messages from a channel | Bot's channel plus public channels, capped at 100 messages |
|
|
69
|
+
| `search_messages` | Search messages | Mattermost only, capped at 25 results |
|
|
70
|
+
| `react_to_post` | Add an emoji reaction | Defaults to the message that triggered it |
|
|
71
|
+
| `update_own_post` | Edit one of its earlier posts | Bot-authored posts only |
|
|
72
|
+
| `send_dm` | Send a direct message to a channel member | 3 per recipient per session; the thread approves each one |
|
|
73
|
+
| `permission_prompt` | Ask the thread to approve a tool use | This one _is_ the approval flow (π/β
/π) |
|
|
74
|
+
|
|
75
|
+
The full reference, including inputs and scoping rules, is in [docs/MCP-TOOLS.md](https://github.com/anneschuth/claude-threads/blob/main/docs/MCP-TOOLS.md).
|
|
38
76
|
|
|
39
77
|
## Quick Start
|
|
40
78
|
|
|
41
|
-
### Install & Run
|
|
42
|
-
|
|
43
79
|
```bash
|
|
44
80
|
# Install (pick one)
|
|
45
81
|
bun install -g claude-threads # with Bun (recommended)
|
|
@@ -50,23 +86,14 @@ cd /your/project
|
|
|
50
86
|
claude-threads
|
|
51
87
|
```
|
|
52
88
|
|
|
53
|
-
The
|
|
89
|
+
The interactive wizard configures your Slack or Mattermost bot, tests the credentials, and gets you running in minutes. For creating the bot account itself, follow the [Setup Guide](https://github.com/anneschuth/claude-threads/blob/main/SETUP_GUIDE.md).
|
|
54
90
|
|
|
55
|
-
|
|
56
|
-
- Set up your Mattermost or Slack bot
|
|
57
|
-
- Test credentials and permissions
|
|
58
|
-
- Get you up and running in minutes
|
|
59
|
-
|
|
60
|
-
**Need help with platform setup?** See the [Setup Guide](SETUP_GUIDE.md) for Mattermost or Slack bot creation.
|
|
61
|
-
|
|
62
|
-
### Prerequisites
|
|
91
|
+
**Prerequisites**
|
|
63
92
|
|
|
64
93
|
- **Bun 1.2.21+** or **Node 20+** - [Install Bun](https://bun.sh/) or [Install Node](https://nodejs.org/)
|
|
65
|
-
- **Claude Code CLI
|
|
66
|
-
|
|
67
|
-
### Use
|
|
94
|
+
- **Claude Code CLI** - test with `claude --version` (needs a subscription or API key)
|
|
68
95
|
|
|
69
|
-
|
|
96
|
+
Then mention the bot in your channel:
|
|
70
97
|
|
|
71
98
|
```
|
|
72
99
|
@claude help me fix the bug in src/auth.ts
|
|
@@ -93,33 +120,28 @@ Type `!help` in any session thread:
|
|
|
93
120
|
| `!github-email <email>` | Register your GitHub noreply email so `!invite` can attribute commits to you |
|
|
94
121
|
| `!update` | Show auto-update status (`!update now` / `!update defer`) |
|
|
95
122
|
| `!bug <desc>` | Report a bug with context (creates a GitHub issue) |
|
|
96
|
-
| `!approve` | Approve pending plan (alternative to
|
|
97
|
-
| `!escape` | Interrupt current task
|
|
98
|
-
| `!stop` | Stop this session
|
|
123
|
+
| `!approve` | Approve pending plan (alternative to π; also `!yes`) |
|
|
124
|
+
| `!escape` | Interrupt current task, session stays active (also `!interrupt`) |
|
|
125
|
+
| `!stop` | Stop this session (also `!cancel`) |
|
|
99
126
|
| `!kill` | Emergency shutdown (kills ALL sessions and exits the bot) |
|
|
100
127
|
|
|
128
|
+
Unknown `!commands` are checked against Claude Code's own slash commands and passed through when they match.
|
|
129
|
+
|
|
101
130
|
## Interactive Controls
|
|
102
131
|
|
|
103
|
-
**Permission approval** - When Claude wants to
|
|
132
|
+
**Permission approval** - When Claude wants to run a tool:
|
|
104
133
|
|
|
105
134
|
- π Allow this action
|
|
106
135
|
- β
Allow all future actions
|
|
107
136
|
- π Deny
|
|
108
137
|
|
|
109
|
-
**Plan approval** - When Claude
|
|
110
|
-
|
|
111
|
-
- π Approve and start
|
|
112
|
-
- π Request changes
|
|
138
|
+
**Plan approval** - When Claude presents a plan: π approve, π request changes
|
|
113
139
|
|
|
114
140
|
**Questions** - React with 1οΈβ£ 2οΈβ£ 3οΈβ£ 4οΈβ£ to answer multiple choice
|
|
115
141
|
|
|
116
|
-
**Session control** - βΈοΈ
|
|
142
|
+
**Session control** - βΈοΈ interrupt, β or π stop, π resume a timed-out session
|
|
117
143
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
Drop any file into the chat (image, PDF, archive, source, log, you name it). The bot saves it to a per-thread directory and prepends the path to your message; Claude reads it with its own `Read` tool (full multimodal for images and PDFs) or processes it via Bash. Single 100 MB cap per file. Need to extract a zip? Claude runs `unzip` itself.
|
|
121
|
-
|
|
122
|
-
Going the other way, Claude can post files back into the thread (screenshots, generated PDFs, plots, MP3s) by calling the `send_file` MCP tool. Path is validated against the session working directory; auto-approved so the user doesn't have to π every screenshot.
|
|
144
|
+
**Housekeeping** - π½ collapses long task lists and subagent output; π on an error post opens a bug report
|
|
123
145
|
|
|
124
146
|
## Collaboration
|
|
125
147
|
|
|
@@ -128,13 +150,9 @@ Going the other way, Claude can post files back into the thread (screenshots, ge
|
|
|
128
150
|
!kick @colleague # Remove access
|
|
129
151
|
```
|
|
130
152
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Invited collaborators are added as `Co-Authored-By:` trailers on any commits Claude makes during the session. Each collaborator runs `!github-email <their-noreply-address>` once (find yours at <https://github.com/settings/emails>) and the bot remembers it across sessions.
|
|
134
|
-
|
|
135
|
-
## Sharing Links With Claude
|
|
153
|
+
Messages from users outside the session can be approved one at a time by the session owner with a π reaction.
|
|
136
154
|
|
|
137
|
-
|
|
155
|
+
Invited collaborators end up as `Co-Authored-By:` trailers on commits Claude makes during the session. Each collaborator runs `!github-email <their-noreply-address>` once (find yours at <https://github.com/settings/emails>) and the bot remembers it across sessions.
|
|
138
156
|
|
|
139
157
|
## Git Worktrees
|
|
140
158
|
|
|
@@ -148,14 +166,17 @@ Or mid-session: `!worktree feature/add-auth`
|
|
|
148
166
|
|
|
149
167
|
## Access Control
|
|
150
168
|
|
|
151
|
-
Restrict who can use the bot during setup
|
|
169
|
+
Restrict who can use the bot during setup, or reconfigure later with `claude-threads --setup`. An empty allowlist lets anyone in the channel start sessions, so leave it empty only in channels you trust.
|
|
152
170
|
|
|
153
|
-
|
|
171
|
+
Who may do what (start sessions, react to permission prompts, approve guest messages) is written down in the [authorization model](https://github.com/anneschuth/claude-threads/blob/main/SECURITY.md).
|
|
154
172
|
|
|
155
173
|
## Documentation
|
|
156
174
|
|
|
157
|
-
- **[Setup Guide](SETUP_GUIDE.md)** -
|
|
158
|
-
- **[Configuration Reference](
|
|
175
|
+
- **[Setup Guide](https://github.com/anneschuth/claude-threads/blob/main/SETUP_GUIDE.md)** - Creating the bot account on Mattermost or Slack, step by step
|
|
176
|
+
- **[Configuration Reference](https://github.com/anneschuth/claude-threads/blob/main/docs/CONFIGURATION.md)** - Every `config.yaml` option, environment variables, CLI flags
|
|
177
|
+
- **[MCP Tools Reference](https://github.com/anneschuth/claude-threads/blob/main/docs/MCP-TOOLS.md)** - The nine tools Claude gets in chat, with their guardrails
|
|
178
|
+
- **[Security Model](https://github.com/anneschuth/claude-threads/blob/main/SECURITY.md)** - Authorization matrix and vulnerability reporting
|
|
179
|
+
- **[Changelog](https://github.com/anneschuth/claude-threads/blob/main/CHANGELOG.md)** - Detailed release history
|
|
159
180
|
|
|
160
181
|
## Updates
|
|
161
182
|
|
|
@@ -163,7 +184,7 @@ Leave the allowed users list empty to let anyone in the channel use the bot (be
|
|
|
163
184
|
npm install -g claude-threads
|
|
164
185
|
```
|
|
165
186
|
|
|
166
|
-
The bot checks for
|
|
187
|
+
The bot checks npm for new versions on its own and offers the update in chat.
|
|
167
188
|
|
|
168
189
|
## License
|
|
169
190
|
|
package/dist/index.js
CHANGED
|
@@ -76335,22 +76335,12 @@ function Header({ version, workingDir, claudeVersion }) {
|
|
|
76335
76335
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76336
76336
|
children: [
|
|
76337
76337
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76338
|
-
color: "
|
|
76339
|
-
children: "
|
|
76340
|
-
}, undefined, false, undefined, this),
|
|
76341
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76342
|
-
children: " "
|
|
76338
|
+
color: "gray",
|
|
76339
|
+
children: "ββ "
|
|
76343
76340
|
}, undefined, false, undefined, this),
|
|
76344
76341
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76345
76342
|
color: "blue",
|
|
76346
|
-
children: "
|
|
76347
|
-
}, undefined, false, undefined, this),
|
|
76348
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76349
|
-
children: " "
|
|
76350
|
-
}, undefined, false, undefined, this),
|
|
76351
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76352
|
-
color: "yellow",
|
|
76353
|
-
children: "β΄"
|
|
76343
|
+
children: "ββ ββ³β"
|
|
76354
76344
|
}, undefined, false, undefined, this),
|
|
76355
76345
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76356
76346
|
children: " "
|
|
@@ -76371,25 +76361,15 @@ function Header({ version, workingDir, claudeVersion }) {
|
|
|
76371
76361
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76372
76362
|
children: [
|
|
76373
76363
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76374
|
-
color: "
|
|
76375
|
-
children: "
|
|
76376
|
-
}, undefined, false, undefined, this),
|
|
76377
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76378
|
-
children: " "
|
|
76364
|
+
color: "gray",
|
|
76365
|
+
children: "ββ "
|
|
76379
76366
|
}, undefined, false, undefined, this),
|
|
76380
76367
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76381
76368
|
color: "blue",
|
|
76382
|
-
children: "
|
|
76383
|
-
}, undefined, false, undefined, this),
|
|
76384
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76385
|
-
children: " "
|
|
76369
|
+
children: "β β"
|
|
76386
76370
|
}, undefined, false, undefined, this),
|
|
76387
76371
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76388
|
-
|
|
76389
|
-
children: "β΄"
|
|
76390
|
-
}, undefined, false, undefined, this),
|
|
76391
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76392
|
-
children: " "
|
|
76372
|
+
children: " "
|
|
76393
76373
|
}, undefined, false, undefined, this),
|
|
76394
76374
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76395
76375
|
dimColor: true,
|
|
@@ -76400,28 +76380,15 @@ function Header({ version, workingDir, claudeVersion }) {
|
|
|
76400
76380
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76401
76381
|
children: [
|
|
76402
76382
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76403
|
-
|
|
76404
|
-
|
|
76405
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76406
|
-
color: "yellow",
|
|
76407
|
-
children: "β΄"
|
|
76408
|
-
}, undefined, false, undefined, this),
|
|
76409
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76410
|
-
children: " "
|
|
76383
|
+
color: "gray",
|
|
76384
|
+
children: "β°β "
|
|
76411
76385
|
}, undefined, false, undefined, this),
|
|
76412
76386
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76413
76387
|
color: "blue",
|
|
76414
|
-
children: "
|
|
76415
|
-
}, undefined, false, undefined, this),
|
|
76416
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76417
|
-
children: " "
|
|
76388
|
+
children: "ββ βΉ"
|
|
76418
76389
|
}, undefined, false, undefined, this),
|
|
76419
76390
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76420
|
-
|
|
76421
|
-
children: "β΄"
|
|
76422
|
-
}, undefined, false, undefined, this),
|
|
76423
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76424
|
-
children: " "
|
|
76391
|
+
children: " "
|
|
76425
76392
|
}, undefined, false, undefined, this),
|
|
76426
76393
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
76427
76394
|
color: "cyan",
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -21,7 +21,7 @@ platforms:
|
|
|
21
21
|
channelId: abc123
|
|
22
22
|
botName: claude-code
|
|
23
23
|
allowedUsers: [alice, bob]
|
|
24
|
-
|
|
24
|
+
permissionMode: default
|
|
25
25
|
|
|
26
26
|
# Slack
|
|
27
27
|
- id: slack-eng
|
|
@@ -32,17 +32,80 @@ platforms:
|
|
|
32
32
|
channelId: C0123456789
|
|
33
33
|
botName: claude
|
|
34
34
|
allowedUsers: [alice, bob]
|
|
35
|
-
|
|
35
|
+
permissionMode: default
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Global Settings
|
|
39
39
|
|
|
40
40
|
| Setting | Description | Default |
|
|
41
41
|
|---------|-------------|---------|
|
|
42
|
+
| `version` | Config schema version | `1` |
|
|
42
43
|
| `workingDir` | Default working directory for Claude | Current directory |
|
|
43
44
|
| `chrome` | Enable Chrome integration | `false` |
|
|
44
45
|
| `worktreeMode` | Git worktree mode: `off`, `prompt`, or `require` | `prompt` |
|
|
45
46
|
| `respondOnlyWhenMentioned` | Start new threads in quiet mode, where the bot only replies to messages that @mention it. Users can still toggle per-thread with `!mentions`. | `false` |
|
|
47
|
+
| `keepAlive` | Prevent system sleep while sessions are active | `true` |
|
|
48
|
+
| `limits` | Resource limits and timeouts (see below) | see below |
|
|
49
|
+
| `threadLogs` | Thread logging (see below) | enabled |
|
|
50
|
+
| `stickyMessage` | Sticky message text customization (see below) | none |
|
|
51
|
+
| `claudeAccounts` | Multi-account pool (see below) | single-account mode |
|
|
52
|
+
|
|
53
|
+
### Resource Limits (`limits`)
|
|
54
|
+
|
|
55
|
+
Every field is optional and falls back to the default. Older `config.yaml` files predate most of these, so leaving the block out is fine.
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
limits:
|
|
59
|
+
maxSessions: 5
|
|
60
|
+
sessionTimeoutMinutes: 30
|
|
61
|
+
sessionWarningMinutes: 5
|
|
62
|
+
cleanupIntervalMinutes: 60
|
|
63
|
+
maxWorktreeAgeHours: 24
|
|
64
|
+
cleanupWorktrees: true
|
|
65
|
+
permissionTimeoutSeconds: 120
|
|
66
|
+
flushDelayMs: 500
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Setting | Description | Default |
|
|
70
|
+
|---------|-------------|---------|
|
|
71
|
+
| `maxSessions` | Maximum concurrent sessions | `5` |
|
|
72
|
+
| `sessionTimeoutMinutes` | Idle timeout before a session auto-terminates | `30` |
|
|
73
|
+
| `sessionWarningMinutes` | Warn the user this many minutes before timeout | `5` |
|
|
74
|
+
| `cleanupIntervalMinutes` | How often the background cleanup runs | `60` |
|
|
75
|
+
| `maxWorktreeAgeHours` | Clean up orphaned worktrees older than this | `24` |
|
|
76
|
+
| `cleanupWorktrees` | Enable automatic cleanup of orphaned worktrees | `true` |
|
|
77
|
+
| `permissionTimeoutSeconds` | How long a permission prompt waits for a reaction | `120` |
|
|
78
|
+
| `flushDelayMs` | Delay before flushing batched output to the platform. Lower is snappier with more API calls; higher posts less often with coarser streaming. | `500` |
|
|
79
|
+
|
|
80
|
+
The legacy env vars `MAX_SESSIONS` and `SESSION_TIMEOUT_MS` still work as fallbacks when `limits.maxSessions` / `limits.sessionTimeoutMinutes` are unset. See [Environment Variables](#environment-variables).
|
|
81
|
+
|
|
82
|
+
### Thread Logs (`threadLogs`)
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
threadLogs:
|
|
86
|
+
enabled: true
|
|
87
|
+
retentionDays: 30
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Setting | Description | Default |
|
|
91
|
+
|---------|-------------|---------|
|
|
92
|
+
| `enabled` | Write per-thread session logs to disk | `true` |
|
|
93
|
+
| `retentionDays` | Delete logs this many days after a session ends | `30` |
|
|
94
|
+
|
|
95
|
+
### Sticky Message Text (`stickyMessage`)
|
|
96
|
+
|
|
97
|
+
Customize the text of the channel sticky message. This is distinct from the per-platform `stickyMessage: <mode>` visibility field documented under [Platform Settings](#platform-settings).
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
stickyMessage:
|
|
101
|
+
description: "Porygon β Mixpanel analytics bot"
|
|
102
|
+
footer: "β’ !stop β End session\nβ’ !help β Show help"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Setting | Description | Default |
|
|
106
|
+
|---------|-------------|---------|
|
|
107
|
+
| `description` | Line shown below the sticky title | none |
|
|
108
|
+
| `footer` | Content shown before the default "Mention me to start a session" line | none |
|
|
46
109
|
|
|
47
110
|
## Platform Settings
|
|
48
111
|
|
|
@@ -58,7 +121,9 @@ platforms:
|
|
|
58
121
|
| `channelId` | Yes | Channel to listen in |
|
|
59
122
|
| `botName` | No | Mention name (default: `claude-code`) |
|
|
60
123
|
| `allowedUsers` | No | List of usernames who can use the bot |
|
|
61
|
-
| `
|
|
124
|
+
| `permissionMode` | No | How tool-use is gated: `default` / `auto` / `bypass` (default: `default`). See [Permission Modes](#permission-modes). |
|
|
125
|
+
| `skipPermissions` | No | **Deprecated.** Use `permissionMode`. `true` maps to `bypass`, `false` to `default`. `permissionMode` wins when both are set. |
|
|
126
|
+
| `outboundFiles` | No | `send_file` settings: `{ enabled, maxBytes }` (defaults: enabled `true`, `maxBytes` 100 MB) |
|
|
62
127
|
| `sessionHeader` | No | Per-thread header visibility: `full` (default) / `minimal` (status bar only) / `hidden` (no header post) |
|
|
63
128
|
| `stickyMessage` | No | Channel sticky visibility: `full` (default) / `minimal` (status bar only) / `hidden` (no sticky, no bumping) |
|
|
64
129
|
|
|
@@ -74,10 +139,24 @@ platforms:
|
|
|
74
139
|
| `channelId` | Yes | Channel ID (e.g., `C0123456789`) |
|
|
75
140
|
| `botName` | No | Mention name (default: `claude`) |
|
|
76
141
|
| `allowedUsers` | No | List of Slack usernames |
|
|
77
|
-
| `
|
|
142
|
+
| `permissionMode` | No | How tool-use is gated: `default` / `auto` / `bypass` (default: `default`). See [Permission Modes](#permission-modes). |
|
|
143
|
+
| `skipPermissions` | No | **Deprecated.** Use `permissionMode`. `true` maps to `bypass`, `false` to `default`. `permissionMode` wins when both are set. |
|
|
144
|
+
| `outboundFiles` | No | `send_file` settings: `{ enabled, maxBytes }` (defaults: enabled `true`, `maxBytes` 100 MB) |
|
|
78
145
|
| `sessionHeader` | No | Per-thread header visibility: `full` (default) / `minimal` (status bar only) / `hidden` (no header post) |
|
|
79
146
|
| `stickyMessage` | No | Channel sticky visibility: `full` (default) / `minimal` (status bar only) / `hidden` (no sticky, no bumping) |
|
|
80
147
|
|
|
148
|
+
### Permission Modes
|
|
149
|
+
|
|
150
|
+
The `permissionMode` field controls how the bot handles a session's tool-use requests.
|
|
151
|
+
|
|
152
|
+
| Mode | Behavior |
|
|
153
|
+
|------|----------|
|
|
154
|
+
| `default` | Every tool-use prompts for approval. The bot posts a permission request in the thread and the user reacts π (allow once) / β
(allow all) / π (deny). Safest option. |
|
|
155
|
+
| `auto` | Claude's built-in classifier decides per tool: low-risk actions are auto-approved, high-risk ones still prompt. Requires Claude CLI 2.1.x. |
|
|
156
|
+
| `bypass` | No prompts and no classifier. Every tool-use is allowed. Equivalent to `--dangerously-skip-permissions`. This is what the legacy `skipPermissions: true` maps to. |
|
|
157
|
+
|
|
158
|
+
A running session can switch mode at any time with `!permissions <mode>`; that override is not persisted across a bot restart.
|
|
159
|
+
|
|
81
160
|
### Quieting the bot's overhead messages
|
|
82
161
|
|
|
83
162
|
Both the per-thread session header and the channel sticky message default to `full` for backward compatibility. To strip them down on a noisy channel, set the per-platform fields in `config.yaml`:
|
|
@@ -87,7 +166,7 @@ platforms:
|
|
|
87
166
|
- id: mattermost-main
|
|
88
167
|
type: mattermost
|
|
89
168
|
# ... credentials ...
|
|
90
|
-
sessionHeader: hidden # no header post
|
|
169
|
+
sessionHeader: hidden # no header post, Claude's reply is the first message in the thread
|
|
91
170
|
stickyMessage: minimal # one-line status bar at the channel bottom, no sessions list
|
|
92
171
|
```
|
|
93
172
|
|
|
@@ -95,11 +174,13 @@ Note: the per-platform `stickyMessage: <mode>` field is distinct from the top-le
|
|
|
95
174
|
|
|
96
175
|
## Claude Accounts (optional, multi-account mode)
|
|
97
176
|
|
|
98
|
-
By default every session spawns `claude` with the bot's own `process.env`, so they all share one subscription's token budget. Add a `claudeAccounts` block to spread load across multiple accounts
|
|
177
|
+
By default every session spawns `claude` with the bot's own `process.env`, so they all share one subscription's token budget. Add a `claudeAccounts` block to spread load across multiple accounts. Omit the block entirely to stay in single-account mode (unchanged behavior).
|
|
178
|
+
|
|
179
|
+
Selection is usage-balanced (since v1.18.0). At each new-session start the bot probes every account's live limits with `claude -p "/usage" --output-format json` under that account's `HOME` (costs nothing, uses no turns) and routes the session to the account with the most subscription headroom, meaning the lowest `max(session%, week%)`. Round-robin is only the fallback when probing yields no usable numbers (for example an API-key account, which reports no percentages). Accounts in rate-limit cooldown are skipped until their reset time. A resumed session always re-binds to the account its history lives under, cooling or not.
|
|
99
180
|
|
|
100
181
|
```yaml
|
|
101
182
|
claudeAccounts:
|
|
102
|
-
# OAuth accounts
|
|
183
|
+
# OAuth accounts (prepare each HOME first with `HOME=<path> claude login`)
|
|
103
184
|
- id: primary
|
|
104
185
|
home: /home/bot/.claude-accounts/primary
|
|
105
186
|
- id: backup
|
|
@@ -124,11 +205,14 @@ Exactly one of `home` or `apiKey` should be set per account. Persisted sessions
|
|
|
124
205
|
|
|
125
206
|
| Variable | Description | Default |
|
|
126
207
|
|----------|-------------|---------|
|
|
127
|
-
| `MAX_SESSIONS` | Max concurrent sessions | `5` |
|
|
128
|
-
| `SESSION_TIMEOUT_MS` | Idle timeout in milliseconds | `1800000` (30 min) |
|
|
129
|
-
| `NO_UPDATE_NOTIFIER` | Disable update checks | - |
|
|
208
|
+
| `MAX_SESSIONS` | Max concurrent sessions. Legacy fallback for `limits.maxSessions`. | `5` |
|
|
209
|
+
| `SESSION_TIMEOUT_MS` | Idle timeout in milliseconds. Legacy fallback for `limits.sessionTimeoutMinutes`. | `1800000` (30 min) |
|
|
130
210
|
| `DEBUG` | Enable verbose logging | - |
|
|
131
|
-
| `
|
|
211
|
+
| `CLAUDE_PATH` | Path to the `claude` binary. Overrides the PATH lookup and the common install locations. | `claude` (from PATH) |
|
|
212
|
+
| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Strip `ANTHROPIC_*`, `AWS_*_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, `GOOGLE_APPLICATION_CREDENTIALS`, and similar from Bash, hook, and stdio-MCP subprocesses Claude spawns. Bot-specific vars like `PLATFORM_TOKEN` pass through. **Also forces permission mode to `default`**; `--dangerously-skip-permissions` will be rejected. Requires Claude CLI 2.1.83+. | - |
|
|
213
|
+
| `CLAUDE_THREADS_SESSIONS_PATH` | Override the path to the persisted sessions file (default `~/.config/claude-threads/sessions.json`). | - |
|
|
214
|
+
| `CLAUDE_THREADS_GITHUB_EMAILS_PATH` | Override the path to the GitHub-emails store used for commit attribution. | - |
|
|
215
|
+
| `NO_UPDATE_NOTIFIER` | Disable update checks | - |
|
|
132
216
|
|
|
133
217
|
### Forwarded to Claude CLI automatically
|
|
134
218
|
|
|
@@ -155,8 +239,9 @@ Options:
|
|
|
155
239
|
--channel <id> Channel ID
|
|
156
240
|
--bot-name <name> Bot mention name (default: claude-code)
|
|
157
241
|
--allowed-users <list> Comma-separated allowed usernames
|
|
158
|
-
--
|
|
159
|
-
--
|
|
242
|
+
--permission-mode <mode> Permission mode: default | auto | bypass
|
|
243
|
+
--skip-permissions [deprecated] Alias for --permission-mode bypass
|
|
244
|
+
--no-skip-permissions [deprecated] Alias for --permission-mode default
|
|
160
245
|
--chrome Enable Chrome integration
|
|
161
246
|
--no-chrome Disable Chrome integration
|
|
162
247
|
--worktree-mode <mode> Git worktree mode: off, prompt, require
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# MCP Tools Reference
|
|
2
|
+
|
|
3
|
+
Every session spawns its own MCP server alongside the Claude CLI process (via `--mcp-config`). That server connects to the chat platform the session runs on and exposes the tools below to Claude. All of them are namespaced `mcp__claude-threads-mcp__<tool>`.
|
|
4
|
+
|
|
5
|
+
`permission_prompt` is special: the Claude CLI calls it as the permission handler for other tool use, so it drives the π / β
/ π reaction flow in the thread. Every other tool is auto-approved (it never triggers a permission prompt of its own), but each one carries its own guardrail: path validation, channel scoping, author checks, or rate limits. Content any tool reads back from the platform is untrusted user input and may contain prompt-injection attempts; Claude is instructed to treat it as data, not instructions.
|
|
6
|
+
|
|
7
|
+
Each tool returns a JSON result: `{ ok: true, ... }` on success or `{ ok: false, reason }` on failure.
|
|
8
|
+
|
|
9
|
+
## permission_prompt
|
|
10
|
+
|
|
11
|
+
The permission handler the Claude CLI calls before running a tool that needs approval. It posts a permission request into the session thread ("β οΈ Permission requested: Write `file.txt`"), adds the π / β
/ π reaction options, and waits for an authorized user to react. The reaction decides the outcome: π allows once, β
allows all further uses of that tool, π denies.
|
|
12
|
+
|
|
13
|
+
| Input | Type | Description |
|
|
14
|
+
|-------|------|-------------|
|
|
15
|
+
| `tool_name` | string | Name of the tool requesting permission. |
|
|
16
|
+
| `input` | object | The tool's input parameters, shown to the user in the prompt. |
|
|
17
|
+
|
|
18
|
+
**Guardrail:** Only reactions from users on the session allowlist count. The bot's own reactions (the option emoji it adds) are ignored. If no reaction arrives within `limits.permissionTimeoutSeconds` (default 120), the request is denied.
|
|
19
|
+
|
|
20
|
+
## send_file
|
|
21
|
+
|
|
22
|
+
Uploads a file from the session working directory into the thread. Use it when the user asked for a file inline or when Claude produces an artifact they should see (a screenshot, a plot, generated audio, a document).
|
|
23
|
+
|
|
24
|
+
| Input | Type | Description |
|
|
25
|
+
|-------|------|-------------|
|
|
26
|
+
| `path` | string | Absolute path of a file inside the session working directory. |
|
|
27
|
+
| `caption` | string (optional) | Message body shown alongside the file. |
|
|
28
|
+
|
|
29
|
+
**Guardrail:** The path is validated to be absolute and inside the session working directory; anything outside is rejected. Uploads are capped at `outboundFiles.maxBytes` (default 100 MB), and the tool errors out when `outboundFiles.enabled` is `false`.
|
|
30
|
+
|
|
31
|
+
## read_post
|
|
32
|
+
|
|
33
|
+
Resolves a chat permalink to the content of that post. Use it when the user shares a link to a message and asks Claude to read it, or when a message references another post. Set `include_thread` to also pull the surrounding thread.
|
|
34
|
+
|
|
35
|
+
| Input | Type | Description |
|
|
36
|
+
|-------|------|-------------|
|
|
37
|
+
| `url` | string | Permalink to a post, on the same host as the bot. |
|
|
38
|
+
| `include_thread` | boolean (optional) | Also fetch surrounding thread messages, oldest first. Default `false`. |
|
|
39
|
+
| `max_messages` | integer (optional) | Thread messages to return when `include_thread` is true. Default 20, capped at 50. |
|
|
40
|
+
|
|
41
|
+
**Guardrail:** The URL must be on the bot's own host. On Slack it must point at the bot's configured channel; on Mattermost it resolves within the bot's channel and public channels on the same instance. Returned content is untrusted.
|
|
42
|
+
|
|
43
|
+
## react_to_post
|
|
44
|
+
|
|
45
|
+
Adds an emoji reaction to a post. Use it to acknowledge a request (β
), flag something ambiguous (π), or mark a triggering message as handled. Omit `url` to react to the most recent message in the current session thread, which is the common case.
|
|
46
|
+
|
|
47
|
+
| Input | Type | Description |
|
|
48
|
+
|-------|------|-------------|
|
|
49
|
+
| `url` | string (optional) | Permalink to the target post. Omit to react to the latest message in the current thread. |
|
|
50
|
+
| `emoji` | string | Emoji name without colons, for example `white_check_mark`, `+1`, `eyes`. |
|
|
51
|
+
|
|
52
|
+
**Guardrail:** The target post must be in the bot's own channel or a public channel on the same instance.
|
|
53
|
+
|
|
54
|
+
## update_own_post
|
|
55
|
+
|
|
56
|
+
Edits a post the bot itself authored, given its permalink. Useful for posting a "working on it..." placeholder and rewriting it once the answer is ready.
|
|
57
|
+
|
|
58
|
+
| Input | Type | Description |
|
|
59
|
+
|-------|------|-------------|
|
|
60
|
+
| `url` | string | Permalink to a post the bot authored. |
|
|
61
|
+
| `message` | string | New body. Replaces the existing post text in full. |
|
|
62
|
+
|
|
63
|
+
**Guardrail:** Restricted to bot-authored posts. Editing a post written by anyone else is rejected.
|
|
64
|
+
|
|
65
|
+
## list_thread
|
|
66
|
+
|
|
67
|
+
Reads the messages in a chat thread. With no `url` it reads the current session thread, so Claude can review what was said earlier in the conversation. With a `url` it reads the thread containing that post.
|
|
68
|
+
|
|
69
|
+
| Input | Type | Description |
|
|
70
|
+
|-------|------|-------------|
|
|
71
|
+
| `url` | string (optional) | Permalink to any post in the target thread. Omit to read the current session thread. |
|
|
72
|
+
| `max_messages` | integer (optional) | Messages to return, oldest first. Default 20, capped at 50. |
|
|
73
|
+
|
|
74
|
+
**Guardrail:** A supplied `url` must resolve to the bot's channel or a public channel on the same instance. Returned content is untrusted.
|
|
75
|
+
|
|
76
|
+
## read_channel_history
|
|
77
|
+
|
|
78
|
+
Reads recent messages from a channel by id. Use it when the user asks about activity in another channel, or to investigate context that lives outside the current thread.
|
|
79
|
+
|
|
80
|
+
| Input | Type | Description |
|
|
81
|
+
|-------|------|-------------|
|
|
82
|
+
| `channel_id` | string | Channel identifier. Mattermost: the 26-char channel id. Slack: the channel id (`Cβ¦` / `Gβ¦`). |
|
|
83
|
+
| `max_messages` | integer (optional) | Messages to return, oldest first. Default 20, capped at 100. |
|
|
84
|
+
|
|
85
|
+
**Guardrail:** The channel must be the bot's own channel or a public channel on the same instance. On Slack the bot must also be a member. Returned content is untrusted.
|
|
86
|
+
|
|
87
|
+
## search_messages
|
|
88
|
+
|
|
89
|
+
Searches messages on the platform. **Mattermost only**; on Slack it returns an unsupported error.
|
|
90
|
+
|
|
91
|
+
| Input | Type | Description |
|
|
92
|
+
|-------|------|-------------|
|
|
93
|
+
| `query` | string | Search query. Mattermost supports phrase quoting and `from:user` filters. |
|
|
94
|
+
| `max_results` | integer (optional) | Results to return. Default 10, capped at 25. |
|
|
95
|
+
|
|
96
|
+
**Guardrail:** Results are filtered to in-scope channels only, meaning the bot's own channel plus public channels on the same instance. Returned content is untrusted.
|
|
97
|
+
|
|
98
|
+
## send_dm
|
|
99
|
+
|
|
100
|
+
Sends a direct message to a member of the bot's channel. Use it when the user asks to ping someone privately, for example a status update or a result they want delivered as a DM. The bot prepends an attribution line so the recipient can see the DM came from a session and who started it.
|
|
101
|
+
|
|
102
|
+
| Input | Type | Description |
|
|
103
|
+
|-------|------|-------------|
|
|
104
|
+
| `recipient` | string | Recipient identifier. Mattermost: a username (with or without a leading `@`). Slack: a user ID (`U0123ABC` or `<@U0123ABC>`). |
|
|
105
|
+
| `message` | string | Message body. The bot prepends an attribution prefix. |
|
|
106
|
+
|
|
107
|
+
**Guardrail:** The recipient must be a current member of the bot channel. The first DM to each recipient in a session triggers a permission prompt in the bot channel; a β
allow-all promotes that specific recipient to no-prompt for the rest of the session. A hard limit of 3 DMs per recipient per session applies.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-threads",
|
|
3
|
-
"version": "1.18.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.18.2",
|
|
4
|
+
"description": "Run Claude Code from Slack or Mattermost. Sessions stream live into threads where your whole team can watch and steer.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -35,12 +35,16 @@
|
|
|
35
35
|
"keywords": [
|
|
36
36
|
"claude",
|
|
37
37
|
"claude-code",
|
|
38
|
+
"slack",
|
|
38
39
|
"mattermost",
|
|
39
40
|
"bot",
|
|
40
41
|
"ai",
|
|
41
42
|
"cli",
|
|
42
43
|
"anthropic",
|
|
43
44
|
"chat",
|
|
45
|
+
"chatops",
|
|
46
|
+
"pair-programming",
|
|
47
|
+
"collaboration",
|
|
44
48
|
"bun"
|
|
45
49
|
],
|
|
46
50
|
"author": "Anne Schuth",
|
|
@@ -52,7 +56,7 @@
|
|
|
52
56
|
"bugs": {
|
|
53
57
|
"url": "https://github.com/anneschuth/claude-threads/issues"
|
|
54
58
|
},
|
|
55
|
-
"homepage": "https://
|
|
59
|
+
"homepage": "https://claude-threads.run",
|
|
56
60
|
"files": [
|
|
57
61
|
"dist",
|
|
58
62
|
"bin",
|