A stateless Discord HTTP API that enables multi-bot interactions via Model Context Protocol (MCP) over HTTP transport. Perfect for containerized architectures where multiple Claude Code containers need Discord access with different bot identities.
- π Completely Stateless: Creates fresh Discord clients per request - no caching or persistent connections
- π€ Multi-Bot Support: Handle multiple Discord bot tokens simultaneously with separate identities
- π‘ HTTP Transport: RESTful API compatible with MCP HTTP protocol
- π³ Container Ready: Dockerized deployment with health checks
- π Secure: Tokens passed per request, never stored server-side
- β‘ Efficient: Proper cleanup after each operation
# Install dependencies pip install -r requirements.txt # Start the stateless Discord API python discord_http_stateless.py # Server runs on http://localhost:9091# Build and start docker-compose up -d discord-http-api # Check health curl http://localhost:9091/health# Send message from Bot 1 curl -X POST http://localhost:9091/messages \ -H "Content-Type: application/json" \ -d '{ "channel_id": "YOUR_CHANNEL_ID", "content": "Hello from Bot 1!", "discord_token": "YOUR_BOT_1_TOKEN" }' # Send message from Bot 2 curl -X POST http://localhost:9091/messages \ -H "Content-Type: application/json" \ -d '{ "channel_id": "YOUR_CHANNEL_ID", "content": "Hello from Bot 2!", "discord_token": "YOUR_BOT_2_TOKEN" }'GET /health Response:
{ "status": "healthy", "stateless": true, "timestamp": "2025-07-23T00:58:45.929694" }POST /messages Body:
{ "channel_id": "1234567890", "content": "Hello Discord!", "discord_token": "your_bot_token_here" }POST /test Body:
{ "discord_token": "your_bot_token_here" }POST /channels Body:
{ "discord_token": "your_bot_token_here" }Use the provided test client to verify multiple Discord bot identities:
# Set up environment variables export DISCORD_TOKEN="your_first_bot_token" export DISCORD_TOKEN2="your_second_bot_token" # Run multi-bot test python test_mcp_http_client.pyExpected output shows messages from different Discord applications:
π΅ Testing MCP Client 1 (Bot Token: ...abcd1234) β
Initialized MCP Discord client (Bot Token: ...abcd1234) β
Test message: Test message sent! Message ID: 1397376915706216558 π’ Testing MCP Client 2 (Bot Token: ...efgh5678) β
Initialized MCP Discord client (Bot Token: ...efgh5678) β
Test message: Test message sent! Message ID: 1397376918445232259 βββββββββββββββββββ HTTP ββββββββββββββββββββββββ β Client App β βββββββββββΊ β Stateless Discord β β (Claude Code) β β HTTP API β βββββββββββββββββββ ββββββββββββββββββββββββ β βΌ ββββββββββββββββββββββββ β Fresh Discord β β Client Per Request β β (Auto-cleanup) β ββββββββββββββββββββββββ - Client sends HTTP request with Discord token in body
- Server creates fresh Discord client for that specific token
- Operation executes (send message, list channels, etc.)
- Discord client closes automatically after operation
- Response returned to client with results
| Stateful (β Old) | Stateless (β New) |
|---|---|
| Caches bot instances | Creates fresh clients per request |
| Token mixing issues | Perfect token isolation |
| Memory leaks possible | Automatic cleanup |
| Single bot identity | Multiple bot identities work correctly |
The server is completely stateless and doesn't require environment variables. Tokens are passed with each request.
# For testing only DISCORD_TOKEN=your_primary_bot_token DISCORD_TOKEN2=your_secondary_bot_token DEFAULT_SERVER_ID=your_discord_server_id{ "mcpServers": { "discord-stateless": { "transport": { "type": "http", "url": "http://localhost:9091" }, "description": "Stateless Discord MCP Server supporting multiple bot tokens" } } }For direct integration with Claude Code using STDIO transport, use the following command:
# Add Discord MCP server to Claude Code claude mcp add discord-manager -- "/path/to/your/venv/bin/python" "-m" "discord_mcp.server" "--token" "YOUR_DISCORD_BOT_TOKEN" "--server-id" "YOUR_SERVER_ID"Important Notes:
- Replace
/path/to/your/venv/bin/pythonwith the actual path to your Python virtual environment - Replace
YOUR_DISCORD_BOT_TOKENwith your Discord bot token - Replace
YOUR_SERVER_IDwith your Discord server ID - The
--separator is required to prevent argument parsing conflicts - This creates a local MCP server configuration that persists across Claude Code sessions
Example with typical paths:
claude mcp add discord-manager -- "/Users/username/project/mcp-discord-local/.venv/bin/python" "-m" "discord_mcp.server" "--token" "YOUR_BOT_TOKEN" "--server-id" "1234567890123456789"Verify Configuration:
# List configured MCP servers claude mcp list # Expected output shows discord-manager as connectedservices: discord-http-api: build: . container_name: discord-stateless-api ports: - "9091:9091" restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9091/health"]# Build image docker build -t discord-stateless-api . # Run container docker run -d \ --name discord-stateless \ -p 9091:9091 \ discord-stateless-apiimport aiohttp class ClaudeCodeDiscordClient: def __init__(self, api_url="http://discord-api:9091", bot_token="..."): self.api_url = api_url self.bot_token = bot_token async def send_status(self, message): async with aiohttp.ClientSession() as session: async with session.post(f"{self.api_url}/messages", json={ "channel_id": "1234567890", "content": message, "discord_token": self.bot_token }) as resp: return await resp.json() # Usage in Claude Code container client = ClaudeCodeDiscordClient(bot_token=os.getenv("CLAUDE_BOT_TOKEN")) await client.send_status("π€ Claude Code container started!")# Different agents use different Discord identities agents = { "research_agent": "BOT_TOKEN_1", "coding_agent": "BOT_TOKEN_2", "testing_agent": "BOT_TOKEN_3" } for agent_name, token in agents.items(): await send_message( channel_id="1234567890", content=f"Agent {agent_name} is online!", discord_token=token )If you see the same Discord user for different tokens:
- Verify tokens are from different Discord applications (not regenerated tokens)
- Check server logs for "Created fresh Discord client" messages
- Use test endpoint to verify bot identities
{ "success": false, "error": "Bot doesn't have permission to send messages in this channel" }Solution: Ensure bot has Send Messages permission in target channel.
{ "success": false, "error": "Invalid Discord token" }Solution: Verify bot token is valid and bot is invited to the server.
- No memory leaks: Fresh clients prevent connection accumulation
- Efficient: Quick client creation/cleanup cycle
- Scalable: Handles multiple concurrent requests
- Resource-friendly: No persistent Discord connections
# Test multiple bot identities python test_mcp_http_client.py # Test single bot functionality curl -X POST http://localhost:9091/test \ -H "Content-Type: application/json" \ -d '{"discord_token": "YOUR_TOKEN"}'- Add endpoint to
discord_http_stateless.py - Use
execute_with_client()wrapper for Discord operations - Ensure proper error handling and cleanup
- Update API documentation
This stateless Discord API is designed for integration with:
- Claude Code containers with individual Discord bot identities
- Multi-agent orchestrators managing different Discord personalities
- Microservice architectures requiring Discord functionality
- MCP-based applications needing HTTP transport
MIT License - see LICENSE file for details.
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
Built for the SuperAgent multi-agent system π€
Perfect for containerized Claude Code deployments π³
Enabling true multi-bot Discord interactions π