Integrated Server Architecture
The Integrated Server combines both MCP and webhook server functionality into a single FastAPI application. This document details the architecture, implementation, and deployment patterns for the unified server approach.
Overview
The integrated server provides a comprehensive solution that handles both MCP client requests and Slack webhook events in a single deployment. This approach simplifies deployment, reduces operational overhead, and enables unified configuration and monitoring.
Architecture Components
The Integrated Server uses the common instance management design shared across all server types in this project. For detailed information about factory patterns, singleton management, token handling, and testing support, see the Common Instance Management documentation.
Integrated Application Factory
The core integration function that creates a unified FastAPI app:
from slack_mcp.integrate.server import create_integrated_app
def create_integrated_app(
token: Optional[str] = None,
mcp_transport: str = "sse",
mcp_mount_path: Optional[str] = "/mcp",
retry: int = 3,
) -> FastAPI:
# Create webhook server as base
app = create_slack_app()
# Initialize shared Slack client
initialize_slack_client(token, retry=retry)
# Mount MCP server based on transport type
if mcp_transport == "sse":
mcp_app = _server_instance.sse_app(mount_path=mcp_mount_path)
app.mount(mcp_mount_path or "/mcp", mcp_app)
elif mcp_transport == "streamable-http":
mcp_app = _server_instance.streamable_http_app()
# Merge routes for HTTP streaming
for route in mcp_app.routes:
app.routes.append(route)
return app
Unified FastAPI Application
The integrated server uses FastAPI as the foundation, providing:
- Webhook Endpoints:
/slack/eventsfor Slack event processing - MCP Endpoints: Mounted at configurable path (default:
/mcp) - Health Checks: Unified health monitoring for both components
- OpenAPI Documentation: Combined API documentation
Shared Resource Management
Slack Client Sharing
Both MCP tools and webhook processing use the same Slack client instance:
# Shared client initialization
from slack_mcp.client.manager import initialize_slack_client
initialize_slack_client(token=slack_token, retry=3)
Benefits:
- Connection pooling efficiency
- Consistent token management
- Unified rate limiting
- Shared authentication state
Configuration Management
Centralized configuration for both components:
# Environment variables affecting both components
SLACK_BOT_TOKEN=xoxb-... # Shared Slack authentication
SLACK_SIGNING_SECRET=... # Webhook verification
MCP_TRANSPORT=sse # MCP transport selection
MCP_MOUNT_PATH=/mcp # MCP endpoint path
SLACK_EVENTS_TOPIC=slack.events # Webhook event publishing
Transport Configuration
Server-Sent Events (SSE) Mode
Default transport for browser-compatible MCP integration:
# SSE transport mounted at /mcp
mcp_app = server.sse_app(mount_path="/mcp")
app.mount("/mcp", mcp_app)
Endpoint Structure:
- Webhook:
POST /slack/events - MCP SSE:
GET /mcp/sse - Health:
GET /health
HTTP Streaming Mode
RESTful HTTP transport integration:
# HTTP streaming routes merged into main app
mcp_app = server.streamable_http_app()
for route in mcp_app.routes:
app.routes.append(route)
Endpoint Structure:
- Webhook:
POST /slack/events - MCP Tools:
POST /call_tool,GET /list_tools, etc. - Health:
GET /health
Deployment Patterns
Single Container Deployment
Unified deployment with Docker:
FROM python:3.11-slim
COPY . /app
WORKDIR /app
RUN pip install -e .
EXPOSE 3000
CMD ["slack-integrated-server", "--transport", "sse", "--port", "3000"]
Environment Configuration:
environment:
- SLACK_BOT_TOKEN=xoxb-your-token
- SLACK_SIGNING_SECRET=your-signing-secret
- MCP_TRANSPORT=sse
- MCP_MOUNT_PATH=/mcp
- PORT=3000
Kubernetes Deployment
Scalable container orchestration:
apiVersion: apps/v1
kind: Deployment
metadata:
name: slack-mcp-integrated
spec:
replicas: 3
selector:
matchLabels:
app: slack-mcp-integrated
template:
metadata:
labels:
app: slack-mcp-integrated
spec:
containers:
- name: server
image: slack-mcp-server:latest
ports:
- containerPort: 3000
env:
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
name: slack-secrets
key: bot-token
- name: SLACK_SIGNING_SECRET
valueFrom:
secretKeyRef:
name: slack-secrets
key: signing-secret
---
apiVersion: v1
kind: Service
metadata:
name: slack-mcp-service
spec:
selector:
app: slack-mcp-integrated
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Cloud Platform Deployment
Heroku
# Deploy to Heroku
heroku create your-slack-mcp-app
heroku config:set SLACK_BOT_TOKEN=xoxb-your-token
heroku config:set SLACK_SIGNING_SECRET=your-secret
heroku config:set MCP_TRANSPORT=sse
git push heroku main
Google Cloud Run
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: slack-mcp-integrated
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/maxScale: "10"
spec:
containers:
- image: gcr.io/project-id/slack-mcp-server
ports:
- containerPort: 3000
env:
- name: SLACK_BOT_TOKEN
value: "xoxb-your-token"
- name: MCP_TRANSPORT
value: "sse"
Configuration Options
CLI Configuration
slack-integrated-server \
--transport sse \
--mount-path /mcp \
--host 0.0.0.0 \
--port 3000 \
--log-level INFO \
--retry 3
Environment Variables
Required
SLACK_BOT_TOKEN: Slack bot token for MCP toolsSLACK_SIGNING_SECRET: Signing secret for webhook verification
Optional
MCP_TRANSPORT: Transport mechanism (sse, streamable-http)MCP_MOUNT_PATH: Mount path for MCP endpointsSLACK_EVENTS_TOPIC: Queue topic for webhook eventsQUEUE_BACKEND_TYPE: Queue backend selectionHOST: Server bind addressPORT: Server portLOG_LEVEL: Logging verbosity
Transport-Specific Configuration
SSE Transport
# Mount path affects SSE endpoint
MCP_MOUNT_PATH=/api/mcp # SSE available at /api/mcp/sse
HTTP Streaming
# Routes merged directly into app
# No mount path required, routes at root level
Client Integration
MCP Client Connection
SSE Transport
// Browser-based MCP client
const client = new MCPClient({
transport: 'sse',
url: 'https://your-server.com/mcp/sse'
});
HTTP Streaming
# Python MCP client
from mcp import Client
from mcp.client.http import HttpTransport
transport = HttpTransport("https://your-server.com")
client = Client(transport)
Webhook Configuration
Configure Slack app webhook URL:
https://your-server.com/slack/events
Monitoring and Observability
Health Checks
Unified health endpoints for both components:
@app.get("/health")
async def health_check():
return {
"status": "healthy",
"components": {
"mcp_server": "ready",
"webhook_server": "ready",
"slack_client": "connected",
"queue_backend": "connected"
},
"timestamp": datetime.utcnow().isoformat()
}