slack-mcp
by LesterAJohn
README.md
# slack-mcp
Slack MCP server built from the skeleton-mcp base.
This project exposes Slack Web API operations as MCP tools with:
- stdio and HTTP transport support
- HTTP bearer-token protection for /mcp
- optional admin authorization gates for mutating tools
- per-user Slack bot token routing (different MCP users can run with different Slack tokens)
- admin tools to set/list/get/delete user token assignments
- Vault/Postgres scaffolding preserved from the original skeleton
## What It Does
The server currently focuses on Slack operations:
- Validate Slack token context
- List conversations
- Read conversation history
- Read user profile info
- Post messages
- Call any Slack Web API method via a generic tool
## Slack MCP Tool Catalog
Read-only tools:
- slack_connection_info
- slack_scope_info
- slack_list_methods
- slack_query_suggestions
- slack_auth_test
- slack_conversations_list
- slack_conversation_history
- slack_user_info
Mutating tools:
- slack_post_message
- slack_api_call (only guarded when the method is mutating)
Admin token tools:
- slack_admin_token_set
- slack_admin_token_get
- slack_admin_token_list
- slack_admin_token_delete
- slack_admin_token_refresh
- slack_admin_emulation_set
### Placeholder token emulation mode
If a resolved Slack bot token (from SLACK_BOT_TOKEN, the token store fallback map, or Vault) is
literally the string `placeholder` (case-insensitive), every Slack Web API call is answered with a
locally generated emulated response instead of calling the real Slack API. Emulated responses are
marked with `emulated: true` and `slack_connection_info` reports `slack.emulationActive: true` and
`slack.emulationMode` (`auto`, `on`, or `off`).
This lets the MCP server start and be exercised end-to-end before a real Slack bot token exists.
Once a real token is seeded into Vault for a user, call `slack_admin_token_refresh` to re-read it
and disable emulation for the default client; per-user calls automatically stop being emulated as
soon as `resolveTokenForUser` resolves a non-placeholder token from Vault or the token store.
An admin can also force emulation on or off directly, independent of the configured token, with
`slack_admin_emulation_set` (`mode: "on" | "off" | "auto"`). `"on"` emulates every Slack call
regardless of the token in use; `"off"` always makes real Slack calls even with a placeholder
token; `"auto"` (the default) restores the placeholder-token detection described above.
Authorization behavior:
- If MCP_ADMIN_AUTH_KEY is set, mutating tools require authorizationKey.
- Guarded mutating method names for slack_api_call include chat.postMessage and common write operations like reactions.add, pins.add, conversations.archive, etc.
- Admin token tools always require authorizationKey when MCP_ADMIN_AUTH_KEY is set.
Per-user execution behavior:
- Operational tools accept optional tokenUserId.
- If tokenUserId is omitted, the server uses the request user context (HTTP token metadata userId/subject when available), then MCP_CONFIG_DEFAULT_USER_ID.
- The selected MCP user id is resolved to a Slack bot token via the configured token store.
## Detailed Tool Definitions
### Shared Behavior Across All Tools
- Transport/auth prerequisites:
- stdio mode has no HTTP bearer-token gate.
- HTTP mode requires Authorization: Bearer <token> for /mcp requests.
- If MCP_ADMIN_AUTH_KEY is set, mutating/admin tools require authorizationKey.
- Environment-selection behavior:
- Tools with tokenUserId run as that MCP user.
- If tokenUserId is omitted, user resolution order is: request context userId/subject -> MCP_CONFIG_DEFAULT_USER_ID.
- The selected user is resolved to a Slack bot token from slackTokenStore or fallback SLACK_BOT_TOKEN.
- Common response shape:
```json
{
"content": [
{
"type": "text",
"text": "{\n \"ok\": true,\n \"status\": 200,\n \"data\": { ... },\n \"context\": { ... }\n}"
}
]
}
```
- Error shape (encoded in content[0].text) includes:
- ok: false
- status: HTTP-like status code (for example 400, 401, 500)
- error: message
### slack_query_suggestions
- Classification: read-only, low risk.
- Use when:
- You want schema discovery and workflow recommendations for every other MCP tool.
- Do not use when:
- You only need known endpoint names (use slack_list_methods).
- Permissions/prerequisites:
- No authorizationKey required.
- Parameters and constraints:
- toolName: optional non-empty string; exact tool name filter.
- query: optional non-empty string; simple text match against tool metadata.
- includeExamples: optional boolean (default true).
- includeAdmin: optional boolean (default true).
- Expected data payload:
- summary: filter metadata and counts.
- recommendations: common usage sequences.
- tools: per-tool guidance, parameter schema, and optional examples.
- Recommended tools:
- Follow-up: invoke any recommended tool sequence directly from response.
- Example:
```json
{
"name": "slack_query_suggestions",
"arguments": {
"query": "history",
"includeExamples": true
}
}
```
### slack_connection_info
- Classification: read-only, low risk.
- Use when:
- You need to verify server metadata, auth-gate configuration, effective request user, Slack client connection config, or token store wiring.
- Do not use when:
- You need to validate a specific Slack token's runtime permissions (use slack_auth_test).
- Permissions/prerequisites:
- No authorizationKey required.
- Requires server startup with valid env parsing.
- Parameters:
- none.
- Expected data payload:
- server: name, version, adminAuthConfigured, scopeModel, requestUserId.
- slack: service connection info.
- tokenStore: token-store connection info or null.
- Common failures:
- Rare; usually process misconfiguration causing server startup failure before tool execution.
- Recommended tools:
- Prerequisite/companion: slack_scope_info.
- Follow-up: slack_auth_test.
- Example:
```json
{
"name": "slack_connection_info",
"arguments": {}
}
```
### slack_scope_info
- Classification: read-only, low risk.
- Use when:
- You need deterministic app/user scoping paths for Vault token index and Postgres config keys.
- Do not use when:
- You need actual token values or token metadata (use admin token tools).
- Permissions/prerequisites:
- No authorizationKey required.
- Parameters:
- userId: optional non-empty string.
- If omitted, defaults to MCP_CONFIG_DEFAULT_USER_ID.
- Expected data payload:
- appName, userId, userIdPathSegment.
- postgres model and vault tokenIndexPath.
- Common failures:
- Invalid empty userId.
- Recommended tools:
- Prerequisite: slack_connection_info.
- Follow-up: slack_admin_token_set.
- Example:
```json
{
"name": "slack_scope_info",
"arguments": {
"userId": "alice"
}
}
```
### slack_list_methods
- Classification: read-only, low risk.
- Use when:
- You want a discoverable list of Slack wrapper endpoints available from this MCP service.
- Do not use when:
- You already know the target method and need execution (use specific tool or slack_api_call).
- Permissions/prerequisites:
- No authorizationKey required.
- Parameters:
- none.
- Expected data payload:
- endpoints: list of known wrapper method descriptors.
- Common failures:
- None typical beyond runtime service-client initialization issues.
- Recommended tools:
- Follow-up: slack_api_call or dedicated wrapper tools.
- Example:
```json
{
"name": "slack_list_methods",
"arguments": {}
}
```
### slack_auth_test
- Classification: read-only, low risk.
- Use when:
- You need to validate token identity/workspace and confirm user-token routing is working.
- Do not use when:
- You need channel/message data.
- Permissions/prerequisites:
- No authorizationKey required.
- Token must exist for resolved user (token store or fallback env token).
- Parameters:
- tokenUserId: optional non-empty string.
- Expected data payload:
- data: Slack auth.test response.
- context: tokenUserId and tokenSource used for this invocation.
- Common failures:
- 400 no Slack token configured for resolved user.
- 500 missing SLACK_BOT_TOKEN when token store is absent.
- Slack API errors (invalid_auth, account_inactive, etc.).
- Recommended tools:
- Prerequisite: slack_connection_info.
- Follow-up: slack_conversations_list.
- Example:
```json
{
"name": "slack_auth_test",
"arguments": {
"tokenUserId": "alice"
}
}
```
### slack_conversations_list
- Classification: read-only, moderate risk (can expose workspace metadata).
- Use when:
- You need channels/DM containers and pagination cursors.
- Do not use when:
- You need message bodies (use slack_conversation_history).
- Permissions/prerequisites:
- No authorizationKey required.
- Token needs conversation-list scopes (for example channels:read/groups:read/im:read/mpim:read).
- Parameters and constraints:
- types: optional non-empty string (Slack conversations.list types format).
- excludeArchived: optional boolean.
- limit: optional positive int <= 999.
- cursor: optional non-empty string.
- teamId: optional non-empty string.
- tokenUserId: optional non-empty string.
- Expected data payload:
- Raw Slack conversations.list response in data.
- context includes tokenUserId/tokenSource.
- Common failures:
- 400 invalid parameter shapes.
- Slack missing_scope/not_in_channel-like access failures.
- Recommended tools:
- Prerequisite: slack_auth_test.
- Follow-up: slack_conversation_history.
- Example:
```json
{
"name": "slack_conversations_list",
"arguments": {
"types": "public_channel,private_channel",
"excludeArchived": true,
"limit": 100,
"tokenUserId": "alice"
}
}
```
### slack_conversation_history
- Classification: read-only, moderate risk (message-content access).
- Use when:
- You need messages from one conversation with cursor/time-window filtering.
- Do not use when:
- You only need channel discovery (use slack_conversations_list).
- Permissions/prerequisites:
- No authorizationKey required.
- Token needs history scopes for the target conversation type.
- Parameters and constraints:
- channel: required non-empty string.
- cursor: optional non-empty string.
- limit: optional positive int <= 999.
- oldest/latest: optional non-empty string (Slack timestamp string).
- inclusive/includeAllMetadata: optional booleans.
- tokenUserId: optional non-empty string.
- Expected data payload:
- Raw Slack conversations.history response in data.
- context includes tokenUserId/tokenSource.
- Common failures:
- 400 missing channel.
- Slack channel_not_found, not_in_channel, missing_scope.
- Recommended tools:
- Prerequisite: slack_conversations_list.
- Follow-up: slack_user_info (to resolve user ids in messages).
- Example:
```json
{
"name": "slack_conversation_history",
"arguments": {
"channel": "C0123456789",
"limit": 50,
"oldest": "1710000000.000000",
"tokenUserId": "alice"
}
}
```
### slack_user_info
- Classification: read-only, moderate risk (PII exposure depending on scopes).
- Use when:
- You need profile details for a Slack user id.
- Do not use when:
- You need to list users in bulk (use slack_api_call with users.list if needed).
- Permissions/prerequisites:
- No authorizationKey required.
- users:read scope required; users:read.email for email fields.
- Parameters and constraints:
- user: required non-empty string.
- includeLocale: optional boolean.
- tokenUserId: optional non-empty string.
- Expected data payload:
- Raw Slack users.info response in data.
- context includes tokenUserId/tokenSource.
- Common failures:
- 400 missing user.
- Slack user_not_found or missing_scope.
- Recommended tools:
- Prerequisite: slack_auth_test.
- Follow-up: slack_post_message (for user-related workflows).
- Example:
```json
{
"name": "slack_user_info",
"arguments": {
"user": "U0123456789",
"includeLocale": true,
"tokenUserId": "alice"
}
}
```
### slack_post_message
- Classification: mutating, high risk.
- Use when:
- You need to send a message to a channel/DM/thread.
- Do not use when:
- You need read-only checks (use auth/list/history tools).
- Permissions/prerequisites:
- chat:write scope required.
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- Parameters and constraints:
- channel: required non-empty string.
- text: optional string, 1..40000 chars when provided.
- blocks: optional array<object>.
- threadTs: optional non-empty string.
- replyBroadcast/unfurlLinks/unfurlMedia: optional booleans.
- tokenUserId: optional non-empty string.
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- Raw Slack chat.postMessage response in data.
- context includes tokenUserId/tokenSource.
- Common failures:
- 401 invalid/missing authorizationKey when required.
- Slack channel_not_found, not_in_channel, missing_scope, invalid_blocks.
- Safety warnings:
- This operation sends real Slack messages.
- Validate channel and content before execution, especially in production workspaces.
- Recommended tools:
- Prerequisite: slack_auth_test and optional slack_conversations_list.
- Follow-up: slack_conversation_history (confirm posted message).
- Example:
```json
{
"name": "slack_post_message",
"arguments": {
"channel": "C0123456789",
"text": "Deployment completed successfully.",
"tokenUserId": "alice",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_api_call
- Classification: mixed.
- read-only when calling read methods.
- mutating/high risk when methodName is in guarded mutating set.
- Use when:
- You need a Slack Web API method not wrapped by a dedicated tool.
- Do not use when:
- A dedicated wrapper exists and provides stronger parameter contracts.
- Permissions/prerequisites:
- Requires a valid token for resolved user.
- If methodName is guarded mutating (for example chat.postMessage, reactions.add, pins.add, conversations.archive), authorizationKey is required when MCP_ADMIN_AUTH_KEY is set.
- Parameters and constraints:
- methodName: required non-empty string; normalized to lower-case before dispatch.
- params: optional JSON object.
- tokenUserId: optional non-empty string.
- authorizationKey: required for guarded mutating calls when admin auth is enabled.
- Expected data payload:
- Raw Slack method response in data.
- context includes tokenUserId/tokenSource.
- Common failures:
- 401 for guarded mutating calls without valid authorizationKey.
- Slack unknown_method, invalid_arguments, missing_scope.
- Safety warnings:
- Generic access can invoke broad Slack behaviors.
- Prefer least-privilege scopes and dedicated wrappers when possible.
- Recommended tools:
- Prerequisite: slack_list_methods and slack_auth_test.
- Follow-up: method-specific read calls to verify side effects.
- Example (read):
```json
{
"name": "slack_api_call",
"arguments": {
"methodName": "users.list",
"params": {
"limit": 100
},
"tokenUserId": "alice"
}
}
```
- Example (guarded mutating):
```json
{
"name": "slack_api_call",
"arguments": {
"methodName": "reactions.add",
"params": {
"channel": "C0123456789",
"name": "white_check_mark",
"timestamp": "1710000000.000000"
},
"tokenUserId": "alice",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_token_set
- Classification: mutating, high risk (credential write path).
- Use when:
- You need to create/update a per-user Slack bot token mapping.
- Do not use when:
- You only need to inspect mappings (use slack_admin_token_get/list).
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- slackTokenStore must be configured.
- Parameters and constraints:
- userId: required non-empty string.
- botToken: required non-empty string.
- note: optional string max 500.
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- Token-store write result metadata (user id, configured state, timestamps/source depending on store).
- Common failures:
- 401 invalid/missing authorizationKey when required.
- 500 slackTokenStore is not configured.
- store backend failures (Vault unavailable, permission denied).
- Safety warnings:
- Stores active credentials for future tool execution.
- Restrict access and audit usage.
- Recommended tools:
- Prerequisite: slack_scope_info.
- Follow-up: slack_admin_token_get and slack_auth_test.
- Example:
```json
{
"name": "slack_admin_token_set",
"arguments": {
"userId": "alice",
"botToken": "xoxb-...",
"note": "Primary workspace bot token",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_token_refresh
- Classification: admin, high risk (credential control-flow).
- Use when:
- SLACK_BOT_TOKEN=placeholder was used to start the server and a real bot token has since been
seeded into Vault; use this to disable emulation mode for the default Slack client.
- Do not use when:
- No slackTokenStore is configured, or the Vault secret still holds the placeholder value.
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- slackTokenStore must be configured.
- Parameters and constraints:
- userId: optional string, defaults to the request/default MCP user id.
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- `{ userId, refreshed, emulationActive, tokenSource }`; `refreshed: false` and
`emulationActive: true` when Vault still only has the placeholder token.
- Common failures:
- 400 no token found in Vault for the user.
- 401 invalid/missing authorizationKey when required.
- 500 slackTokenStore is not configured.
- Safety warnings:
- Only disables emulation once a genuine token is present in Vault; does not create tokens.
- Recommended tools:
- Prerequisite: seed a real token into Vault out-of-band.
- Follow-up: slack_auth_test, slack_connection_info.
- Example:
```json
{
"name": "slack_admin_token_refresh",
"arguments": {
"userId": "default",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_emulation_set
- Classification: admin, high risk (changes whether real Slack calls are made at all).
- Use when:
- You want to deliberately enter emulation mode for testing/demos, or force real Slack calls even
though the resolved token is the placeholder value.
- Do not use when:
- You only want the default automatic behavior (placeholder token -> emulated, real token -> real
calls); use `mode: "auto"` to restore that, or simply do nothing.
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- Parameters and constraints:
- mode: required, one of `on`, `off`, `auto`.
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- `{ emulationMode, emulationActive }`.
- Common failures:
- 401 invalid/missing authorizationKey when required.
- Safety warnings:
- `mode: "off"` sends real requests to Slack even with a placeholder token, which Slack will reject
as invalid_auth; `mode: "on"` silently emulates all calls, including mutating ones like
slack_post_message, so no real message is sent.
- Recommended tools:
- Follow-up: slack_connection_info to confirm the active mode.
- Example:
```json
{
"name": "slack_admin_emulation_set",
"arguments": {
"mode": "on",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_token_get
- Classification: read-only, high risk when includeToken=true (credential exposure).
- Use when:
- You need token metadata or token value (explicitly) for a user mapping.
- Do not use when:
- You only need a roster of configured users (use slack_admin_token_list).
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- slackTokenStore must be configured.
- Parameters and constraints:
- userId: required non-empty string.
- includeToken: optional boolean (default false recommended).
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- Metadata summary.
- If includeToken=true and configured, includes token field.
- Common failures:
- 401 invalid/missing authorizationKey when required.
- 500 slackTokenStore is not configured.
- Safety warnings:
- includeToken=true reveals secret material in tool output.
- Prefer includeToken=false unless strictly required.
- Recommended tools:
- Follow-up: slack_auth_test.
- Example:
```json
{
"name": "slack_admin_token_get",
"arguments": {
"userId": "alice",
"includeToken": false,
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_token_list
- Classification: read-only, moderate risk (reveals configured user identifiers).
- Use when:
- You need to enumerate MCP users with configured Slack token records.
- Do not use when:
- You need details for one user (use slack_admin_token_get).
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- slackTokenStore must be configured.
- Parameters:
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- users: array of configured user summaries.
- Common failures:
- 401 invalid/missing authorizationKey when required.
- 500 slackTokenStore is not configured.
- Recommended tools:
- Follow-up: slack_admin_token_get or slack_admin_token_delete.
- Example:
```json
{
"name": "slack_admin_token_list",
"arguments": {
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
### slack_admin_token_delete
- Classification: mutating, high risk (credential deletion).
- Use when:
- You need to revoke/remove stored Slack token mappings for a user.
- Do not use when:
- You only need to disable usage temporarily (consider rotating token externally first).
- Permissions/prerequisites:
- If MCP_ADMIN_AUTH_KEY is set, authorizationKey is required and must match.
- slackTokenStore must be configured.
- Parameters and constraints:
- userId: required non-empty string.
- authorizationKey: required when admin auth is enabled.
- Expected data payload:
- userId and deleted boolean.
- Common failures:
- 401 invalid/missing authorizationKey when required.
- 500 slackTokenStore is not configured.
- store backend failures.
- Safety warnings:
- Destructive operation for local token mapping.
- Confirm target userId before deletion.
- Recommended tools:
- Prerequisite: slack_admin_token_get.
- Follow-up: slack_admin_token_list and slack_auth_test (for validation of revocation impact).
- Example:
```json
{
"name": "slack_admin_token_delete",
"arguments": {
"userId": "alice",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
## Slack API Notes
Configured Slack client:
- Base URL defaults to https://slack.com/api
- Bot token is required via SLACK_BOT_TOKEN
Implemented method wrappers:
- auth.test
- conversations.list
- conversations.history
- users.info
- chat.postMessage
Generic method execution:
- slack_api_call sends POST to /<methodName> with params JSON payload
- Example methodName: conversations.info, users.list, chat.postMessage
## Required Slack Scopes
Typical scopes you should grant your Slack app for these tools:
- chat:write for slack_post_message
- channels:read, groups:read, im:read, mpim:read for conversations.list
- channels:history, groups:history, im:history, mpim:history for conversations.history
- users:read for users.info
- users:read.email if you need email in users.info responses
Exact required scopes can vary by workspace and conversation type.
## Environment Variables
Slack-specific:
- SLACK_BOT_TOKEN (optional default/fallback token)
- SLACK_API_BASE_URL (default: https://slack.com/api)
- SLACK_TIMEOUT_MS (default: 15000)
- MCP_SLACK_TOKEN_STORE (vault|memory; default auto-detects from Vault config)
- MCP_SLACK_DEFAULT_TOKEN_IN_VAULT (default: true)
- MCP_SLACK_USER_TOKENS_JSON (optional JSON fallback map, e.g. {"alice":"xoxb-..."})
Core app:
- APP_NAME
- MCP_SERVER_NAME (default: slack-mcp)
- MCP_SERVER_VERSION
- MCP_ADMIN_AUTH_KEY
- MCP_TRANSPORT_MODE (stdio, http, both)
HTTP transport:
- MCP_HTTP_HOST
- MCP_HTTP_PORT
- MCP_HTTP_PATH
- MCP_HTTP_HEALTH_PATH
- MCP_HTTP_AUTH_MODE
- MCP_HTTP_AUTH_TOKENS
- MCP_HTTP_TRUST_PROXY
- MCP_HTTP_ALLOWED_ORIGINS
- MCP_HTTP_ALLOWED_IPS
- MCP_HTTP_MAX_BODY_BYTES
- MCP_HTTP_RATE_LIMIT_WINDOW_MS
- MCP_HTTP_RATE_LIMIT_MAX_REQUESTS
- MCP_HTTP_TOKEN_SOURCE (vault|static; when vault, enables Vault token verifier metadata)
- MCP_HTTP_VAULT_TOKEN_INDEX_PATH
- MCP_HTTP_VAULT_TOKEN_DEFAULT_USER_ID
- MCP_HTTP_VAULT_TOKEN_REQUIRED_SCOPES
- MCP_HTTP_VAULT_TOKEN_REQUIRED_AUDIENCE
- MCP_HTTP_VAULT_TOKEN_CACHE_TTL_MS
For full defaults and examples, see .env.example.
## Quick Start
1. Install dependencies:
```bash
npm install
```
2. Copy env file and set Slack token:
```bash
cp .env.example .env
```
Set at minimum:
- SLACK_BOT_TOKEN=xoxb-...
3. Start MCP server:
```bash
npm run start:stdio
```
Or HTTP mode:
```bash
npm run start:http
```
4. Run tests:
```bash
npm test
```
## Registering in MCP Clients
### VS Code (stdio)
Example .vscode/mcp.json entry:
```json
{
"command": "npm",
"args": ["run", "start:stdio"],
"cwd": "/path/to/slack-mcp"
}
```
### HTTP-capable clients
Run:
```bash
npm run start:http
```
Default endpoint:
- MCP: http://127.0.0.1:3000/mcp
- Health: http://127.0.0.1:3000/healthz
## HTTP Security Model
- Every /mcp request requires Authorization: Bearer <token>
- Token validation currently uses configured MCP_HTTP_AUTH_TOKENS unless other auth sources are wired
- Rate limit and body-size protections are enforced by src/http/server.js
With MCP_HTTP_TOKEN_SOURCE=vault and a Vault token index configured:
- incoming bearer tokens are verified via Vault token metadata
- user metadata (for example userId/subject) is propagated to MCP request context
- Slack tool execution defaults to that user context unless tokenUserId is explicitly provided
## Multi-User Token Administration
Use admin tools to manage user-to-Slack-token mappings:
1. Set token for a user:
```json
{
"name": "slack_admin_token_set",
"arguments": {
"userId": "alice",
"botToken": "xoxb-...",
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
2. Verify a user token mapping:
```json
{
"name": "slack_admin_token_get",
"arguments": {
"userId": "alice",
"includeToken": false,
"authorizationKey": "<MCP_ADMIN_AUTH_KEY>"
}
}
```
3. Run a Slack call as that user:
```json
{
"name": "slack_auth_test",
"arguments": {
"tokenUserId": "alice"
}
}
```
Token records are stored per user under Vault path:
- <appName>/users/<normalizedUserId>/http/auth/token-index
If Vault token storage is disabled, mappings are kept in-memory for that process.
Note:
- TLS termination is intended at reverse proxy/load balancer level in this process mode.
## External Services Mode
The repository still supports an app-only startup profile via docker-compose.external.yml when using external Vault and Postgres services.
Required variables in that mode include:
- POSTGRES_HOST
- POSTGRES_PORT
- POSTGRES_DB
- POSTGRES_USER
- POSTGRES_PASSWORD
- VAULT_ADDR
- VAULT_TOKEN
Start with:
```bash
docker compose -f docker-compose.external.yml up -d
```
## Project Structure
Primary runtime files:
- src/index.js: stdio startup
- src/http/index.js: HTTP startup
- src/http/server.js: HTTP transport/auth/rate limiting
- src/mcp/server.js: MCP tool registration and auth checks
- src/services/targetService.js: SlackServiceClient adapter
- src/config/env.js: env parsing/validation
Skeleton infrastructure (preserved):
- src/services/vault.js
- src/services/configStore.js
- docker-compose.yml
- docker-compose.external.yml
- vault-production/
## Testing
Current tests include:
- Slack MCP tool behavior and mutating auth requirements
- HTTP transport auth/initialize/health behavior
- Existing skeleton Vault/config infrastructure tests
Run all:
```bash
npm test
```
## Known Follow-up Work
The server behavior is Slack-specific, but some legacy skeleton assets remain intentionally preserved (Vault/Postgres flows and migration docs). If desired, those docs and compose defaults can be slimmed to a Slack-only deployment profile in a follow-up pass.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues