@joe-broadhead/opencode-slack 0.0.0-stage → 0.0.1
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 +29 -0
- package/LICENSE +21 -0
- package/README.md +204 -2
- package/dist/index.js +646 -0
- package/dist/tui.js +335 -0
- package/package.json +253 -4
- package/skills/slack-search/SKILL.md +79 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
## [0.0.1] - 2026-11-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- A `jelly` section in `package.json`: each tool with its permission, its default effect and whether it only reads, the skill ids. Jelly reads it without loading the plugin and applies the declared asks, because its agents have no base allow rule for this plugin's own default rules to follow. `docs/jelly.md` explains it.
|
|
10
|
+
- `title` and `signIns` in the `jelly` section: the name Jelly shows on the plugin's card, and what the plugin signs in to, so that one card can say whether each sign-in is connected and start, renew or end it. `docs/jelly.md` lists them.
|
|
11
|
+
- Hosted callbacks, so sign-in works when OpenCode runs on another machine ([#1](https://github.com/joe-broadhead/opencode-slack/issues/1)): `oauth.redirect_uri` also accepts an `https:` URL with a path and no credentials, query or fragment, together with the new `oauth.callback_port`, the port of OpenCode's local callback listener, which a reverse proxy forwards the address to. The server config then carries `callback_port`, and status shows the port in `callbackPort` and its `Callback` row. `oauth.callback_port` is refused with a loopback redirect, whose own port is the listener's. The docs explain how to add a hosted address to the Slack app's Redirect URLs, and how two sign-ins on one machine avoid colliding on port 8765.
|
|
12
|
+
- `presetBy` on the `jelly.signIns` Slack app step: with `oauth.client_id` set in the plugin options, the step is done, so Jelly asks nobody to paste a client ID.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- The `oauth.redirect_uri` errors say which rule an `http:` URL broke, and their next step names both a loopback and a hosted example. The `Callback` status row says to register the URL in the app's Redirect URLs.
|
|
17
|
+
|
|
18
|
+
## [0.0.0] - 2026-11-01
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Slack's hosted MCP server, `https://mcp.slack.com/mcp`, registered as the MCP server `slack` with your Slack app's OAuth client. OpenCode signs in with PKCE and refreshes the token.
|
|
23
|
+
- Sign-in from `/connect`: **Slack app** stores the app's client ID (and an optional client secret) in OpenCode's credential store, and **Slack** signs in. A change to the stored client applies without a restart.
|
|
24
|
+
- Options: `oauth.client_id` (pins the client, for example in an organisation's managed config), `oauth.redirect_uri` (default `http://localhost:8765/callback`), `oauth.scopes` (default `channels:history channels:read search:read.public users:read`), `oauth.client_secret` through `{env:NAME}`, `server` and `allowUntestedHost`.
|
|
25
|
+
- Default permissions: the known read tools run without asking. Private search, file reads, writes (messages, drafts, schedules, reactions, canvases, lists, new conversations and file uploads) and unknown tools ask. Your `permissions` rules and "Always allow" answers override them.
|
|
26
|
+
- `/slack-status`, the TUI dialog **Slack: Status** (`/slack`) and the status RPC, sharing one status model: the state, an error code, the client and its source, the tools by class, the agents without the default rules, the host check and one next step.
|
|
27
|
+
- A host check: on an OpenCode version outside `>=2.2.3 <2.3.0`, only the status surfaces are registered unless `allowUntestedHost` is `true`.
|
|
28
|
+
- The `slack-search` skill: search with `keywords` and `natural_language_query`, read for context, cite permalinks, and treat Slack content as untrusted.
|
|
29
|
+
- A Slack app manifest, `docs/slack-app-manifest.json`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joe Broadhead
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,205 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Slack for OpenCode
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An [OpenCode](https://opencode.ai) plugin that connects Slack's hosted MCP server, so OpenCode agents can search and read Slack for you.
|
|
4
|
+
|
|
5
|
+
Unofficial; not affiliated with Slack. Slack is a trademark of Slack Technologies, LLC, a Salesforce company.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- OpenCode `>=2.2.3 <2.3.0`, tested on 2.2.3 and 2.2.4; macOS and Linux.
|
|
10
|
+
- A Slack app that your organisation owns, with Slack's MCP server turned on. Slack lets only internal apps and Slack Marketplace apps use its MCP server. If your organisation has none, someone who can create apps in your workspace makes one from the [app manifest](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/slack-app-manifest.json): see [Create the Slack app](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md#create-the-slack-app).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
opencode plugin add @joe-broadhead/opencode-slack
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Sign in
|
|
19
|
+
|
|
20
|
+
1. **Give OpenCode your Slack app's client ID.** Run `/connect` and choose **Slack app**. Skip the client secret (an app made from the manifest uses PKCE and has none; OpenCode shows that field unmasked). When OpenCode asks for the key, paste the client ID from the app's **Basic Information → App Credentials** page. The client ID is public. From a terminal, `opencode auth login slack-app` does the same.
|
|
21
|
+
|
|
22
|
+
If your organisation already set the client ID for you (see [Organisation rollout](#organisation-rollout)), there is no **Slack app** entry; go straight to step 2.
|
|
23
|
+
2. **Sign in to Slack.** Run `/connect` and choose **Slack**. In the TUI, press `o` or Enter to open the sign-in page in your browser. In a terminal, `opencode mcp auth slack` opens the browser automatically. `/mcps` → `slack` is an equivalent way in.
|
|
24
|
+
3. Slack shows the workspace, the account and what the app asks for. Approve it. Slack sends the browser back to the callback, `http://localhost:8765/callback` unless you set another, and OpenCode finishes the sign-in.
|
|
25
|
+
|
|
26
|
+
`/slack-status` now shows `connected` and the Slack tools it found. OpenCode stores the credential and refreshes it. To sign out, run `opencode mcp logout slack`.
|
|
27
|
+
|
|
28
|
+
## Use
|
|
29
|
+
|
|
30
|
+
Ask in plain words, for example "find what we decided about the launch date in #release, with links". The `slack-search` skill guides the agent: search public channels first, read the thread for context, cite permalinks, never claim it searched everything, and treat Slack content as data, not instructions.
|
|
31
|
+
|
|
32
|
+
The Slack tools are Slack's own. With Code Mode, which is on by default, agents call them as `tools.slack.<tool>` inside `execute`, for example `tools.slack.slack_search_public({ natural_language_query: "When is the launch?", keywords: ["launch"] })`. Their names and permission actions are `slack_<tool>`, for example `slack_slack_search_public`.
|
|
33
|
+
|
|
34
|
+
**Status.** In the TUI, `/slack` (or **Slack: Status** in the command palette) opens a dialog. Press `r` to refresh and `Esc` to close; it also refreshes when the connection, agents or saved client change. If it shows 0 tools just after connecting, press `r`. `/slack-status` posts the same status into the session without starting a model turn. Status shows these rows, in order:
|
|
35
|
+
|
|
36
|
+
- `Connection`: `connected`, `sign-in required`, `connecting`, `disabled`, `failed`, `not configured`, `conflict` or `host untested`, with the error code and what happened;
|
|
37
|
+
- `Account`: Slack shows the account on its sign-in page; OpenCode does not store it;
|
|
38
|
+
- `Access`: what runs without asking, what asks first, and how to allow it;
|
|
39
|
+
- `Server`, `Client`, `Callback` and `Scopes`: the Slack server, the client ID and where it came from, the callback URL to register, and the requested scopes;
|
|
40
|
+
- `Tools`: the Slack tools found, counted by class, with any unknown tools named;
|
|
41
|
+
- `Agents without default rules`: agents that run Slack tools without asking, with the rules to paste (see [Agents without the default rules](#agents-without-the-default-rules));
|
|
42
|
+
- `OpenCode`: the version and the tested range;
|
|
43
|
+
- `Next step`: exactly one, or `Nothing to do.`
|
|
44
|
+
|
|
45
|
+
## Permissions
|
|
46
|
+
|
|
47
|
+
**What runs without asking:** the known read tools: `slack_search_public`, `slack_search_channels`, `slack_search_users`, `slack_read_channel`, `slack_read_thread`, `slack_read_user_profile`, `slack_read_canvas`, `slack_list_channel_members`, `slack_get_reactions`, `slack_list_user_channels`, `slack_read_list` and `slack_search_emojis`.
|
|
48
|
+
|
|
49
|
+
**What asks first:**
|
|
50
|
+
|
|
51
|
+
- private search: `slack_search_public_and_private`;
|
|
52
|
+
- file reads: `slack_read_file`;
|
|
53
|
+
- writes: sending, drafting and scheduling messages, adding reactions, creating and updating canvases and lists, creating conversations, and file uploads;
|
|
54
|
+
- any Slack tool the plugin does not know yet.
|
|
55
|
+
|
|
56
|
+
The plugin adds these defaults as rules right after each agent's base `allow` rule. OpenCode uses the last matching rule, so these all override the defaults:
|
|
57
|
+
|
|
58
|
+
- the agent's own built-in rules: Explore, Title and Summary still deny Slack, and Plan keeps its limits;
|
|
59
|
+
- your `permissions`;
|
|
60
|
+
- your "Always allow" answers.
|
|
61
|
+
|
|
62
|
+
**Allow** a tool that asks: choose **Always allow** when OpenCode asks, or add a rule to `permissions`:
|
|
63
|
+
|
|
64
|
+
```jsonc
|
|
65
|
+
"permissions": [
|
|
66
|
+
{ "action": "slack_slack_read_file", "resource": "*", "effect": "allow" }
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
"Always allow" applies to every agent in the current project, Plan included.
|
|
71
|
+
|
|
72
|
+
**Deny** a tool with `"effect": "deny"`. A deny always wins, even over "Always allow", and it hides the tool from the model. `{ "action": "slack_*", "resource": "*", "effect": "deny" }` denies every Slack tool.
|
|
73
|
+
|
|
74
|
+
The `slack_*` rule also matches tools of any other MCP server whose name starts with `slack_`, so those tools ask too.
|
|
75
|
+
|
|
76
|
+
### Agents without the default rules
|
|
77
|
+
|
|
78
|
+
OpenCode creates some agents after the plugin adds its rules, so they get none: agents defined only in your config (`agents.<id>` entries that are not built-in agents, and Markdown agent files), and agents added by plugins that load after this one. These agents run Slack writes and unknown Slack tools **without asking**. Status names them in its `Agents without default rules` row and prints the rules to paste.
|
|
79
|
+
|
|
80
|
+
**Fix:** put the plugin's default block in **that agent's own** `permissions`: the `slack_*` ask rule, then one allow rule per read tool. After the block, repeat any rules you already have for Slack tools in your top-level `permissions`, so they keep winning for that agent:
|
|
81
|
+
|
|
82
|
+
```jsonc
|
|
83
|
+
"agents": {
|
|
84
|
+
"reviewer": {
|
|
85
|
+
"permissions": [
|
|
86
|
+
{ "action": "slack_*", "resource": "*", "effect": "ask" },
|
|
87
|
+
{ "action": "slack_slack_search_public", "resource": "*", "effect": "allow" },
|
|
88
|
+
{ "action": "slack_slack_search_channels", "resource": "*", "effect": "allow" },
|
|
89
|
+
{ "action": "slack_slack_search_users", "resource": "*", "effect": "allow" },
|
|
90
|
+
{ "action": "slack_slack_read_channel", "resource": "*", "effect": "allow" },
|
|
91
|
+
{ "action": "slack_slack_read_thread", "resource": "*", "effect": "allow" },
|
|
92
|
+
{ "action": "slack_slack_read_user_profile", "resource": "*", "effect": "allow" },
|
|
93
|
+
{ "action": "slack_slack_read_canvas", "resource": "*", "effect": "allow" },
|
|
94
|
+
{ "action": "slack_slack_list_channel_members", "resource": "*", "effect": "allow" },
|
|
95
|
+
{ "action": "slack_slack_get_reactions", "resource": "*", "effect": "allow" },
|
|
96
|
+
{ "action": "slack_slack_list_user_channels", "resource": "*", "effect": "allow" },
|
|
97
|
+
{ "action": "slack_slack_read_list", "resource": "*", "effect": "allow" },
|
|
98
|
+
{ "action": "slack_slack_search_emojis", "resource": "*", "effect": "allow" }
|
|
99
|
+
// then your top-level Slack rules again, if you have any
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Do not put this block in the top-level `permissions`. OpenCode adds top-level rules to every agent after its built-in rules, so the block would loosen agents that deny Slack, such as Explore.
|
|
106
|
+
|
|
107
|
+
## Configure
|
|
108
|
+
|
|
109
|
+
Everything works without options. Options set the client ID for everyone (instead of `/connect`), the callback URL and its local port, the scopes, a client secret for apps without PKCE, the server name and the host check. To pass them, use the object form of the `plugins` entry:
|
|
110
|
+
|
|
111
|
+
```jsonc
|
|
112
|
+
{
|
|
113
|
+
"plugins": [
|
|
114
|
+
{ "package": "@joe-broadhead/opencode-slack", "options": { "oauth": { "scopes": ["channels:history", "channels:read", "search:read.public", "users:read", "search:read.private"] } } }
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**OpenCode on another machine.** The default callback, `http://localhost:8765/callback`, works only when the browser runs on OpenCode's machine. Otherwise use a hosted callback: an `https:` address the browser can reach, which a reverse proxy forwards to OpenCode's local listener on `oauth.callback_port`:
|
|
120
|
+
|
|
121
|
+
```jsonc
|
|
122
|
+
"oauth": { "client_id": "YOUR_SLACK_CLIENT_ID", "redirect_uri": "https://host.example/oauth/return", "callback_port": 8766 }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Add the address to the Slack app's **OAuth & Permissions → Redirect URLs** (or `oauth_config.redirect_urls` in the [manifest](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/slack-app-manifest.json)). Slack matches the host and port exactly. [The callback: loopback or hosted](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md#the-callback-loopback-or-hosted) explains the proxy and how two sign-ins on one machine avoid colliding on port 8765.
|
|
126
|
+
|
|
127
|
+
[docs/configuration.md](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md) lists every option, the scopes each tool needs, the permission rules and the status model.
|
|
128
|
+
|
|
129
|
+
## Organisation rollout
|
|
130
|
+
|
|
131
|
+
Put the client ID of your organisation's Slack app in the system configuration, so members have nothing to set up: they see no **Slack app** entry and only run `/connect` and choose **Slack** to sign in. OpenCode reads the system configuration from `/Library/Application Support/opencode/opencode.json` on macOS (or the `ai.opencode.managed` managed-preferences domain) and from `/etc/opencode/opencode.json` on Linux:
|
|
132
|
+
|
|
133
|
+
```jsonc
|
|
134
|
+
{
|
|
135
|
+
"$schema": "https://opencode.ai/config.json",
|
|
136
|
+
"plugins": [
|
|
137
|
+
{
|
|
138
|
+
"package": "@joe-broadhead/opencode-slack",
|
|
139
|
+
"options": {
|
|
140
|
+
"oauth": { "client_id": "YOUR_SLACK_CLIENT_ID" }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Replace `YOUR_SLACK_CLIENT_ID` with the app's client ID. Options take precedence over a client ID saved in `/connect`. Plugin lists from different config files are combined.
|
|
148
|
+
|
|
149
|
+
## Troubleshooting
|
|
150
|
+
|
|
151
|
+
Run `/slack-status` (or `/slack` in the TUI) first. Its `Connection` row shows a state and, when something is wrong, a code; the last row is one next step. [Errors](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md#errors) lists every code.
|
|
152
|
+
|
|
153
|
+
| Connection | Code | Meaning | What to do |
|
|
154
|
+
| --- | --- | --- | --- |
|
|
155
|
+
| `not configured` | `CLIENT_ID_MISSING` | No Slack app client ID is set, so the Slack server is not added. | Run `/connect` and choose **Slack app**, then paste your Slack app's client ID. |
|
|
156
|
+
| `not configured` | `CLIENT_ID_INVALID` | The client ID saved in the `/connect` **Slack app** entry is empty or has spaces. | Run `/connect` and choose **Slack app**, then paste the client ID again. |
|
|
157
|
+
| `sign-in required` | `AUTH_REQUIRED` | Nobody has signed in yet, or the sign-in expired. | Run `/connect` and choose **Slack**, then press `o` or Enter to open the sign-in page. `opencode mcp auth slack` opens the browser automatically. |
|
|
158
|
+
| `connecting` | none | OpenCode is connecting to Slack. | Wait a few seconds, then refresh. |
|
|
159
|
+
| `disabled` | `SERVER_DISABLED` | The server is turned off. | Turn on `slack` in `/mcps`. |
|
|
160
|
+
| `failed` | `CONNECTION_FAILED` | The connection failed. Status includes OpenCode's error text. | Fix the error shown, then reconnect `slack` in `/mcps`. |
|
|
161
|
+
| `conflict` | `SERVER_NAME_IN_USE` | Another MCP server already uses the name `slack`. | Remove `mcp.servers.slack` from your config, or set the `server` option to another name. |
|
|
162
|
+
| `failed` | none | OpenCode has not loaded the server. | Run `opencode reload`, then check again. |
|
|
163
|
+
| `not configured` | `OPTIONS_INVALID` | An option is invalid. Status names the field. | Follow the next step. |
|
|
164
|
+
| `host untested` | `HOST_UNTESTED` | This OpenCode version is outside `>=2.2.3 <2.3.0`, so Slack is not set up. | Use OpenCode `>=2.2.3 <2.3.0`, or set `"allowUntestedHost": true` in the plugin's options. |
|
|
165
|
+
| `connected` | none | Ready. The next step reads `Nothing to do.` | If status names agents without default rules, put the default rules first in their own permissions (see above). |
|
|
166
|
+
|
|
167
|
+
If status itself cannot be read, `/slack-status` says `STATUS_UNAVAILABLE`; run it again in a moment.
|
|
168
|
+
|
|
169
|
+
**Slack shows an error during sign-in**
|
|
170
|
+
|
|
171
|
+
- **`bad_redirect_uri`, or "redirect_uri did not match":** the app does not list the callback URL exactly. Add the `Callback` URL that status shows under **OAuth & Permissions → Redirect URLs**.
|
|
172
|
+
- **`invalid_team_for_non_distributed_app`:** the app belongs to another workspace. Use the client ID of your own organisation's app.
|
|
173
|
+
- **Slack asks you to request approval:** your workspace requires admin approval for apps or scopes. Ask an admin to approve the app, then sign in again.
|
|
174
|
+
- **Slack refuses the app for MCP:** turn on **Agents → Slack Model Context Protocol (MCP) Server** in the app settings. The app must be internal to your organisation or published in the Slack Marketplace.
|
|
175
|
+
- **The browser cannot open `localhost:8765` after Slack approves:** OpenCode listens for the callback on `127.0.0.1` only. If your browser tries IPv6 for `localhost`, replace `localhost` with `127.0.0.1` in the address bar. To avoid it, register `http://127.0.0.1:8765/callback` in the app and set it as `oauth.redirect_uri`.
|
|
176
|
+
- **The browser cannot open `localhost:8765` because OpenCode runs on another machine:** the browser's `localhost` is not OpenCode's. Use a [hosted callback](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md#the-callback-loopback-or-hosted).
|
|
177
|
+
- **Sign-in fails because the callback port is in use:** another sign-in on this machine is waiting on port 8765. Finish it first, or give this OpenCode its own callback, such as `http://localhost:8767/callback`, registered in the Slack app too.
|
|
178
|
+
|
|
179
|
+
**A Slack tool fails**
|
|
180
|
+
|
|
181
|
+
- **Missing scope (`missing_scope`):** add the scope to the app and to `oauth.scopes`, then run `opencode mcp logout slack` and sign in again. See the [scope table](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md#scopes).
|
|
182
|
+
- **Rate limited:** Slack limits each tool separately. Wait, then make fewer calls.
|
|
183
|
+
- **You declined a prompt:** nothing was sent. In Code Mode, the decline appears to the agent as an error inside its program.
|
|
184
|
+
|
|
185
|
+
**Asked to sign in again after about 30 days.** Slack expires the refresh tokens it issues to PKCE apps after 30 days. Run `/connect` and choose **Slack** again, then press `o` or Enter.
|
|
186
|
+
|
|
187
|
+
**After you change the Slack app or workspace,** run `opencode mcp logout slack`, then sign in again. OpenCode keys the Slack sign-in by server name and URL, not by client ID, so it would otherwise keep the old app's token.
|
|
188
|
+
|
|
189
|
+
## Uninstall
|
|
190
|
+
|
|
191
|
+
1. Run `opencode plugin remove @joe-broadhead/opencode-slack`.
|
|
192
|
+
2. Sign out of Slack: `opencode mcp logout slack`.
|
|
193
|
+
3. If you saved a client ID, remove the **Slack app** entry: in `/connect`, choose **Slack app** and delete the account, or run `opencode auth logout slack-app`.
|
|
194
|
+
4. Remove any Slack rules you copied into your agents' own `permissions`.
|
|
195
|
+
|
|
196
|
+
## Links
|
|
197
|
+
|
|
198
|
+
- [Configuration](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/configuration.md)
|
|
199
|
+
- [Slack app manifest](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/docs/slack-app-manifest.json)
|
|
200
|
+
- [Security and data flow](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/SECURITY.md)
|
|
201
|
+
- [Contributing](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/CONTRIBUTING.md)
|
|
202
|
+
- [Changelog](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/CHANGELOG.md)
|
|
203
|
+
- [Issues](https://github.com/joe-broadhead/opencode-slack/issues)
|
|
204
|
+
- [Slack MCP server documentation](https://docs.slack.dev/ai/slack-mcp-server)
|
|
205
|
+
- License: [MIT](https://github.com/joe-broadhead/opencode-slack/blob/HEAD/LICENSE)
|