Skip to content

Conversation

@lswith
Copy link

@lswith lswith commented Feb 9, 2026

Summary

Adds single-user local OAuth login flow for CLI (stdio) usage, stacked on top of #166.

  • pkg/oauth/local.go — Local OAuth flow: generates a self-signed TLS cert, starts a temporary HTTPS server on localhost:8443, opens the browser for Slack authorization, exchanges the callback code for an xoxp token
  • pkg/oauth/storage_file.go — File-based token storage at ~/.slack-mcp/token.json with full metadata (user_id, team_id, timestamps), 0600 permissions
  • cmd/slack-mcp-server/main.go — Token resolution in legacy mode now follows: env vars → file store → local OAuth flow, keeping full backward compatibility

Also fixes two pre-existing compile errors in #166's conversations handler.

Note: This PR is stacked on #166 and includes its commits. It should be reviewed/merged after #166 lands.

Test plan

  • go build ./... passes
  • go test ./pkg/oauth/ -v — 15 new tests all passing
  • Manual test: full OAuth flow with real Slack app (browser opens, authorize, token exchanged, stored, server starts)
  • Manual test: subsequent startup reads token from file store (skips OAuth)
  • Backward compat: existing SLACK_MCP_XOXP_TOKEN env var still works unchanged

🤖 Generated with Claude Code

wentaoyang-moloco and others added 23 commits November 5, 2025 15:41
Add OAuth 2.0 authentication flow for multi-user support with the following features:

Core OAuth Implementation:
- OAuth 2.0 authorization flow with Slack API
- CSRF protection via state parameter validation
- In-memory token storage with automatic cleanup
- Per-request Slack client creation for token isolation
- Support for both user tokens (xoxp) and bot tokens (xoxb)

Dual-Mode Architecture:
- Legacy mode: Single-user with browser tokens (xoxc/xoxd/xoxp)
- OAuth mode: Multi-user with OAuth tokens
- Backward compatible with existing configurations

OAuth Handlers:
- /oauth/authorize endpoint for initiating OAuth flow
- /oauth/callback endpoint for processing OAuth callbacks
- OAuth middleware for token validation and user context injection

Multi-User Features:
- Per-user token isolation and validation
- User context propagation through request chain
- Separate user and bot token support
- Option to post as bot or user via post_as_bot parameter

Security Enhancements:
- Secure state generation using crypto/rand
- Token validation on each request
- HTTPS requirement for OAuth callbacks (Slack requirement)
- Security headers on OAuth endpoints
- Credentials removed from example files

Documentation:
- Comprehensive OAuth setup guide (docs/04-oauth-setup.md)
- ngrok setup instructions for local development
- OAuth configuration examples
- Architecture and troubleshooting sections

Developer Tools:
- OAuth testing script (scripts/test-oauth.sh)
- OAuth server startup script (start-oauth-server.sh)
- Example configuration file (oauth.env.example)

Modified Components:
- main.go: Added OAuth mode detection and initialization
- channels.go: OAuth support with per-request client
- conversations.go: OAuth support with user/bot token selection
- server.go: OAuth-enabled SSE and HTTP server methods
- sse_auth.go: Exported WithAuthKey for OAuth middleware
- .gitignore: Added oauth.env and binary exclusions

New Components:
- pkg/oauth/: OAuth manager, storage, and types
- pkg/server/auth/: OAuth middleware and user context
- pkg/server/oauth_handler.go: OAuth HTTP handlers

Breaking Changes: None (fully backward compatible)

Environment Variables:
- SLACK_MCP_OAUTH_ENABLED: Enable OAuth mode
- SLACK_MCP_OAUTH_CLIENT_ID: Slack app client ID
- SLACK_MCP_OAUTH_CLIENT_SECRET: Slack app client secret
- SLACK_MCP_OAUTH_REDIRECT_URI: OAuth callback URL (requires HTTPS)
Skip TestIntegrationConversations as it requires:
- External Slack workspace with #testcase-1 channel and test data
- SLACK_MCP_OPENAI_API environment variable
- ngrok forwarding setup

This test is from the upstream repo and requires infrastructure
not available in CI. Test can be re-enabled when proper test
infrastructure is set up.
Remove ability to post as bot for security and clarity:
- Removed post_as_bot parameter from conversations handler
- Removed bot scopes from OAuth authorization request
- Simplified OAuth callback response (no bot token)
- Updated documentation to reflect user-only posting

Users will now always appear as themselves when posting messages,
never as the app bot. This provides better transparency and
prevents impersonation concerns.
Add comprehensive OAuth quick-start section to README:
- Step-by-step OAuth setup instructions
- Comparison with legacy mode (when to use each)
- OAuth environment variables added to reference table
- Clear benefits and use cases for OAuth vs legacy
- MCP client configuration examples

Makes it easier for users to understand and choose between
OAuth mode (multi-user, production) and legacy mode (single-user, testing).
Merged latest changes from upstream korotovsky/slack-mcp-server:
- Bot token (xoxb) support from upstream
- Dependency updates and bug fixes
- Tool annotations for better LLM understanding
- Default cache directory improvements

Conflicts resolved:
- README.md: Merged OAuth variables with bot token support
- Both OAuth and bot token authentication methods now documented

Changes from upstream:
- xoxb bot token support
- Updated dependencies (slack-go v0.17.3)
- Cache file location improvements
- Various bug fixes and features
- Add GovSlack token verification support
- Fix OAuth context URL handling and user info retrieval
- Update Docker Hub image name and credentials
- Fix member count and channel ID lookup issues
- Improve conversation and channel handling
- Add Trivy security scanning and Dependabot configuration
- Update dependencies and Docker entrypoint

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Removed skip condition for integration test due to external dependencies.
Companion to reactions_add (merged in korotovsky#141). Allows removing emoji
reactions from messages using the same channel/timestamp/emoji params.

Tested with xoxb, xoxc/xoxd token types.
Generalizes error messages since this parser is now shared between
reactions_add and reactions_remove. Both tools use the same guardrail
(SLACK_MCP_ADD_MESSAGE_TOOL env var).
Adds metadata fields to help identify media-containing messages:
- BotName: populated from msg.BotProfile.Name for bot messages (e.g., 'giphy')
- FileCount: count of attached files
- HasMedia: true if message has files OR image blocks

This provides visibility into message types that was previously stripped
from the Slack API response, addressing user requests in issue korotovsky#88.

For SearchMessage results, only HasMedia is populated (via blocks) since
the search API doesn't return BotProfile or Files data.
Adds ability to download file content by file ID, addressing maintainer
request on PR korotovsky#170.

- New files_get tool gated by SLACK_MCP_FILES_TOOL env var
- Text files (text/*, application/json, etc.) returned as plain text
- Binary files returned as base64-encoded content
- 5MB size limit to keep responses reasonable for LLM context
- Returns structured JSON: file_id, filename, mimetype, size, encoding, content
Enables agents to discover file IDs from conversation history,
completing the workflow for files_get tool usage.
…gy consistency

- Tool: files_get → attachment_get_data
- Field: FileIDs → AttachmentIDs
- Env var: SLACK_MCP_FILES_TOOL → SLACK_MCP_ATTACHMENT_TOOL

Per maintainer feedback - aligns with Slack's 'attachment' terminology
and may improve LLM performance due to training data prevalence.
Add single-user local OAuth flow that starts a temporary HTTPS server
with a self-signed cert on localhost:8443, opens the browser for Slack
authorization, and exchanges the callback code for an xoxp token.

Token resolution in legacy mode now follows: env vars → file store
(~/.slack-mcp/token.json) → local OAuth flow, keeping full backward
compatibility while enabling interactive CLI login.

Also fixes two pre-existing compile errors in PR korotovsky#166's conversations
handler (missing parseParamsToolReaction args, duplicate hasMedia decl).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants