mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-25 03:43:08 +00:00
fix: Docker stdio communication for Claude Desktop compatibility
Fixed the initialization timeout issue with minimal changes: 1. Added stdout flush after server connection to combat Docker buffering 2. Fixed docker-entrypoint.sh to not output to stdout in stdio mode 3. Added process.stdin.resume() to keep server alive 4. Added IS_DOCKER environment variable for future use 5. Updated README to prioritize Docker with correct -i flag configuration The core issue was Docker's block buffering preventing immediate JSON-RPC responses. The -i flag maintains stdin connection, and explicit flushing ensures responses reach Claude Desktop immediately. Also fixed "Shutting down..." message that was breaking JSON-RPC protocol by redirecting it to stderr in stdio mode. Docker is now the recommended installation method as originally intended. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,9 @@ RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|||||||
# Switch to non-root user
|
# Switch to non-root user
|
||||||
USER nodejs
|
USER nodejs
|
||||||
|
|
||||||
|
# Set Docker environment flag
|
||||||
|
ENV IS_DOCKER=true
|
||||||
|
|
||||||
# Expose HTTP port
|
# Expose HTTP port
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
|||||||
59
README.md
59
README.md
@@ -35,7 +35,45 @@ When Claude, Anthropic's AI assistant, tested n8n-MCP, the results were transfor
|
|||||||
|
|
||||||
Get n8n-MCP running in 5 minutes:
|
Get n8n-MCP running in 5 minutes:
|
||||||
|
|
||||||
### Option 1: Local Installation (Recommended)
|
### Option 1: Docker (Easiest)
|
||||||
|
|
||||||
|
**Prerequisites:** [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed on your system
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull the Docker image
|
||||||
|
docker pull ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Add to Claude Desktop config:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"n8n-mcp": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"-i",
|
||||||
|
"--rm",
|
||||||
|
"-e", "MCP_MODE=stdio",
|
||||||
|
"-e", "LOG_LEVEL=error",
|
||||||
|
"-e", "DISABLE_CONSOLE_OUTPUT=true",
|
||||||
|
"ghcr.io/czlonkowski/n8n-mcp:latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** The `-i` flag is required for MCP stdio communication.
|
||||||
|
|
||||||
|
**Configuration file locations:**
|
||||||
|
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||||
|
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||||
|
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
||||||
|
|
||||||
|
**Restart Claude Desktop after updating configuration** - That's it! 🎉
|
||||||
|
|
||||||
|
### Option 2: Local Installation
|
||||||
|
|
||||||
**Prerequisites:** [Node.js](https://nodejs.org/) installed on your system
|
**Prerequisites:** [Node.js](https://nodejs.org/) installed on your system
|
||||||
|
|
||||||
@@ -63,25 +101,6 @@ Add to Claude Desktop config:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Option 2: Docker (Experimental)
|
|
||||||
|
|
||||||
⚠️ **Known Issue**: Docker support has a timeout issue with MCP initialization. The server doesn't respond to Claude's initialize request within 60 seconds, causing connection failures. Use local installation until this is resolved.
|
|
||||||
|
|
||||||
For brave souls who want to help debug:
|
|
||||||
```bash
|
|
||||||
docker pull ghcr.io/czlonkowski/n8n-mcp:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
See [Issue #X](https://github.com/czlonkowski/n8n-mcp/issues) for updates.
|
|
||||||
|
|
||||||
### Configuration File Locations
|
|
||||||
|
|
||||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
||||||
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
||||||
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
||||||
|
|
||||||
**Remember to restart Claude Desktop after updating configuration!** 🎉
|
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,12 @@ if [ "$(id -u)" = "0" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Trap signals for graceful shutdown
|
# Trap signals for graceful shutdown
|
||||||
trap 'echo "Shutting down..."; kill -TERM $PID' TERM INT
|
# In stdio mode, don't output anything to stdout as it breaks JSON-RPC
|
||||||
|
if [ "$MCP_MODE" = "stdio" ]; then
|
||||||
|
trap 'kill -TERM $PID 2>/dev/null' TERM INT
|
||||||
|
else
|
||||||
|
trap 'echo "Shutting down..." >&2; kill -TERM $PID' TERM INT
|
||||||
|
fi
|
||||||
|
|
||||||
# Execute the main command in background
|
# Execute the main command in background
|
||||||
"$@" &
|
"$@" &
|
||||||
|
|||||||
163
docs/DOCKER_FIX_IMPLEMENTATION.md
Normal file
163
docs/DOCKER_FIX_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# Docker stdio Fix Implementation Plan for n8n-MCP
|
||||||
|
|
||||||
|
Based on community research and successful MCP Docker deployments, here's a streamlined fix for the initialization timeout issue.
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
|
||||||
|
Docker treats container stdout as a pipe (not TTY), causing block buffering. The MCP server's JSON-RPC responses sit in the buffer instead of being immediately sent to Claude Desktop, causing a 60-second timeout.
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
|
||||||
|
### Step 1: Test Simple Interactive Mode
|
||||||
|
|
||||||
|
First, verify if just using `-i` flag solves the issue:
|
||||||
|
|
||||||
|
**Update README.md:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"n8n-mcp": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"-i", // Interactive mode - keeps stdin open
|
||||||
|
"--rm",
|
||||||
|
"-e", "MCP_MODE=stdio",
|
||||||
|
"-e", "LOG_LEVEL=error",
|
||||||
|
"-e", "DISABLE_CONSOLE_OUTPUT=true",
|
||||||
|
"ghcr.io/czlonkowski/n8n-mcp:latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Test command:**
|
||||||
|
```bash
|
||||||
|
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05"},"id":1}' | \
|
||||||
|
docker run -i --rm \
|
||||||
|
-e MCP_MODE=stdio \
|
||||||
|
-e LOG_LEVEL=error \
|
||||||
|
-e DISABLE_CONSOLE_OUTPUT=true \
|
||||||
|
ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: Should receive a JSON response immediately.
|
||||||
|
|
||||||
|
### Step 2: Add Explicit Stdout Flushing (If Needed)
|
||||||
|
|
||||||
|
If Step 1 doesn't work, add minimal flushing to the Node.js server:
|
||||||
|
|
||||||
|
**File: `src/mcp/server-update.ts`**
|
||||||
|
|
||||||
|
Update the `run()` method:
|
||||||
|
```typescript
|
||||||
|
async run(): Promise<void> {
|
||||||
|
await this.ensureInitialized();
|
||||||
|
|
||||||
|
const transport = new StdioServerTransport();
|
||||||
|
await this.server.connect(transport);
|
||||||
|
|
||||||
|
// Ensure stdout is not buffered in Docker
|
||||||
|
if (!process.stdout.isTTY && process.env.IS_DOCKER) {
|
||||||
|
// Force unbuffered stdout
|
||||||
|
process.stdout.write('');
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('n8n Documentation MCP Server running on stdio transport');
|
||||||
|
|
||||||
|
// Keep process alive
|
||||||
|
process.stdin.resume();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**File: `Dockerfile`**
|
||||||
|
|
||||||
|
Add environment variable:
|
||||||
|
```dockerfile
|
||||||
|
ENV IS_DOCKER=true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: System-Level Unbuffering (Last Resort)
|
||||||
|
|
||||||
|
Only if Steps 1-2 fail, implement stdbuf wrapper:
|
||||||
|
|
||||||
|
**File: `docker-entrypoint.sh`**
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
# Force line buffering for stdio communication
|
||||||
|
exec stdbuf -oL -eL node /app/dist/mcp/index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
**File: `Dockerfile`**
|
||||||
|
```dockerfile
|
||||||
|
# Add stdbuf utility
|
||||||
|
RUN apk add --no-cache coreutils
|
||||||
|
|
||||||
|
# Copy and setup entrypoint
|
||||||
|
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
|
RUN chmod +x /docker-entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Protocol
|
||||||
|
|
||||||
|
### 1. Local Docker Test
|
||||||
|
```bash
|
||||||
|
# Build test image
|
||||||
|
docker build -t n8n-mcp:test .
|
||||||
|
|
||||||
|
# Test with echo pipe
|
||||||
|
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05"},"id":1}' | \
|
||||||
|
docker run -i --rm n8n-mcp:test | head -1
|
||||||
|
|
||||||
|
# Should see immediate JSON response
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Claude Desktop Test
|
||||||
|
1. Update `claude_desktop_config.json` with new configuration
|
||||||
|
2. Restart Claude Desktop
|
||||||
|
3. Check Developer tab for "running" status
|
||||||
|
4. Test a simple MCP command
|
||||||
|
|
||||||
|
### 3. Debug if Needed
|
||||||
|
```bash
|
||||||
|
# Run with stderr output for debugging
|
||||||
|
docker run -i --rm \
|
||||||
|
-e MCP_MODE=stdio \
|
||||||
|
-e LOG_LEVEL=debug \
|
||||||
|
ghcr.io/czlonkowski/n8n-mcp:latest 2>debug.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
- [ ] No timeout errors in Claude Desktop logs
|
||||||
|
- [ ] MCP tools are accessible immediately
|
||||||
|
- [ ] No "Shutting down..." messages in stdout
|
||||||
|
- [ ] Simple `-i` flag configuration works
|
||||||
|
|
||||||
|
## Rollout Plan
|
||||||
|
|
||||||
|
1. **Test locally** with simple `-i` flag first
|
||||||
|
2. **Update Docker image** only if code changes needed
|
||||||
|
3. **Update README** with working configuration
|
||||||
|
4. **Community announcement** with simple Docker instructions
|
||||||
|
|
||||||
|
## Key Insights from Research
|
||||||
|
|
||||||
|
- Most MCP Docker deployments work with just `-i` flag
|
||||||
|
- Complex solutions often unnecessary
|
||||||
|
- Node.js typically doesn't need explicit unbuffering (unlike Python with `-u`)
|
||||||
|
- Claude Desktop only supports stdio for local servers (not HTTP)
|
||||||
|
- Proper testing can quickly identify if buffering is the actual issue
|
||||||
|
|
||||||
|
## What NOT to Do
|
||||||
|
|
||||||
|
- Don't add TTY flag (`-t`) - it's for terminal UI, not needed for MCP
|
||||||
|
- Don't implement complex multi-phase solutions
|
||||||
|
- Don't switch to HTTP transport (Claude Desktop doesn't support it locally)
|
||||||
|
- Don't modify MCP protocol handling
|
||||||
|
- Don't add unnecessary wrapper scripts unless proven necessary
|
||||||
|
|
||||||
|
The solution should be as simple as possible - likely just the `-i` flag in the Docker command.
|
||||||
252
docs/DOCKER_MCP_FIX_PLAN.md
Normal file
252
docs/DOCKER_MCP_FIX_PLAN.md
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
# Docker MCP Initialization Timeout Fix Plan
|
||||||
|
|
||||||
|
## Problem Summary
|
||||||
|
|
||||||
|
The n8n-MCP Docker container fails to work with Claude Desktop due to MCP initialization timeout:
|
||||||
|
|
||||||
|
1. Claude sends `initialize` request
|
||||||
|
2. Server receives it (logs show "Message from client: {"method":"initialize"...}")
|
||||||
|
3. Server appears to connect successfully
|
||||||
|
4. **No response is sent back to Claude**
|
||||||
|
5. Claude times out after 60 seconds
|
||||||
|
6. Container outputs "Shutting down..." which breaks JSON-RPC protocol
|
||||||
|
|
||||||
|
## Root Cause Analysis
|
||||||
|
|
||||||
|
### 1. **Stdout Buffering in Docker**
|
||||||
|
|
||||||
|
Docker containers often buffer stdout, especially when not running with TTY (`-t` flag). This is the most likely culprit:
|
||||||
|
|
||||||
|
- Node.js/JavaScript may buffer stdout when not connected to a TTY
|
||||||
|
- Docker's stdout handling differs from direct execution
|
||||||
|
- The MCP response might be stuck in the buffer
|
||||||
|
|
||||||
|
**Evidence:**
|
||||||
|
- Common Docker issue (moby/moby#1385, docker/compose#1549)
|
||||||
|
- Python requires `-u` flag for unbuffered output in Docker
|
||||||
|
- Different base images have different buffering behavior
|
||||||
|
|
||||||
|
### 2. **MCP SDK Server Connection Issue**
|
||||||
|
|
||||||
|
The server might not be properly completing the connection handshake:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const transport = new StdioServerTransport();
|
||||||
|
await server.connect(transport); // This might not complete properly
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Missing Initialize Handler**
|
||||||
|
|
||||||
|
While the MCP SDK should handle `initialize` automatically, there might be an issue with:
|
||||||
|
- Handler registration order
|
||||||
|
- Server capabilities configuration
|
||||||
|
- Transport initialization timing
|
||||||
|
|
||||||
|
### 4. **Process Lifecycle Management**
|
||||||
|
|
||||||
|
The container might be:
|
||||||
|
- Exiting too early
|
||||||
|
- Not keeping the event loop alive
|
||||||
|
- Missing proper signal handling
|
||||||
|
|
||||||
|
## Fixing Plan
|
||||||
|
|
||||||
|
### Phase 1: Immediate Fixes (High Priority)
|
||||||
|
|
||||||
|
#### 1.1 Force Stdout Flushing
|
||||||
|
|
||||||
|
**File:** `src/mcp/server-update.ts`
|
||||||
|
|
||||||
|
Add explicit stdout flushing after server connection:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async run(): Promise<void> {
|
||||||
|
await this.ensureInitialized();
|
||||||
|
|
||||||
|
const transport = new StdioServerTransport();
|
||||||
|
await this.server.connect(transport);
|
||||||
|
|
||||||
|
// Force flush stdout
|
||||||
|
if (process.stdout.isTTY === false) {
|
||||||
|
process.stdout.write('', () => {}); // Force flush
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('n8n Documentation MCP Server running on stdio transport');
|
||||||
|
|
||||||
|
// Keep process alive
|
||||||
|
process.stdin.resume();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 Add TTY Support to Docker
|
||||||
|
|
||||||
|
**File:** `Dockerfile`
|
||||||
|
|
||||||
|
Add environment variable to detect Docker:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
ENV IS_DOCKER=true
|
||||||
|
ENV NODE_OPTIONS="--max-old-space-size=2048"
|
||||||
|
```
|
||||||
|
|
||||||
|
**File:** Update Docker command in README
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"n8n-mcp": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-i",
|
||||||
|
"-t", // Add TTY allocation
|
||||||
|
"--init", // Proper signal handling
|
||||||
|
"-e", "MCP_MODE=stdio",
|
||||||
|
"-e", "LOG_LEVEL=error",
|
||||||
|
"-e", "DISABLE_CONSOLE_OUTPUT=true",
|
||||||
|
"ghcr.io/czlonkowski/n8n-mcp:latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 2: Robust Fixes (Medium Priority)
|
||||||
|
|
||||||
|
#### 2.1 Implement Explicit Initialize Handler
|
||||||
|
|
||||||
|
**File:** `src/mcp/server-update.ts`
|
||||||
|
|
||||||
|
Add explicit initialize handler to ensure response:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import {
|
||||||
|
InitializeRequestSchema,
|
||||||
|
InitializeResult
|
||||||
|
} from '@modelcontextprotocol/sdk/types.js';
|
||||||
|
|
||||||
|
private setupHandlers(): void {
|
||||||
|
// Add explicit initialize handler
|
||||||
|
this.server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
||||||
|
logger.debug('Handling initialize request', request);
|
||||||
|
|
||||||
|
const result: InitializeResult = {
|
||||||
|
protocolVersion: "2024-11-05",
|
||||||
|
capabilities: {
|
||||||
|
tools: {}
|
||||||
|
},
|
||||||
|
serverInfo: {
|
||||||
|
name: "n8n-documentation-mcp",
|
||||||
|
version: "1.0.0"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Force immediate flush
|
||||||
|
if (process.stdout.isTTY === false) {
|
||||||
|
process.stdout.write('', () => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ... existing handlers
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 Add Docker-Specific Stdio Handling
|
||||||
|
|
||||||
|
**File:** Create `src/utils/docker-stdio.ts`
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class DockerStdioTransport extends StdioServerTransport {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Disable buffering for Docker
|
||||||
|
if (process.env.IS_DOCKER === 'true') {
|
||||||
|
process.stdout.setDefaultEncoding('utf8');
|
||||||
|
if (process.stdout._handle && process.stdout._handle.setBlocking) {
|
||||||
|
process.stdout._handle.setBlocking(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async writeMessage(message: string): Promise<void> {
|
||||||
|
await super.writeMessage(message);
|
||||||
|
|
||||||
|
// Force flush in Docker
|
||||||
|
if (process.env.IS_DOCKER === 'true') {
|
||||||
|
process.stdout.write('', () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 3: Alternative Approaches (Low Priority)
|
||||||
|
|
||||||
|
#### 3.1 Use Wrapper Script
|
||||||
|
|
||||||
|
Create a Node.js wrapper that ensures proper buffering:
|
||||||
|
|
||||||
|
**File:** `docker-entrypoint.js`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Disable all buffering
|
||||||
|
process.stdout._handle?.setBlocking?.(true);
|
||||||
|
process.stdin.setRawMode?.(false);
|
||||||
|
|
||||||
|
// Import and run the actual server
|
||||||
|
require('./dist/mcp/index.js');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 Switch to HTTP Transport for Docker
|
||||||
|
|
||||||
|
Consider using HTTP transport instead of stdio for Docker deployments, as it doesn't have buffering issues.
|
||||||
|
|
||||||
|
## Testing Plan
|
||||||
|
|
||||||
|
1. **Local Testing:**
|
||||||
|
```bash
|
||||||
|
# Test with Docker TTY
|
||||||
|
docker run -it --rm ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
|
||||||
|
# Test initialize response
|
||||||
|
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05"},"id":1}' | \
|
||||||
|
docker run -i --rm ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Claude Desktop Testing:**
|
||||||
|
- Apply fixes incrementally
|
||||||
|
- Test with each configuration change
|
||||||
|
- Monitor Claude Desktop logs
|
||||||
|
|
||||||
|
3. **Debug Output:**
|
||||||
|
Add temporary debug logging to stderr:
|
||||||
|
```typescript
|
||||||
|
console.error('DEBUG: Received initialize');
|
||||||
|
console.error('DEBUG: Sending response');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation Priority
|
||||||
|
|
||||||
|
1. **Immediate:** Add `-t` flag to Docker command (no code changes)
|
||||||
|
2. **High:** Force stdout flushing in server code
|
||||||
|
3. **Medium:** Add explicit initialize handler
|
||||||
|
4. **Low:** Create Docker-specific transport class
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
- Claude Desktop connects without timeout
|
||||||
|
- No "Shutting down..." message in JSON stream
|
||||||
|
- Tools are accessible after connection
|
||||||
|
- Connection remains stable
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Docker stdout buffering issue](https://github.com/moby/moby/issues/1385)
|
||||||
|
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
|
||||||
|
- [Python unbuffered mode in Docker](https://stackoverflow.com/questions/39486327/stdout-being-buffered-in-docker-container)
|
||||||
|
- [MCP initialization timeout issues](https://github.com/modelcontextprotocol/servers/issues/57)
|
||||||
@@ -912,6 +912,17 @@ Full documentation is being prepared. For now, use get_node_essentials for confi
|
|||||||
|
|
||||||
const transport = new StdioServerTransport();
|
const transport = new StdioServerTransport();
|
||||||
await this.server.connect(transport);
|
await this.server.connect(transport);
|
||||||
|
|
||||||
|
// Force flush stdout for Docker environments
|
||||||
|
// Docker uses block buffering which can delay MCP responses
|
||||||
|
if (!process.stdout.isTTY) {
|
||||||
|
// Write empty string to force flush
|
||||||
|
process.stdout.write('', () => {});
|
||||||
|
}
|
||||||
|
|
||||||
logger.info('n8n Documentation MCP Server running on stdio transport');
|
logger.info('n8n Documentation MCP Server running on stdio transport');
|
||||||
|
|
||||||
|
// Keep the process alive and listening
|
||||||
|
process.stdin.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user