$ lanes link connect slack --profile personal --workspace localA browser opens, you approve, and that is the whole of it. There is no Slack app to create, no scope list to transcribe, and no token to copy.
You will see the browser flick through api.lanes.sh on the way back. Slack refuses to register a
callback that is not HTTPS, and a command line cannot be HTTPS, so it returns you there and that
page immediately redirects down to the command waiting on your machine. Nothing is stored on the
way through.
What it will ask for
connect prints the scopes before the browser opens, and stops if you do not agree to them. These
are Slack user-token scopes: Slack's MCP server reads the user token, and a bot token is a
different credential that does not work here at all.
| Scope | What it means |
|---|---|
search:read.public, search:read.users, search:read.files | Search public channels, people, files |
search:read.private, search:read.im, search:read.mpim | Search private channels and DMs |
channels:history, channels:read | Read and list public channels |
groups:history, groups:read | Read and list private channels |
im:history, mpim:history, mpim:read | Read direct and group direct messages |
users:read | Read people and profiles |
files:read | Read files and their contents |
chat:write | Send messages as you |
reactions:write | Add and remove reactions as you |
canvases:read, canvases:write | Read and edit canvases |
channels:write | Create and manage public channels |
Seven of those are flagged broad and need an explicit yes: the four that reach private
conversations, the two that search them, and chat:write. Slack draws no line between reading a
conversation and reading a private one, so a scope that reads like routine access is usually the
most sensitive thing in the workspace.
Granting a scope is not the same as letting an agent use it. connect grants the read bundle and
nothing else, and lanes link policy is where the rest is turned on.
If your workspace has not approved the Lanes app
An Enterprise Grid admin decides that, and you may not be able to change it. Use a token from an app your workspace already trusts:
$ lanes link connect slack --profile personal --workspace local --auth pasted_token- Open https://api.slack.com/apps and choose Create New App, then From scratch. Name it and pick the workspace.
- Open OAuth & Permissions and add the scopes you need under User Token Scopes, not Bot Token Scopes. The table above is the full set. A smaller set works, and the tools whose scope is missing fail when they are called rather than being hidden.
- Choose Install to Workspace and approve. An admin may have to approve it for you.
- Copy the User OAuth Token. It starts with
xoxp-. The bot token starts withxoxb-and will not work here.
The token does not expire unless you enable token rotation on the app. If you rotate or reinstall, the token changes:
$ lanes link connect slack --profile personal --workspace local --auth pasted_token --replaceTwo things are weaker on this path, both recorded in the security model. The
stored value is the credential itself rather than a means of obtaining one, so rotating it is
manual. And there is no scope-disclosure gate: what the token can do was decided in your console and
cannot be read back, so connect records what it asked for rather than what it got.
Why Slack works this way
Slack does not support Dynamic Client Registration, so nothing can register itself with Slack the way Notion and Linear do. That is deliberate: registering dynamically would let a client authenticate someone without an app existing, and on Enterprise Grid an admin approves each app first. So a client has to be pre-registered, and the only question is whose. It used to be yours. Now it is one Lanes registered, which is why the browser path exists at all. Lanes holds the app's client secret; the consent is still between you and your workspace, and the token lands in your credential store.
Unlike Google, there is no opting out: the hosted client is also the HTTPS address Slack returns you
to, so lanes link connect slack needs it. Connections already made are unaffected if it is down,
because Slack issues no refresh token.
When it does not work
| What you see | What it is |
|---|---|
App is not enabled for Slack MCP server access | A per-app switch, separate from scopes and from distribution, at api.slack.com/apps/<APP_ID>/app-assistant. Only the owner of the app sees this, so on the browser path it is already on. Re-run connect afterwards |
Slack refused the token | A bot token (xoxb-) where the user token (xoxp-) belongs, a scope missing from User Token Scopes, or an app reinstalled since (which mints a new token) |
| A tool is listed and fails when called | Its scope was not granted. Re-run connect to consent again, or add the scope in your own app |
What is recorded
Every call is recorded, allowed or refused. Slack's MCP server is Slack's, so the capabilities are discovered at connect time rather than declared here, and redaction has no authored list to key on: the default withholds every argument value. You get the call, not what was in it.
That is a thinner record than Gmail gives, and it is the honest consequence of proxying somebody else's tool list. See the audit log.
Next: every provider, or Add it to your agent.