- Add crush.json with comprehensive MCP configurations for Crush AI assistant - Configure stdio-based MCPs: penpot, context7, docker, drawio, redmine - Configure HTTP-based MCP: nextcloud (port 8083 with SSE endpoint) - Fix mcp-redmine Dockerfile with correct python module entrypoint - Fix nextcloud-mcp Dockerfile to handle .dockerignore blocking observability - Fix drawio-mcp Dockerfile to use pnpm and correct build directory - Update docker-compose.yml with proper MCP server configurations - Add environment variable configuration for MCPs requiring external services - Create MCP validation script to test servers with protocol messages - Update STATUS.md with confirmed working MCP servers and their requirements - Validate: penpot, context7, docker, drawio, redmine, nextcloud (HTTP) - Document required env vars for ghost, imap, proxmox, penpot MCPs - Configure Crush to use both stdio (docker run) and HTTP endpoints
130 lines
3.9 KiB
Markdown
130 lines
3.9 KiB
Markdown
# LSP Container Configuration
|
|
|
|
## Status
|
|
|
|
- **bash-language-server**: ✅ Working - Fixed crash by adding `start` command
|
|
- **docker-language-server**: ✅ Working - Fixed by adding `start --stdio` command
|
|
- **marksman**: ✅ Working - Fixed by adding `server` command
|
|
|
|
## Architecture Notes
|
|
|
|
### Why LSP Containers Don't Run Continuously
|
|
|
|
The bash, docker, and markdown LSP servers are **stdio-based LSP servers**. This means:
|
|
|
|
1. They communicate via stdin/stdout (not network sockets)
|
|
2. Each LSP client needs its own process instance
|
|
3. They exit when the client disconnects (end of stdin)
|
|
|
|
This is **by design** and is the standard way LSP servers work:
|
|
|
|
```
|
|
Crush Session 1 → docker run -i bash-lsp → [bash-language-server process]
|
|
Crush Session 2 → docker run -i bash-lsp → [bash-language-server process]
|
|
```
|
|
|
|
Each session needs its own container instance because the stdio connection is 1-to-1.
|
|
|
|
### Startup Performance
|
|
|
|
Despite creating new containers for each session, startup is fast because:
|
|
|
|
1. **Docker images are pre-built**: No build time
|
|
2. **Container creation is fast**: < 1 second typically
|
|
3. **Layers are cached**: All dependencies already present
|
|
|
|
The main delay only happens on the first startup when the image is built.
|
|
|
|
### Alternatives for Persistent Containers
|
|
|
|
If you truly need persistent containers to avoid all startup delay, you would need:
|
|
|
|
#### Option 1: TCP-based LSP Servers
|
|
- Modify LSP servers to listen on TCP ports instead of stdio
|
|
- Run containers in detached mode with exposed ports
|
|
- Connect to existing containers
|
|
|
|
Pros: Zero startup delay, true persistent containers
|
|
Cons: Requires modifying LSP servers or finding TCP-compatible alternatives
|
|
|
|
#### Option 2: Proxy Wrapper (Complex)
|
|
- Run containers in detached mode with a proxy process
|
|
- Proxy handles multiple Crush sessions
|
|
- Routes stdio between Crush and LSP servers
|
|
|
|
Pros: Persistent containers, no LSP server modifications
|
|
Cons: Complex implementation, potential performance overhead, single point of failure
|
|
|
|
#### Option 3: Current Implementation (Recommended)
|
|
- Run on-demand with `docker run -i --rm`
|
|
- Each Crush session gets its own container
|
|
- Fast startup with pre-built images
|
|
|
|
Pros: Simple, reliable, standard LSP architecture
|
|
Cons: ~1 second startup per session
|
|
|
|
## Configuration
|
|
|
|
The current `crush.json` configuration:
|
|
|
|
```json
|
|
{
|
|
"lsp": {
|
|
"bash": {
|
|
"command": "docker",
|
|
"args": ["run", "-i", "--rm", "kneldevstack-aimiddleware-bash-language-server", "start"]
|
|
},
|
|
"docker": {
|
|
"command": "docker",
|
|
"args": ["run", "-i", "--rm", "kneldevstack-aimiddleware-docker-language-server", "start", "--stdio"]
|
|
},
|
|
"markdown": {
|
|
"command": "docker",
|
|
"args": ["run", "-i", "--rm", "kneldevstack-aimiddleware-marksman", "server"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Key Points
|
|
|
|
- `-i`: Interactive mode (required for stdio)
|
|
- `--rm`: Remove container after exit (cleanup)
|
|
- Command arguments: `start`, `start --stdio`, `server` (varies by LSP)
|
|
|
|
## Troubleshooting
|
|
|
|
### "Container keeps crashing"
|
|
|
|
If you see LSP containers restarting repeatedly, check:
|
|
|
|
1. **Is the container configured for detached mode?**
|
|
- LSP servers should NOT run in detached mode
|
|
- They should be started on-demand via `docker run -i`
|
|
|
|
2. **Is the command specified?**
|
|
- `bash-language-server` needs `start`
|
|
- `docker-language-server` needs `start --stdio`
|
|
- `marksman` needs `server`
|
|
|
|
3. **Check crush.json configuration**
|
|
- Ensure all command arguments are included
|
|
- See configuration section above
|
|
|
|
### Testing LSP Servers
|
|
|
|
Test each LSP manually:
|
|
|
|
```bash
|
|
# Test bash LSP
|
|
echo '{}' | timeout 2 docker run -i --rm kneldevstack-aimiddleware-bash-language-server start
|
|
|
|
# Test docker LSP
|
|
echo '{}' | timeout 2 docker run -i --rm kneldevstack-aimiddleware-docker-language-server start --stdio
|
|
|
|
# Test marksman
|
|
echo '{}' | timeout 2 docker run -i --rm kneldevstack-aimiddleware-marksman server
|
|
```
|
|
|
|
Expected: Exit code 124 (timeout), meaning the LSP server is running and waiting for input.
|