Compare commits
6 Commits
576a582b21
...
30cbbeb90c
| Author | SHA1 | Date | |
|---|---|---|---|
| 30cbbeb90c | |||
| cfca7e6342 | |||
| add39a2671 | |||
| bc96cb4c02 | |||
| c583ed38eb | |||
| 23bc39f082 |
34
AGENTS.md
34
AGENTS.md
@@ -173,8 +173,42 @@ When working on any MCP server:
|
|||||||
- Service names are lowercase for Docker Compose compatibility
|
- Service names are lowercase for Docker Compose compatibility
|
||||||
- Each agent is validated individually before moving to the next
|
- Each agent is validated individually before moving to the next
|
||||||
- Vendor directory is gitignored to avoid committing cloned repositories
|
- Vendor directory is gitignored to avoid committing cloned repositories
|
||||||
|
- **Dockerfile Management**: Custom Dockerfiles created for vendors must be saved in the `dockerfiles/` directory with a corresponding subdirectory structure (e.g., `dockerfiles/bash-language-server/Dockerfile`). These are tracked in git, while vendor/* is not.
|
||||||
- **KiCAD MCP** is host-only - requires KiCAD to be installed on host machine and connects via TCP
|
- **KiCAD MCP** is host-only - requires KiCAD to be installed on host machine and connects via TCP
|
||||||
|
|
||||||
|
### Crush Integration
|
||||||
|
|
||||||
|
All LSP and MCP instances must be configured in `crush.json` for Crush to use them. The configuration file uses the following format:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"$schema": "https://charm.land/crush.json",
|
||||||
|
"lsp": {
|
||||||
|
"bash": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": ["run", "-i", "--rm", "KNELDevStack-AIMiddleware-bash-language-server"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mcp": {
|
||||||
|
"docker": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": ["run", "-i", "--rm", "KNELDevStack-AIMiddleware-docker-mcp"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration Priority:**
|
||||||
|
1. `.crush.json` (project-local)
|
||||||
|
2. `crush.json` (project-local)
|
||||||
|
3. `$HOME/.config/crush/crush.json` (global)
|
||||||
|
|
||||||
|
**For Docker-based LSP/MCP instances:**
|
||||||
|
- Use `docker` as the command
|
||||||
|
- Include container name as the main argument
|
||||||
|
- Use `-i` for interactive mode (required for stdio communication)
|
||||||
|
- Use `--rm` to automatically clean up containers after use
|
||||||
|
|
||||||
## Validation Checklist
|
## Validation Checklist
|
||||||
|
|
||||||
For each agent, verify:
|
For each agent, verify:
|
||||||
|
|||||||
291
README.md
291
README.md
@@ -1,3 +1,292 @@
|
|||||||
# KNEL-AIMiddleware
|
# KNEL-AIMiddleware
|
||||||
|
|
||||||
MCP and LSP infrastructure for OpenWebUI and Crush to utilize
|
[](https://www.docker.com/)
|
||||||
|
[](LICENSE)
|
||||||
|
[](https://modelcontextprotocol.io/)
|
||||||
|
[](https://microsoft.github.io/language-server-protocol/)
|
||||||
|
|
||||||
|
> MCP and LSP infrastructure for OpenWebUI and Crush to utilize
|
||||||
|
|
||||||
|
## 📖 Overview
|
||||||
|
|
||||||
|
KNEL-AIMiddleware is a comprehensive Docker-based infrastructure for running **Model Context Protocol (MCP)** servers and **Language Server Protocol (LSP)** providers. It enables AI assistants like OpenWebUI and Crush to seamlessly integrate with external tools, services, and code intelligence.
|
||||||
|
|
||||||
|
### 🎯 Use Cases
|
||||||
|
|
||||||
|
- **OpenWebUI Integration**: Provide MCP servers for enhanced AI context and tooling
|
||||||
|
- **Crush Integration**: LSP servers for intelligent code completion and analysis
|
||||||
|
- **Development**: Individual server isolation for easy debugging and updates
|
||||||
|
- **Production**: Scalable, containerized service deployment
|
||||||
|
|
||||||
|
## 🚀 Features
|
||||||
|
|
||||||
|
- ✅ **Modular Architecture**: Each service runs in its own container
|
||||||
|
- ✅ **Docker Compose**: Easy orchestration and management
|
||||||
|
- ✅ **Prebuilt Images**: Optimized container images with minimal dependencies
|
||||||
|
- ✅ **Crush Ready**: Pre-configured LSP servers for `crush.json`
|
||||||
|
- ✅ **Environment Variables**: Secure configuration via `.env` file
|
||||||
|
- ✅ **Health Monitoring**: Built-in logging and container health checks
|
||||||
|
|
||||||
|
## 📊 Server Status
|
||||||
|
|
||||||
|
For detailed build and configuration status of all MCP/LSP servers, see [STATUS.md](STATUS.md).
|
||||||
|
|
||||||
|
## 📦 Installation
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/get-docker/) 20.10+
|
||||||
|
- [Docker Compose](https://docs.docker.com/compose/install/) 2.0+
|
||||||
|
- (Optional) [Crush](https://github.com/charmbracelet/crush) for LSP integration
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
|
||||||
|
1. **Clone the repository**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/KNEL/KNEL-AIMiddleware.git
|
||||||
|
cd KNEL-AIMiddleware
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure environment variables**
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your API keys and configurations
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Build and start services**
|
||||||
|
```bash
|
||||||
|
# Start all built services
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Or start specific service
|
||||||
|
docker compose up -d <service-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💻 Usage
|
||||||
|
|
||||||
|
### Docker Compose Commands
|
||||||
|
|
||||||
|
#### Build and Start
|
||||||
|
```bash
|
||||||
|
# Build specific service
|
||||||
|
docker compose build <service-name>
|
||||||
|
|
||||||
|
# Build without cache
|
||||||
|
docker compose build --no-cache <service-name>
|
||||||
|
|
||||||
|
# Start service (detached mode)
|
||||||
|
docker compose up -d <service-name>
|
||||||
|
|
||||||
|
# Start all services
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
#### View Logs
|
||||||
|
```bash
|
||||||
|
# Follow logs for service
|
||||||
|
docker compose logs -f <service-name>
|
||||||
|
|
||||||
|
# View last 100 lines
|
||||||
|
docker compose logs --tail 100 <service-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Stop and Clean
|
||||||
|
```bash
|
||||||
|
# Stop service
|
||||||
|
docker compose stop <service-name>
|
||||||
|
|
||||||
|
# Remove service (also deletes container)
|
||||||
|
docker compose rm -f <service-name>
|
||||||
|
|
||||||
|
# Stop all services
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Remove all volumes
|
||||||
|
docker compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Profiles
|
||||||
|
|
||||||
|
Services are organized into profiles for selective startup:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development services (LSP + MCP)
|
||||||
|
docker compose --profile dev up
|
||||||
|
|
||||||
|
# Production services
|
||||||
|
docker compose --profile prod up
|
||||||
|
|
||||||
|
# Design tools (KiCAD, Blender, etc.)
|
||||||
|
docker compose --profile design up
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Crush Integration
|
||||||
|
|
||||||
|
All LSP and MCP instances must be configured in `crush.json` for Crush to use them.
|
||||||
|
|
||||||
|
### crush.json Format
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"$schema": "https://charm.land/crush.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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Priority
|
||||||
|
|
||||||
|
Crush looks for configuration files in this order:
|
||||||
|
1. `.crush.json` (project-local)
|
||||||
|
2. `crush.json` (project-local)
|
||||||
|
3. `$HOME/.config/crush/crush.json` (global)
|
||||||
|
|
||||||
|
### Docker-based LSP Configuration
|
||||||
|
|
||||||
|
For Docker-based LSP instances, use this pattern:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"-i", // Interactive mode (required for stdio)
|
||||||
|
"--rm", // Auto-cleanup after use
|
||||||
|
"KNELDevStack-AIMiddleware-<service-name>",
|
||||||
|
"<server-args>" // e.g., "start", "--stdio"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏗️ Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
KNEL-AIMiddleware/
|
||||||
|
├── docker-compose.yml # Service orchestration
|
||||||
|
├── .env # Environment variables (not committed)
|
||||||
|
├── .env.example # Environment template
|
||||||
|
├── dockerfiles/ # Custom Dockerfiles (tracked in git)
|
||||||
|
│ ├── bash-language-server/
|
||||||
|
│ ├── docker-language-server/
|
||||||
|
│ └── marksman/
|
||||||
|
├── vendor/ # Cloned repositories (gitignored)
|
||||||
|
│ ├── bash-language-server/
|
||||||
|
│ ├── docker-language-server/
|
||||||
|
│ └── marksman/
|
||||||
|
├── AGENTS.md # Development workflow and conventions
|
||||||
|
├── STATUS.md # Server status and progress tracking
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dockerfile Management
|
||||||
|
|
||||||
|
Custom Dockerfiles are created in `dockerfiles/` and referenced in `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
service-name:
|
||||||
|
build:
|
||||||
|
context: ./vendor/service-name
|
||||||
|
dockerfile: ../../dockerfiles/service-name/Dockerfile
|
||||||
|
container_name: KNELDevStack-AIMiddleware-service-name
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
This approach:
|
||||||
|
- Keeps custom Dockerfiles under version control
|
||||||
|
- Uses vendor repository as build context
|
||||||
|
- Maintains clean separation of concerns
|
||||||
|
|
||||||
|
## 🌍 Environment Variables
|
||||||
|
|
||||||
|
Required variables (see `.env.example`):
|
||||||
|
|
||||||
|
| Variable | Description | Required |
|
||||||
|
|----------|-------------|-----------|
|
||||||
|
| `OPENAI_API_KEY` | OpenAI API key for LLM services | Yes (for OpenAI) |
|
||||||
|
| `KICAD_HOST` | KiCAD server host | Yes (for KiCAD MCP) |
|
||||||
|
| `KICAD_PORT` | KiCAD server port | Yes (for KiCAD MCP) |
|
||||||
|
| `BITWARDEN_*` | Bitwarden credentials | Yes (for Bitwarden MCP) |
|
||||||
|
| `MATOMO_*` | Matomo API credentials | Yes (for Matomo MCP) |
|
||||||
|
| `*_API_KEY` | Service-specific API keys | Varies |
|
||||||
|
|
||||||
|
**⚠️ Security Note**: Never commit `.env` file to version control.
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting
|
||||||
|
|
||||||
|
### Container Not Starting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check container logs
|
||||||
|
docker compose logs <service-name>
|
||||||
|
|
||||||
|
# Inspect container state
|
||||||
|
docker inspect <container-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### MCP Server Not Connecting
|
||||||
|
|
||||||
|
1. Verify service is running: `docker ps`
|
||||||
|
2. Check logs for errors: `docker compose logs <service>`
|
||||||
|
3. Verify environment variables in `.env`
|
||||||
|
4. Test connectivity: `docker compose exec <service> curl localhost:8080`
|
||||||
|
|
||||||
|
### LSP Server Not Responding (Crush)
|
||||||
|
|
||||||
|
1. Verify Docker image exists: `docker images | grep knel`
|
||||||
|
2. Test container manually:
|
||||||
|
```bash
|
||||||
|
echo '{"jsonrpc":"2.0","method":"initialize","params":{}}' | \
|
||||||
|
docker run -i --rm KNELDevStack-AIMiddleware-<lsp-name>
|
||||||
|
```
|
||||||
|
3. Check `crush.json` configuration
|
||||||
|
4. Verify container runs with `-i` flag for stdio
|
||||||
|
|
||||||
|
### Port Conflicts
|
||||||
|
|
||||||
|
If ports are already in use, modify `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "8081:8080" # Change host port
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please see [AGENTS.md](AGENTS.md) for development guidelines.
|
||||||
|
|
||||||
|
### Development Workflow
|
||||||
|
|
||||||
|
1. Review [AGENTS.md](AGENTS.md) for conventions
|
||||||
|
2. Check [STATUS.md](STATUS.md) for current project status
|
||||||
|
3. Create feature branch
|
||||||
|
4. Add service following existing patterns
|
||||||
|
5. Update `docker-compose.yml`, `STATUS.md`, and `crush.json`
|
||||||
|
6. Test thoroughly
|
||||||
|
7. Submit pull request
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## 🙏 Acknowledgments
|
||||||
|
|
||||||
|
- [Model Context Protocol](https://modelcontextprotocol.io/)
|
||||||
|
- [Language Server Protocol](https://microsoft.github.io/language-server-protocol/)
|
||||||
|
- [Docker](https://www.docker.com/)
|
||||||
|
- [Charmbracelet Crush](https://github.com/charmbracelet/crush)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Maintained by**: KNEL Development Team
|
||||||
|
**Last Updated**: 2024-01-21
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ Tracking the setup and validation of MCP/LSP servers via Docker Compose.
|
|||||||
| blender-mcp | Built | Container built successfully with uvx entrypoint |
|
| blender-mcp | Built | Container built successfully with uvx entrypoint |
|
||||||
| context7 | Pending | |
|
| context7 | Pending | |
|
||||||
| gimp-mcp | Built | Container built successfully with uvx entrypoint |
|
| gimp-mcp | Built | Container built successfully with uvx entrypoint |
|
||||||
| bash-language-server | Pending | |
|
| bash-language-server | Built | Container built using prebuilt npm package (190MB). Configured for Crush via docker run with -i flag for stdio. |
|
||||||
| docker-language-server | Pending | |
|
| docker-language-server | Built | Container built from Go source (49.2MB). Configured for Crush via docker run with -i flag for stdio. |
|
||||||
|
| marksman | Built | Container built from prebuilt binary (144MB). Configured for Crush via docker run with -i flag for stdio. |
|
||||||
| drawio-mcp-server | Pending | |
|
| drawio-mcp-server | Pending | |
|
||||||
| matomo-mcp-client | Pending | |
|
| matomo-mcp-client | Pending | |
|
||||||
| imap-mcp | Built | Container built successfully with uvx entrypoint |
|
| imap-mcp | Built | Container built successfully with uvx entrypoint |
|
||||||
@@ -55,4 +56,4 @@ To rebuild a server after changes:
|
|||||||
docker compose build --no-cache <service-name>
|
docker compose build --no-cache <service-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Use lowercase service names from the compose file. Container names will still be prefixed with KNELDevStack-AIMiddleware-.
|
Note: Use lowercase service names from compose file. Container names will still be prefixed with KNELDevStack-AIMiddleware-.
|
||||||
|
|||||||
17
crush.json
Normal file
17
crush.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://charm.land/crush.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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,12 +134,9 @@ services:
|
|||||||
bash-language-server:
|
bash-language-server:
|
||||||
build:
|
build:
|
||||||
context: ./vendor/bash-language-server
|
context: ./vendor/bash-language-server
|
||||||
dockerfile: Dockerfile
|
dockerfile: ../../dockerfiles/bash-language-server/Dockerfile
|
||||||
container_name: KNELDevStack-AIMiddleware-bash-language-server
|
container_name: KNELDevStack-AIMiddleware-bash-language-server
|
||||||
restart: unless-stopped
|
restart: "no"
|
||||||
ports:
|
|
||||||
- "8082:8080"
|
|
||||||
command: ["npm", "start"]
|
|
||||||
profiles:
|
profiles:
|
||||||
- dev
|
- dev
|
||||||
|
|
||||||
@@ -417,11 +414,19 @@ services:
|
|||||||
docker-language-server:
|
docker-language-server:
|
||||||
build:
|
build:
|
||||||
context: ./vendor/docker-language-server
|
context: ./vendor/docker-language-server
|
||||||
dockerfile: Dockerfile
|
dockerfile: ../../dockerfiles/docker-language-server/Dockerfile
|
||||||
container_name: KNELDevStack-AIMiddleware-docker-language-server
|
container_name: KNELDevStack-AIMiddleware-docker-language-server
|
||||||
restart: unless-stopped
|
restart: "no"
|
||||||
ports:
|
profiles:
|
||||||
- "8085:8080"
|
- dev
|
||||||
|
|
||||||
|
# Marksman LSP - Markdown language server
|
||||||
|
marksman:
|
||||||
|
build:
|
||||||
|
context: ./vendor/marksman
|
||||||
|
dockerfile: ../../dockerfiles/marksman/Dockerfile
|
||||||
|
container_name: KNELDevStack-AIMiddleware-marksman
|
||||||
|
restart: "no"
|
||||||
profiles:
|
profiles:
|
||||||
- dev
|
- dev
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,9 @@ FROM node:22-alpine
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json package-lock.json* ./
|
# Install prebuilt bash-language-server from npm
|
||||||
|
RUN npm install -g bash-language-server
|
||||||
|
|
||||||
RUN npm ci
|
# Set entrypoint
|
||||||
|
ENTRYPOINT ["bash-language-server"]
|
||||||
COPY . .
|
CMD ["start"]
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
CMD ["node", "dist/index.js"]
|
|
||||||
|
|||||||
32
dockerfiles/docker-language-server/Dockerfile
Normal file
32
dockerfiles/docker-language-server/Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
ARG GO_VERSION="1.25"
|
||||||
|
ARG ALPINE_VERSION="3.22"
|
||||||
|
|
||||||
|
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# Copy go files
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
|
# Download dependencies
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build of binary
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -o docker-language-server ./cmd/docker-language-server
|
||||||
|
|
||||||
|
# Runtime stage
|
||||||
|
FROM alpine:${ALPINE_VERSION}
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy binary from builder
|
||||||
|
COPY --from=builder /src/docker-language-server /usr/local/bin/
|
||||||
|
|
||||||
|
# Set entrypoint to run LSP server
|
||||||
|
ENTRYPOINT ["docker-language-server"]
|
||||||
|
CMD ["start", "--stdio"]
|
||||||
14
dockerfiles/marksman/Dockerfile
Normal file
14
dockerfiles/marksman/Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies (wget and icu-libs for marksman)
|
||||||
|
RUN apt-get update && apt-get install -y wget libicu72 && \
|
||||||
|
wget -O /usr/local/bin/marksman \
|
||||||
|
https://github.com/artempyanykh/marksman/releases/download/2025-12-13/marksman-linux-x64 \
|
||||||
|
&& chmod +x /usr/local/bin/marksman && \
|
||||||
|
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Set entrypoint to run LSP server
|
||||||
|
ENTRYPOINT ["marksman"]
|
||||||
|
CMD ["server"]
|
||||||
Reference in New Issue
Block a user