Skip to content

Commit 31e87a4

Browse files
committed
fix: add critical SSE headers and fix CORS for ChatGPT
- Add X-Accel-Buffering: no header to prevent nginx buffering - Add immediate keepalive comment on SSE connection - Add Access-Control-Allow-Methods and Allow-Headers - Fix CORS configuration to always enable (not conditional) - Change docker-compose to always enable CORS in production - Update .env and .env.example with proper CORS defaults Fixes ChatGPT MCP connector timeout issue.
1 parent 0a7d16f commit 31e87a4

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

.env.example

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ IOT_API_KEY=your-api-key-here
1414
IOT_API_TIMEOUT=30000
1515

1616
# CORS Configuration
17-
# Enable CORS for cross-origin requests
17+
# Enable CORS for cross-origin requests (required for ChatGPT/Claude)
1818
ENABLE_CORS=true
1919

2020
# Comma-separated list of allowed origins
21-
# Use * to allow all origins (not recommended for production)
22-
CORS_ORIGINS=http://localhost:3000,https://chat.openai.com,https://claude.ai
21+
# Use * to allow all origins (recommended for MCP servers)
22+
# Or specify: https://chat.openai.com,https://claude.ai
23+
CORS_ORIGINS=*
2324

2425
# Rate Limiting
2526
# Enable rate limiting to prevent abuse

docker-compose.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ services:
88
ports:
99
- '${PORT:-3001}:3001'
1010
environment:
11-
# Server Configuration
11+
# Server
1212
NODE_ENV: ${NODE_ENV:-production}
13-
PORT: 3001
14-
HOST: 0.0.0.0
13+
PORT: ${PORT:-3001}
14+
HOST: ${HOST:-0.0.0.0}
1515

1616
# IoT Cloud API
1717
IOT_API_BASE_URL: ${IOT_API_BASE_URL}
1818
IOT_API_KEY: ${IOT_API_KEY}
1919
IOT_API_TIMEOUT: ${IOT_API_TIMEOUT:-30000}
2020

21-
# CORS Configuration
22-
ENABLE_CORS: ${ENABLE_CORS:-true}
21+
# CORS Configuration (always enabled for MCP)
22+
ENABLE_CORS: 'true'
2323
CORS_ORIGINS: ${CORS_ORIGINS:-*}
2424

2525
# Rate Limiting

src/api/controllers/mcp.controller.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ export class McpController {
2525
description: 'SSE stream established',
2626
})
2727
async streamMcpEvents(@Req() req: Request, @Res() res: Response): Promise<void> {
28-
// Set SSE headers
28+
// Set SSE headers (ChatGPT-compatible)
2929
res.setHeader('Content-Type', 'text/event-stream');
3030
res.setHeader('Cache-Control', 'no-cache');
3131
res.setHeader('Connection', 'keep-alive');
32+
res.setHeader('X-Accel-Buffering', 'no'); // Prevent nginx buffering
3233
res.setHeader('Access-Control-Allow-Origin', '*');
34+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
35+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
36+
37+
// Send immediate keepalive to prevent timeout
38+
res.write(': keepalive\n\n');
3339

3440
// Store connection state
3541
const connectionState = {

src/main.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ async function bootstrap() {
99

1010
const configService = app.get(ConfigService);
1111

12-
// Enable CORS
13-
const enableCors = configService.get<string>('ENABLE_CORS') === 'true';
14-
if (enableCors) {
15-
const origins = configService.get<string>('CORS_ORIGINS')?.split(',') || [];
16-
app.enableCors({
17-
origin: origins,
18-
credentials: true,
19-
});
20-
}
12+
// Enable CORS (always enable for MCP compatibility)
13+
const enableCors = configService.get<string>('ENABLE_CORS') !== 'false';
14+
const origins = configService.get<string>('CORS_ORIGINS')?.split(',') || ['*'];
15+
16+
app.enableCors({
17+
origin: origins.length > 0 && origins[0] !== '*' ? origins : '*',
18+
methods: ['GET', 'POST', 'OPTIONS'],
19+
allowedHeaders: ['Content-Type', 'Authorization', 'Accept'],
20+
credentials: true,
21+
});
2122

2223
// Global validation pipe
2324
app.useGlobalPipes(

0 commit comments

Comments
 (0)