Fix SSE endpoint and improve server deployment
- Enhanced SSE endpoint with better error handling and logging - Added comprehensive API info endpoint - Improved server startup logging with all endpoints - Updated Dockerfile to use SSE transport by default - Added debug script for SSE connection troubleshooting - Server now binds to 0.0.0.0 for better container compatibility
This commit is contained in:
@@ -31,5 +31,5 @@ EXPOSE 3000
|
|||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
||||||
|
|
||||||
# Default command - run HTTP server
|
# Default command - run HTTP server with SSE support
|
||||||
CMD ["node", "dist/index.js", "--transport", "http", "--port", "3000"]
|
CMD ["node", "dist/index.js", "--transport", "sse", "--port", "3000"]
|
||||||
|
@@ -7,7 +7,7 @@ A professional-grade Model Context Protocol (MCP) server for Rider-Waite tarot c
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"command": "npx",
|
"command": "npx",
|
||||||
"args": ["tarot-mcp-server"],
|
"args": ["tarot-mcp-server@latest"],
|
||||||
"env": {
|
"env": {
|
||||||
"NODE_ENV": "production"
|
"NODE_ENV": "production"
|
||||||
}
|
}
|
||||||
|
56
debug-sse.sh
Executable file
56
debug-sse.sh
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Debug script for SSE connection issues
|
||||||
|
|
||||||
|
SERVER_URL=${1:-"http://localhost:3000"}
|
||||||
|
|
||||||
|
echo "🔍 Debugging SSE connection to: $SERVER_URL"
|
||||||
|
echo "================================================"
|
||||||
|
|
||||||
|
# Test basic connectivity
|
||||||
|
echo "1. Testing basic connectivity..."
|
||||||
|
if curl -f "$SERVER_URL/health" > /dev/null 2>&1; then
|
||||||
|
echo "✅ Server is reachable"
|
||||||
|
curl -s "$SERVER_URL/health" | jq '.' 2>/dev/null || curl -s "$SERVER_URL/health"
|
||||||
|
else
|
||||||
|
echo "❌ Server is not reachable at $SERVER_URL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test API info endpoint
|
||||||
|
echo "2. Testing API info endpoint..."
|
||||||
|
if curl -f "$SERVER_URL/api/info" > /dev/null 2>&1; then
|
||||||
|
echo "✅ API info endpoint is working"
|
||||||
|
curl -s "$SERVER_URL/api/info" | jq '.' 2>/dev/null || curl -s "$SERVER_URL/api/info"
|
||||||
|
else
|
||||||
|
echo "❌ API info endpoint is not working"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test SSE endpoint
|
||||||
|
echo "3. Testing SSE endpoint..."
|
||||||
|
echo "Attempting to connect to SSE endpoint (will timeout after 5 seconds)..."
|
||||||
|
|
||||||
|
timeout 5s curl -N -H "Accept: text/event-stream" -H "Cache-Control: no-cache" "$SERVER_URL/sse" 2>&1 | head -10
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "4. Testing SSE endpoint with verbose output..."
|
||||||
|
curl -v -N -H "Accept: text/event-stream" -H "Cache-Control: no-cache" "$SERVER_URL/sse" 2>&1 | head -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================"
|
||||||
|
echo "🔍 Debug complete!"
|
||||||
|
echo ""
|
||||||
|
echo "If you see 404 errors, check:"
|
||||||
|
echo "1. Server is running in HTTP/SSE mode (not stdio)"
|
||||||
|
echo "2. Server is listening on the correct port"
|
||||||
|
echo "3. No reverse proxy is interfering"
|
||||||
|
echo "4. Firewall allows the connection"
|
||||||
|
echo ""
|
||||||
|
echo "Expected SSE response should include:"
|
||||||
|
echo "- HTTP 200 status"
|
||||||
|
echo "- Content-Type: text/event-stream"
|
||||||
|
echo "- Connection: keep-alive"
|
@@ -89,14 +89,60 @@ export class TarotHttpServer {
|
|||||||
* Setup HTTP routes
|
* Setup HTTP routes
|
||||||
*/
|
*/
|
||||||
private setupRoutes(): void {
|
private setupRoutes(): void {
|
||||||
|
// Health check endpoint
|
||||||
this.app.get('/health', (req, res) => {
|
this.app.get('/health', (req, res) => {
|
||||||
res.json({ status: 'ok' });
|
res.json({
|
||||||
|
status: 'ok',
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
endpoints: {
|
||||||
|
sse: '/sse',
|
||||||
|
mcp: '/mcp',
|
||||||
|
health: '/health',
|
||||||
|
api: {
|
||||||
|
reading: '/api/reading',
|
||||||
|
customSpread: '/api/custom-spread',
|
||||||
|
info: '/api/info'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// SSE endpoint
|
// API info endpoint
|
||||||
|
this.app.get('/api/info', (req, res) => {
|
||||||
|
res.json({
|
||||||
|
name: 'Tarot MCP Server',
|
||||||
|
version: '1.0.0',
|
||||||
|
capabilities: ['tools'],
|
||||||
|
tools: this.tarotServer.getAvailableTools(),
|
||||||
|
endpoints: {
|
||||||
|
sse: '/sse',
|
||||||
|
mcp: '/mcp',
|
||||||
|
health: '/health'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// SSE endpoint for MCP
|
||||||
this.app.get('/sse', async (req, res) => {
|
this.app.get('/sse', async (req, res) => {
|
||||||
|
try {
|
||||||
|
console.log('SSE connection request received');
|
||||||
const transport = new SSEServerTransport('/sse', res);
|
const transport = new SSEServerTransport('/sse', res);
|
||||||
await this.server.connect(transport);
|
await this.server.connect(transport);
|
||||||
|
console.log('SSE connection established');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('SSE connection error:', error);
|
||||||
|
res.status(500).json({ error: 'Failed to establish SSE connection' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// MCP HTTP endpoint (alternative to SSE)
|
||||||
|
this.app.post('/mcp', async (req, res) => {
|
||||||
|
try {
|
||||||
|
// This would need proper MCP HTTP transport implementation
|
||||||
|
res.json({ message: 'MCP HTTP endpoint - not yet implemented' });
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ error: error instanceof Error ? error.message : String(error) });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Example of a direct API endpoint
|
// Example of a direct API endpoint
|
||||||
@@ -133,9 +179,12 @@ export class TarotHttpServer {
|
|||||||
*/
|
*/
|
||||||
public async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.app.listen(this.port, () => {
|
this.app.listen(this.port, '0.0.0.0', () => {
|
||||||
console.log(`Tarot MCP Server running on http://localhost:${this.port}`);
|
console.log(`🔮 Tarot MCP Server running on http://0.0.0.0:${this.port}`);
|
||||||
console.log(`SSE endpoint available at http://localhost:${this.port}/sse`);
|
console.log(`📡 SSE endpoint: http://0.0.0.0:${this.port}/sse`);
|
||||||
|
console.log(`🔧 MCP endpoint: http://0.0.0.0:${this.port}/mcp`);
|
||||||
|
console.log(`❤️ Health check: http://0.0.0.0:${this.port}/health`);
|
||||||
|
console.log(`📋 API info: http://0.0.0.0:${this.port}/api/info`);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user