Skip to content

Commit 06197ab

Browse files
authored
Merge pull request #7 from WebexCommunity/claude/streaming-server-aws-Sgava
2 parents 415de6c + 04f0c8c commit 06197ab

11 files changed

Lines changed: 281 additions & 258 deletions

File tree

DEPLOYMENT.md

Lines changed: 139 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,160 @@
1-
# Webex Bot MCP Server Configuration
2-
3-
This file provides deployment guidance and configuration options for production use.
4-
5-
## Production Deployment Checklist
6-
7-
### Security Configuration
8-
- [ ] Bot token stored in secure environment variables (not in code)
9-
- [ ] SSL/TLS enabled for all communications
10-
- [ ] Regular token rotation schedule established
11-
- [ ] Access logging enabled
12-
- [ ] Rate limiting configured
13-
- [ ] Input validation implemented
14-
15-
### Monitoring & Observability
16-
- [ ] Application logs configured (structured logging recommended)
17-
- [ ] Metrics collection enabled
18-
- [ ] Health check endpoints configured
19-
- [ ] Error tracking and alerting set up
20-
- [ ] Performance monitoring dashboard created
21-
22-
### High Availability & Scale
23-
- [ ] Container orchestration configured (if using containers)
24-
- [ ] Load balancing configured (for HTTP transport)
25-
- [ ] Graceful shutdown handling implemented
26-
- [ ] Resource limits defined
27-
- [ ] Auto-scaling policies configured
28-
29-
### Compliance & Governance
30-
- [ ] Data retention policies defined
31-
- [ ] Audit logging enabled
32-
- [ ] Compliance framework alignment verified
33-
- [ ] Privacy policies updated
34-
- [ ] User consent mechanisms implemented
35-
36-
## Environment Variables Reference
37-
38-
### Required
39-
- `WEBEX_ACCESS_TOKEN`: Bot access token from Webex Developer Portal
40-
41-
### Optional Configuration
42-
- `WEBEX_DEBUG`: Enable debug logging (default: false)
43-
- `WEBEX_RATE_LIMIT_MESSAGES_PER_SECOND`: Message rate limit (default: 10)
44-
- `WEBEX_RATE_LIMIT_API_CALLS_PER_MINUTE`: API call rate limit (default: 300)
45-
- `LOG_LEVEL`: Logging verbosity (DEBUG, INFO, WARN, ERROR)
46-
- `METRICS_ENABLED`: Enable metrics collection (default: false)
47-
48-
### Transport Configuration
49-
- `MCP_TRANSPORT`: Transport type (stdio, streamable-http)
50-
- `MCP_HOST`: Host binding for HTTP transport (default: localhost)
51-
- `MCP_PORT`: Port binding for HTTP transport (default: 8000)
52-
53-
## Docker Deployment
54-
55-
```dockerfile
56-
FROM python:3.12-slim
57-
58-
WORKDIR /app
59-
COPY requirements.txt .
60-
RUN pip install -r requirements.txt
61-
62-
COPY . .
63-
EXPOSE 8000
64-
65-
CMD ["python", "main.py", "--transport", "streamable-http", "--host", "0.0.0.0"]
1+
# AWS Deployment Guide — Webex Bot MCP
2+
3+
This guide covers deploying the server on an EC2 instance with an Application Load Balancer
4+
providing TLS termination.
5+
6+
```
7+
MCP Client
8+
│ HTTPS :443 Authorization: Bearer <webex_token>
9+
10+
┌─────────────────────────────────┐
11+
│ Application Load Balancer │ ← ACM certificate (TLS termination)
12+
│ Listener: HTTPS 443 │
13+
└──────────────┬──────────────────┘
14+
│ HTTP :8000
15+
16+
┌─────────────────────────────────┐
17+
│ EC2 instance │
18+
│ docker-compose │
19+
│ webex-bot-mcp container :8000 │
20+
└─────────────────────────────────┘
21+
```
22+
23+
## Prerequisites
24+
25+
- AWS account with permissions to create EC2, ALB, ACM, and security group resources
26+
- A domain name with DNS you can update (required for the ACM certificate)
27+
- Docker and Docker Compose installed on the EC2 instance
28+
29+
## 1. Build and push the image
30+
31+
Build locally and push to ECR, or build directly on the instance.
32+
33+
**Option A — build on the EC2 instance (simpler):**
34+
```bash
35+
git clone https://github.com/WebexCommunity/webex-bot-mcp.git
36+
cd webex-bot-mcp
37+
docker compose build
6638
```
6739

68-
## Kubernetes Deployment
69-
70-
```yaml
71-
apiVersion: apps/v1
72-
kind: Deployment
73-
metadata:
74-
name: webex-bot-mcp
75-
spec:
76-
replicas: 2
77-
selector:
78-
matchLabels:
79-
app: webex-bot-mcp
80-
template:
81-
metadata:
82-
labels:
83-
app: webex-bot-mcp
84-
spec:
85-
containers:
86-
- name: webex-bot-mcp
87-
image: webex-bot-mcp:latest
88-
ports:
89-
- containerPort: 8000
90-
env:
91-
- name: WEBEX_ACCESS_TOKEN
92-
valueFrom:
93-
secretKeyRef:
94-
name: webex-secrets
95-
key: access-token
96-
resources:
97-
limits:
98-
memory: "512Mi"
99-
cpu: "500m"
100-
requests:
101-
memory: "256Mi"
102-
cpu: "250m"
103-
---
104-
apiVersion: v1
105-
kind: Service
106-
metadata:
107-
name: webex-bot-mcp-service
108-
spec:
109-
selector:
110-
app: webex-bot-mcp
111-
ports:
112-
- port: 80
113-
targetPort: 8000
114-
type: LoadBalancer
40+
**Option B — ECR:**
41+
```bash
42+
aws ecr create-repository --repository-name webex-bot-mcp
43+
# follow the ECR push commands shown in the console
11544
```
11645

117-
## Claude Desktop Configuration
46+
## 2. Security groups
47+
48+
Create two security groups.
11849

119-
Add to your Claude Desktop config:
50+
**ALB security group (`sg-alb`):**
51+
| Type | Protocol | Port | Source |
52+
|-------|----------|------|-----------|
53+
| HTTPS | TCP | 443 | 0.0.0.0/0 |
54+
55+
**EC2 security group (`sg-ec2`):**
56+
| Type | Protocol | Port | Source |
57+
|-------------|----------|------|----------|
58+
| Custom TCP | TCP | 8000 | sg-alb |
59+
| SSH | TCP | 22 | your IP |
60+
61+
Port 8000 is only reachable from the ALB — never directly from the internet.
62+
63+
## 3. ACM certificate
64+
65+
1. Go to **AWS Certificate Manager → Request certificate**
66+
2. Request a public certificate for your domain (e.g. `mcp.example.com`)
67+
3. Validate via DNS — add the CNAME record ACM gives you to your DNS provider
68+
4. Wait for status to show **Issued** before continuing
69+
70+
## 4. Target group
71+
72+
1. Go to **EC2 → Target Groups → Create target group**
73+
2. Settings:
74+
- Target type: **Instances**
75+
- Protocol: **HTTP**, Port: **8000**
76+
- Health check path: **`/health`**
77+
- Healthy threshold: 2, Unhealthy threshold: 3, Interval: 30s
78+
3. Register your EC2 instance as a target
79+
80+
## 5. Application Load Balancer
81+
82+
1. Go to **EC2 → Load Balancers → Create load balancer → Application Load Balancer**
83+
2. Settings:
84+
- Scheme: **Internet-facing**
85+
- IP address type: **IPv4**
86+
- VPC and subnets: select at least two AZs
87+
- Security group: `sg-alb`
88+
3. **Listeners:**
89+
- HTTPS :443 → forward to your target group
90+
- Select your ACM certificate
91+
4. Create the load balancer and note the DNS name (e.g. `my-alb-123456.us-east-1.elb.amazonaws.com`)
92+
93+
## 6. DNS
94+
95+
Add a CNAME record pointing your domain to the ALB DNS name:
96+
```
97+
mcp.example.com CNAME my-alb-123456.us-east-1.elb.amazonaws.com
98+
```
99+
100+
## 7. Run the container
101+
102+
On the EC2 instance:
103+
```bash
104+
cd webex-bot-mcp
105+
docker compose up -d
106+
```
107+
108+
No environment variables are required — each MCP client supplies its own Webex bot token
109+
via the `Authorization: Bearer` header. If you want to run in stdio mode on the same host
110+
you can still set `WEBEX_ACCESS_TOKEN` in a `.env` file.
111+
112+
## 8. Verify
113+
114+
```bash
115+
# Health check (no auth required)
116+
curl https://mcp.example.com/health
117+
# → {"status":"ok"}
118+
119+
# Confirm auth is enforced on the MCP endpoint
120+
curl https://mcp.example.com/mcp
121+
# → 401 Authorization: Bearer <webex_bot_token> header required
122+
```
123+
124+
## 9. MCP client configuration
125+
126+
Point your MCP client at the HTTPS URL. Example for Claude Desktop (`claude_desktop_config.json`):
120127

121128
```json
122129
{
123130
"mcpServers": {
124131
"webex-bot": {
125-
"command": "python",
126-
"args": ["/path/to/webex-bot-mcp/main.py"],
127-
"env": {
128-
"WEBEX_ACCESS_TOKEN": "your_token_here"
132+
"url": "https://mcp.example.com/mcp",
133+
"headers": {
134+
"Authorization": "Bearer <your_webex_bot_token>"
129135
}
130136
}
131137
}
132138
}
133139
```
134140

135-
## Common Issues & Solutions
136-
137-
### Issue: "Token Invalid" Errors
138-
**Solution**: Check token expiration, regenerate if needed, ensure proper environment variable setup.
139-
140-
### Issue: Rate Limiting
141-
**Solution**: Implement exponential backoff, respect API limits, consider request batching.
142-
143-
### Issue: Memory Usage
144-
**Solution**: Monitor for memory leaks, implement connection pooling, tune garbage collection.
145-
146-
### Issue: High Latency
147-
**Solution**: Use connection pooling, implement caching, optimize database queries if used.
148-
149-
## Performance Tuning
150-
151-
### Message Throughput Optimization
152-
- Use bulk operations where possible
153-
- Implement message queuing for high-volume scenarios
154-
- Consider async/await patterns for concurrent operations
155-
156-
### Resource Optimization
157-
- Connection pooling for HTTP transport
158-
- Memory-efficient data structures
159-
- Proper cleanup of resources
141+
Each user or team connects with their own Webex bot token. The server itself holds no token.
160142

161-
### Monitoring Metrics
162-
- Message send success rate
163-
- API response times
164-
- Error rates by operation type
165-
- Resource utilization (CPU, memory, network)
143+
## Environment variables reference
166144

167-
## Security Best Practices
145+
All variables are optional for HTTP transport.
168146

169-
### Token Management
170-
- Store tokens in secure key management systems
171-
- Implement token rotation automation
172-
- Monitor for token compromise
147+
| Variable | Default | Description |
148+
|---|---|---|
149+
| `WEBEX_ACCESS_TOKEN` || Token for stdio transport only |
150+
| `WEBEX_DEBUG` | `false` | Enable verbose logging |
151+
| `LOG_LEVEL` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |
152+
| `LOG_FORMAT` | `text` | `text` or `json` |
153+
| `METRICS_ENABLED` | `false` | Enable Prometheus metrics |
173154

174-
### Network Security
175-
- Use HTTPS only in production
176-
- Implement proper firewall rules
177-
- Consider VPN or private network deployment
155+
## Scaling note
178156

179-
### Data Protection
180-
- Encrypt sensitive data at rest
181-
- Implement audit logging
182-
- Follow data retention policies
183-
- Regular security assessments
157+
MCP sessions are stateful — a client initializes a session and reuses it for subsequent
158+
tool calls. If you run multiple EC2 instances behind the ALB, enable **sticky sessions**
159+
(duration-based) on the target group so all requests from one client land on the same
160+
instance. A single instance is fine for most deployments.

Dockerfile

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,44 @@
11
# Multi-stage build for Webex Bot MCP Server
2-
FROM python:3.12-slim as builder
2+
FROM python:3.12-slim AS builder
33

4-
# Install build dependencies
54
RUN apt-get update && apt-get install -y \
65
build-essential \
76
&& rm -rf /var/lib/apt/lists/*
87

9-
# Set working directory
108
WORKDIR /app
119

12-
# Copy requirements and install dependencies
13-
COPY pyproject.toml ./
14-
RUN pip install --no-cache-dir -e .
10+
# Copy everything needed for a PEP 517 build
11+
COPY pyproject.toml README.md ./
12+
COPY src/ ./src/
1513

16-
# Production stage
17-
FROM python:3.12-slim as production
14+
# Non-editable install so the package lands fully in site-packages
15+
RUN pip install --no-cache-dir .
16+
17+
18+
FROM python:3.12-slim AS production
1819

19-
# Create non-root user for security
2020
RUN groupadd -r webexbot && useradd -r -g webexbot webexbot
2121

22-
# Install runtime dependencies
2322
RUN apt-get update && apt-get install -y \
2423
ca-certificates \
2524
&& rm -rf /var/lib/apt/lists/*
2625

27-
# Set working directory
2826
WORKDIR /app
2927

30-
# Copy installed packages from builder
3128
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
32-
COPY --from=builder /usr/local/bin /usr/local/bin
29+
COPY --from=builder /usr/local/bin/webex-bot-mcp* /usr/local/bin/
3330

34-
# Copy application code
35-
COPY main.py ./
36-
COPY tools/ ./tools/
37-
COPY config.py ./
38-
COPY health_check.py ./
39-
COPY .env.template ./
40-
41-
# Change ownership to non-root user
4231
RUN chown -R webexbot:webexbot /app
4332

44-
# Switch to non-root user
4533
USER webexbot
4634

47-
# Create volume for configuration
48-
VOLUME ["/app/config"]
49-
50-
# Expose port for HTTP transport
5135
EXPOSE 8000
5236

53-
# Health check
5437
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
55-
CMD python health_check.py --skip-rooms --exit-code || exit 1
38+
CMD webex-bot-mcp-health --skip-api --exit-code || exit 1
5639

57-
# Default command
58-
CMD ["python", "main.py", "--transport", "streamable-http", "--host", "0.0.0.0", "--port", "8000"]
40+
CMD ["webex-bot-mcp", "--transport", "streamable-http", "--host", "0.0.0.0", "--port", "8000"]
5941

60-
# Metadata
6142
LABEL maintainer="Webex Bot MCP Team"
6243
LABEL description="Webex Bot Model Context Protocol Server"
6344
LABEL version="1.0.0"

0 commit comments

Comments
 (0)