/**
* Slack MCP Server - HTTP Transport
* Exposes Slack tools via HTTP endpoints
*/
import express from 'express';
import cors from 'cors';
import { SlackMCP, TOOL_DEFINITIONS } from './index.js';
const PORT = process.env.MCP_PORT || 3929;
const TOKEN = process.env.SLACK_TOKEN || process.env.SLACK_BOT_TOKEN;
if (!TOKEN) {
console.error('ERROR: SLACK_TOKEN or SLACK_BOT_TOKEN environment variable required');
process.exit(1);
}
const slack = new SlackMCP(TOKEN);
const app = express();
app.use(cors());
app.use(express.json());
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'ok', server: 'slack-mcp' });
});
// List available tools
app.get('/tools', (req, res) => {
res.json({
tools: TOOL_DEFINITIONS.map(t => ({
name: t.name,
description: t.description
}))
});
});
// Direct tool call endpoint
app.post('/call', async (req, res) => {
const { name, arguments: args = {} } = req.body;
try {
let result;
switch (name) {
case 'slack_list_channels':
result = await slack.listChannels(args);
break;
case 'slack_get_channel_history':
result = await slack.getChannelHistory(args.channel_id, args);
break;
case 'slack_post_message':
result = await slack.postMessage(args.channel, args.text, {
threadTs: args.thread_ts
});
break;
case 'slack_update_message':
result = await slack.updateMessage(args.channel, args.ts, args.text);
break;
case 'slack_delete_message':
result = await slack.deleteMessage(args.channel, args.ts);
break;
case 'slack_add_reaction':
result = await slack.addReaction(args.channel, args.ts, args.emoji);
break;
case 'slack_remove_reaction':
result = await slack.removeReaction(args.channel, args.ts, args.emoji);
break;
case 'slack_get_user_info':
result = await slack.getUserInfo(args.user_id);
break;
case 'slack_list_users':
result = await slack.listUsers(args);
break;
case 'slack_search_messages':
result = await slack.searchMessages(args.query, args);
break;
case 'slack_upload_file':
result = await slack.uploadFile(args.channels, args.content, args);
break;
default:
return res.status(400).json({
error: `Unknown tool: ${name}`,
available: TOOL_DEFINITIONS.map(t => t.name)
});
}
res.json({
result: {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
}
});
} catch (error) {
res.status(500).json({
error: error.message
});
}
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Slack MCP Server running on http://0.0.0.0:${PORT}`);
console.log('Endpoints: /health, /tools, /call');
});