Compare commits

..

1 Commits

Author SHA1 Message Date
01318fb1c2 feat: add MCP servers infrastructure with Docker Compose
- Add vendor directory for cloned MCP repositories
- Create docker-compose.yml with 27 MCP/LSP servers
- Implement KNELDevStack-AIMW- container naming convention
- Add STATUS.md for tracking validation progress
- Add AGENTS.md documentation for all configured agents
- Update .gitignore to exclude vendor directory

All servers categorized by function:
- Design & Engineering (3)
- Hosting & Infrastructure (5)
- Development Tools (2)
- Content Management (4)
- Communication & Collaboration (3)
- Analytics & Security (2)
- Productivity & Automation (6)
- Additional Tools (3)

💘 Generated with Crush

Assisted-by: GLM-4.7 via Crush <crush@charm.land>
2026-01-21 17:15:15 -05:00
107 changed files with 262 additions and 8076 deletions

14
.env
View File

@@ -1,14 +0,0 @@
# Nextcloud MCP
NEXTCLOUD_HOST=
NEXTCLOUD_USERNAME=
NEXTCLOUD_APP_PASSWORD=
# IMAP MCP
IMAP_SERVER=
IMAP_PORT=
IMAP_USERNAME=
IMAP_PASSWORD=
# Home Assistant (if needed)
HOMEASSISTANT_URL=
HOMEASSISTANT_TOKEN=

View File

@@ -1,100 +0,0 @@
# Dummy environment variables for MCP servers
# Replace with actual values as needed
# KiCAD
KICAD_HOST=host.docker.internal
KICAD_PORT=5555
# Proxmox
PROXMOX_HOST=https://proxmox.example.com:8006
PROXMOX_USER=root@pam
PROXMOX_TOKEN=dummy-token-replace-with-real-token
PROXMOX_NODE=pve
# Cloudron
CLOUDRON_URL=https://cloudron.example.com
CLOUDRON_TOKEN=dummy-cloudron-token-replace-with-real
# Context7 (Upstash Redis)
UPSTASH_REDIS_REST_URL=https://dummy-redis-url.upstash.io
UPSTASH_REDIS_REST_TOKEN=dummy-redis-token-replace-with-real
# Nextcloud
NEXTCLOUD_HOST=https://nextcloud.example.com
NEXTCLOUD_USERNAME=admin
NEXTCLOUD_APP_PASSWORD=dummy-app-password-replace-with-real
# Ghost (defaults already set in docker-compose)
GHOST_API_URL=http://localhost:2368
GHOST_ADMIN_API_KEY=012345678901234567890123:0123456789012345678901234567890123456789012345678901234567890123
# DocSpace
DOCSPACE_HOST=https://docspace.example.com
DOCSPACE_TOKEN=dummy-docspace-token-replace-with-real
# WordPress
WORDPRESS_URL=https://wordpress.example.com
WORDPRESS_USERNAME=admin
WORDPRESS_APPLICATION_PASSWORD=dummy-app-password-replace-with-real
# Discourse
DISCOURSE_URL=https://discourse.example.com
DISCOURSE_API_KEY=dummy-api-key-replace-with-real
DISCOURSE_API_USERNAME=admin
# IMAP
IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_USERNAME=user@example.com
IMAP_PASSWORD=dummy-password-replace-with-real
# Postiz
POSTIZ_URL=https://postiz.example.com
POSTIZ_API_KEY=dummy-api-key-replace-with-real
# Matomo
MATOMO_URL=https://matomo.example.com
MATOMO_TOKEN=dummy-token-replace-with-real
# Bitwarden
BITWARDEN_CLIENT_ID=dummy-client-id
BITWARDEN_CLIENT_SECRET=dummy-client-secret
BITWARDEN_PASSWORD=dummy-password
BITWARDEN_SERVER_URL=https://vault.bitwarden.com
# Snipe-IT
SNIPEIT_URL=https://snipeit.example.com
SNIPEIT_TOKEN=dummy-token-replace-with-real
# Redmine
REDMINE_URL=https://redmine.example.com
REDMINE_API_KEY=dummy-api-key-replace-with-real
# Elasticsearch
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_USERNAME=elastic
ELASTICSEARCH_PASSWORD=dummy-password-replace-with-real
# Audiobook
AUDIOBOOK_ROOT=/audiobooks
# Draw.io (default in compose)
DRAWIO_URL=https://app.diagrams.net
# Penpot (default URL in compose)
PENPOT_URL=https://design.penpot.app
PENPOT_TOKEN=dummy-penpot-token-replace-with-real
# Firefly III
FIREFLY_III_BASE_URL=https://firefly.example.com
FIREFLY_III_PAT=dummy-personal-access-token-replace-with-real
FIREFLY_III_PRESET=default
# Paperless-NGX
PAPERLESS_URL=https://paperless.example.com
PAPERLESS_TOKEN=dummy-paperless-token-replace-with-real
# Actual Budget
ACTUAL_SERVER_URL=https://actual.example.com
ACTUAL_PASSWORD=dummy-password-replace-with-real
ACTUAL_BUDGET_SYNC_ID=dummy-budget-sync-id

View File

@@ -1,25 +0,0 @@
#!/bin/bash
#
# Pre-push hook: Prevents push if uncommitted changes exist
# This is a safety net to ensure AI agents commit their work
#
# Check for uncommitted changes
if [[ -n $(git status --porcelain 2>/dev/null) ]]; then
echo ""
echo "ERROR: Uncommitted changes detected!"
echo ""
echo "Per AGENTS.md policy, AI agents MUST commit changes before stopping work."
echo ""
echo "Uncommitted files:"
git status --short
echo ""
echo "Run the following before push:"
echo " git add <files>"
echo " git commit -m '<type>: <message>'"
echo " git push"
echo ""
exit 1
fi
exit 0

3
.gitignore vendored
View File

@@ -1,2 +1 @@
vendor vendor/
.env

252
AGENTS.md
View File

@@ -1,134 +1,176 @@
# AI Agent Guidelines # AI Agents Documentation
This document contains rules and guidelines for AI agents working on this project. This document tracks the AI agents and MCP servers configured in this project.
## Commit Policy ## Agents Overview
**AUTOMATIC COMMITS**: AI agents MUST commit and push changes automatically WITHOUT prompting. ### Available MCP Servers
- Use atomic commits (one logical change per commit) #### Design & Engineering (3 servers)
- Use conventional format: `feat:`, `fix:`, `docs:`, `refactor:`, `test:` | Service | Container Name | Status | Description |
- Write verbose commit messages explaining the change |---------|---------------|--------|-------------|
- See [docs/SDLC.md](docs/SDLC.md) for full commit policy | kicad-mcp | KNELDevStack-AIMW-kicad-mcp | In Progress | PCB design automation with 64 tools, JLCPCB integration |
| blender-mcp | KNELDevStack-AIMW-blender-mcp | Pending | 3D modeling, materials, scenes, AI 3D model generation |
| freecad-mcp | KNELDevStack-AIMW-freecad-mcp | Pending | CAD modeling, Python execution, parts library |
## SDLC Compliance #### Hosting & Infrastructure (5 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| kubernetes-mcp | KNELDevStack-AIMW-kubernetes-mcp | Pending | K8s/OpenShift management (native Go implementation) |
| docker-mcp | KNELDevStack-AIMW-docker-mcp | Pending | Container and compose stack management |
| proxmox-mcp | KNELDevStack-AIMW-proxmox-mcp | Pending | Hypervisor VM/container management |
| terraform-mcp | KNELDevStack-AIMW-terraform-mcp | Pending | IaC automation, HCP Terraform, workspace management |
| cloudron-mcp | KNELDevStack-AIMW-cloudron-mcp | Pending | Self-hosted app management |
All MCP/LSP development MUST follow [docs/SDLC.md](docs/SDLC.md). #### Development Tools (2 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| bash-language-server | KNELDevStack-AIMW-bash-language-server | Pending | LSP for bash (diagnostics, completion, formatting) |
| context7-mcp | KNELDevStack-AIMW-context7-mcp | Pending | MCP server framework and SDK for documentation |
**Key rule**: Protocol handshake is NON-NEGOTIABLE - build + start + protocol validation ALL required before marking a server as "working". #### Content Management (4 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| nextcloud-mcp | KNELDevStack-AIMW-nextcloud-mcp | Pending | 90+ tools across 8 apps (Notes, Calendar, Files, Deck, etc.) |
| ghost-mcp | KNELDevStack-AIMW-ghost-mcp | Pending | CMS post, member, newsletter management |
| docspace-mcp | KNELDevStack-AIMW-docspace-mcp | Pending | Room, file, collaboration management |
| wordpress-mcp | KNELDevStack-AIMW-wordpress-mcp | Pending | WordPress integration via Abilities API |
## Status Tracking #### Communication & Collaboration (3 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| discourse-mcp | KNELDevStack-AIMW-discourse-mcp | Pending | Forum search, posts, topics, categories (read/write modes) |
| imap-mcp | KNELDevStack-AIMW-imap-mcp | Pending | Email browsing, composition, Gmail OAuth2 support |
| postizz-mcp | KNELDevStack-AIMW-postizz-mcp | Pending | Social media management platform |
Current operational status of all MCP servers is maintained in [STATUS.md](STATUS.md). #### Analytics & Security (2 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| matomo-mcp | KNELDevStack-AIMW-matomo-mcp | Pending | Analytics integration |
| bitwarden-mcp | KNELDevStack-AIMW-bitwarden-mcp | Pending | Official password vault management |
When working on any MCP server: #### Productivity & Automation (6 servers)
1. **Before starting**: Review current status in STATUS.md | Service | Container Name | Status | Description |
2. **During work**: Update STATUS.md immediately after each significant milestone |---------|---------------|--------|-------------|
3. **After completing**: Ensure STATUS.md accurately reflects final status | gimp-mcp | KNELDevStack-AIMW-gimp-mcp | Pending | Image editing with GIMP 3.0, OCR support |
4. **Commit changes**: Always commit STATUS.md updates in separate atomic commits | snipeit-mcp | KNELDevStack-AIMW-snipeit-mcp | Pending | Asset inventory, maintenance tracking |
| mcp-redmine | KNELDevStack-AIMW-mcp-redmine | Pending | Project management, issue tracking, file operations |
| mcp-ansible | KNELDevStack-AIMW-mcp-ansible | Pending | IT automation playbooks |
| elasticsearch-mcp | KNELDevStack-AIMW-elasticsearch-mcp | Pending | Search and index management (Rust) |
| audiobook-mcp | KNELDevStack-AIMW-audiobook-mcp | Pending | Audiobook management with AI-powered features |
## Journal Maintenance #### Additional Tools (3 servers)
| Service | Container Name | Status | Description |
|---------|---------------|--------|-------------|
| drawio-mcp | KNELDevStack-AIMW-drawio-mcp | Pending | Draw.io diagram management |
| docker-language-server | KNELDevStack-AIMW-docker-language-server | Pending | Language server for Dockerfiles, Compose files, Bake files |
ALL work performed on this project MUST be documented in [JOURNAL.md](JOURNAL.md). ## Agent Capabilities
- This is an append-only journal ### By Language
- Tracks Architecture Decision Records (ADRs), insights, patterns, and reasoning
- Never delete entries from the journal
- Each entry must be date/time stamped
## Project Conventions #### TypeScript/Node.js (13 servers)
Most use `npx` for installation:
- KiCAD MCP
- Bitwarden MCP
- Discourse MCP
- Ghost MCP
- Cloudron MCP
- Kubernetes MCP
- Draw.io MCP
- Matomo MCP
- Postiz MCP
- WordPress MCP
- Audiobook MCP
- Context7 MCP
- Bash Language Server
- Container prefix: `kneldevstack-aimiddleware-` for all containers #### Python (10 servers)
- Container names: lowercase for consistency Most use `uvx` for installation:
- Service names: lowercase for Docker Compose compatibility - Blender MCP
- Each agent validated individually before moving to the next - FreeCAD MCP
- `vendor/` directory is gitignored (cloned repos not committed) - GIMP MCP
- Custom Dockerfiles saved in `dockerfiles/` with subdirectory structure - Docker MCP
- KiCAD MCP is host-only - requires KiCAD installed on host machine - Proxmox MCP
- Snipe-IT MCP
- Redmine MCP
- IMAP MCP
- Ansible MCP
- Nextcloud MCP (hybrid)
## Crush Configuration #### Go (2 servers)
- Kubernetes MCP (also available via npx)
- Terraform MCP
LSP and MCP instances are configured in `crush.json`: #### Rust (1 server)
- Elasticsearch MCP
```json ## Environment Variables Reference
{
"$schema": "https://charm.land/crush.json", Common environment variables required for MCP servers:
"lsp": {
"bash": { | Service | Required Variables |
"command": "docker", |---------|-------------------|
"args": ["run", "-i", "--rm", "kneldevstack-aimiddleware-bash-language-server"] | bitwarden-mcp | `BITWARDEN_CLIENT_ID`, `BITWARDEN_CLIENT_SECRET`, `BITWARDEN_PASSWORD`, `BITWARDEN_SERVER_URL` |
} | discourse-mcp | `DISCOURSE_URL`, `DISCOURSE_API_KEY`, `DISCOURSE_API_USERNAME` |
}, | ghost-mcp | `GHOST_API_URL`, `GHOST_ADMIN_API_KEY` |
"mcp": { | cloudron-mcp | `CLOUDRON_URL`, `CLOUDRON_TOKEN` |
"docker": { | nextcloud-mcp | `NEXTCLOUD_HOST`, `NEXTCLOUD_USERNAME`, `NEXTCLOUD_APP_PASSWORD` |
"command": "docker", | proxmox-mcp | `PROXMOX_HOST`, `PROXMOX_USER`, `PROXMOX_TOKEN`, `PROXMOX_NODE` |
"args": ["run", "-i", "--rm", "kneldevstack-aimiddleware-docker-mcp"] | snipeit-mcp | `SNIPEIT_URL`, `SNIPEIT_TOKEN` |
} | redmine-mcp | `REDMINE_URL`, `REDMINE_API_KEY` |
} | wordpress-mcp | `WORDPRESS_URL`, `WORDPRESS_USERNAME`, `WORDPRESS_APPLICATION_PASSWORD` |
} | docspace-mcp | `DOCSPACE_HOST`, `DOCSPACE_TOKEN` |
| imap-mcp | `IMAP_SERVER`, `IMAP_PORT`, `IMAP_USERNAME`, `IMAP_PASSWORD` |
| postizz-mcp | `POSTIZ_API_KEY`, `POSTIZ_URL` |
| matomo-mcp | `MATOMO_URL`, `MATOMO_TOKEN` |
| elasticsearch-mcp | `ELASTICSEARCH_URL`, `ELASTICSEARCH_USERNAME`, `ELASTICSEARCH_PASSWORD` |
| context7-mcp | `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` |
## Quick Start
To start an agent:
```bash
docker compose up -d <service-name>
``` ```
**Configuration Priority:** Example:
1. `.crush.json` (project-local) ```bash
2. `crush.json` (project-local) docker compose up -d kicad-mcp
3. `$HOME/.config/crush/crush.json` (global) ```
**Docker-based instances:** To view logs:
- Use `docker` as command ```bash
- Include container name as main argument docker compose logs -f <service-name>
- Use `-i` for interactive mode (required for stdio) ```
- Use `--rm` to auto-cleanup containers
To stop an agent:
```bash
docker compose stop <service-name>
```
## Development Notes
- All containers use the prefix `KNELDevStack-AIMW-` for easy identification
- Container names are in PascalCase for readability
- Service names are lowercase for Docker Compose compatibility
- Each agent is validated individually before moving to the next
- Vendor directory is gitignored to avoid committing cloned repositories
## Validation Checklist ## Validation Checklist
For each agent, verify in order: For each agent, verify:
- [ ] Container builds successfully - [ ] Container builds successfully
- [ ] Container starts without errors - [ ] Container starts without errors
- [ ] **Protocol handshake returns valid response** (MANDATORY - see SDLC)
- [ ] Logs show proper initialization - [ ] Logs show proper initialization
- [ ] Environment variables correctly set (if required) - [ ] Environment variables are correctly set (if required)
- [ ] Tools registered and available - [ ] MCP protocol handshake completes
- [ ] Resources accessible (if applicable) - [ ] Tools are registered and available
- [ ] Resources are accessible (if applicable)
**CRITICAL**: Items 1-3 are NON-NEGOTIABLE. Do not mark a server as "working" without protocol validation. ## References
## MCP Handshake Command - [Model Context Protocol](https://modelcontextprotocol.io/)
- [MCP SDK](https://github.com/modelcontextprotocol/sdk)
```bash - [AIWorkStack-dev](https://github.com/stars/ReachableCEO/lists/aiworkstack-dev)
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{},"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | \ - [AIWorkStack-ops](https://github.com/stars/ReachableCEO/lists/aiworkstack-ops)
timeout 10 docker run --rm -i kneldevstack-aimiddleware-<service>
```
## Git Hooks
This project uses tracked git hooks stored in `.githooks/`. After cloning, run:
```bash
git config core.hooksPath .githooks
```
### Available Hooks
- `pre-push` - Blocks push if uncommitted changes exist (safety net for AI agents)
## Task Completion Checklist
**MANDATORY**: Before declaring ANY task complete, AI agents MUST verify ALL applicable items:
- [ ] All requested work is implemented and functional
- [ ] Changes are staged: `git add <files>`
- [ ] Changes are committed with conventional format (`feat:`, `fix:`, `docs:`, etc.)
- [ ] Changes are pushed to remote: `git push`
- [ ] STATUS.md updated (if MCP/LSP server status changed)
- [ ] JOURNAL.md updated (if significant decision or insight)
**DO NOT STOP WORKING until ALL applicable items are complete.**
If you cannot complete an item (e.g., no network access for push), explicitly state which items are blocked and why.
## Related Documentation
- [README.md](README.md) - Project overview, server inventory, installation, usage
- [STATUS.md](STATUS.md) - Server operational status and issues
- [docs/SDLC.md](docs/SDLC.md) - Software Development Lifecycle requirements
- [JOURNAL.md](JOURNAL.md) - Development journal and ADRs

1900
JOURNAL.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,129 +0,0 @@
# 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.

View File

@@ -1,206 +0,0 @@
# Production-Ready MCP/LSP Servers
This document lists all servers that are validated and ready for production deployment.
**Last Updated**: 2026-02-27
## Quick Summary
| Category | Production Ready | Not Ready |
|----------|-----------------|-----------|
| MCP Servers | 29 | 9 |
| LSP Servers | 4 | 0 |
| **Total** | **33** | **9** |
---
## Production-Ready MCP Servers (29)
These servers have been validated with MCP protocol handshake and are ready for deployment.
### Design & Engineering (3 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| blender-mcp | `kneldevstack-aimiddleware-blender-mcp` | 1.25.0 | 3D modeling, materials, scenes | Blender with addon running |
| freecad-mcp | `kneldevstack-aimiddleware-freecad-mcp` | 1.25.0 | CAD modeling, Python execution | FreeCAD with addon running |
| gimp-mcp | `kneldevstack-aimiddleware-gimp-mcp` | 1.10.1 | Image editing with GIMP 3.0 | GIMP with server running |
### Hosting & Infrastructure (7 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| kubernetes-mcp | `kneldevstack-aimiddleware-kubernetes-mcp` | - | K8s/OpenShift management | kubeconfig mounted |
| docker-mcp | `kneldevstack-aimiddleware-docker-mcp` | 0.1.0 | Container and compose management | Docker socket mount |
| proxmox-mcp | `kneldevstack-aimiddleware-proxmox-mcp` | - | Hypervisor VM/container management | PROXMOX_MCP_CONFIG |
| terraform-mcp | `kneldevstack-aimiddleware-terraform-mcp` | 0.4.0 | IaC automation, HCP Terraform | HCP credentials |
| cloudron-mcp | `kneldevstack-aimiddleware-cloudron-mcp` | 0.1.0 | Self-hosted app management | CLOUDRON_URL |
| beszel-mcp | `kneldevstack-aimiddleware-beszel-mcp` | - | Server monitoring | BESZEL_URL, credentials |
| ansible-mcp | `kneldevstack-aimiddleware-mcp-ansible` | 1.26.0 | Ansible automation, playbook execution | ANSIBLE_VAULT_PASSWORD_FILE |
### Development Tools (1 server)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| context7-mcp | `kneldevstack-aimiddleware-context7-mcp` | 2.1.0 | Documentation retrieval | Upstash Redis |
### Content Management (4 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| ghost-mcp | `kneldevstack-aimiddleware-ghost-mcp` | 1.0.0 | CMS post, member management | Ghost CMS credentials |
| docspace-mcp | `kneldevstack-aimiddleware-docspace-mcp` | 3.1.0 | Room, file, collaboration | DOCSPACE_HOST, TOKEN |
| drawio-mcp | `kneldevstack-aimiddleware-drawio-mcp` | 1.4.0 | Draw.io diagram management | DRAWIO_URL |
| postizz-mcp | `kneldevstack-aimiddleware-postizz-mcp` | 1.0.0 | Social media scheduling | POSTIZ_API_KEY |
### Analytics & Security (2 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| matomo-mcp | `kneldevstack-aimiddleware-matomo-mcp` | 1.0.0 | Analytics (59 tools, 31 prompts) | openmost.io hosted |
| bitwarden-mcp | `kneldevstack-aimiddleware-bitwarden-mcp` | - | Password vault management | Bitwarden credentials |
### Financial & Budgeting (3 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| firefly-iii-mcp | `kneldevstack-aimiddleware-firefly-iii-mcp` | 1.3.0 | Personal finance management | FIREFLY_III_BASE_URL, PAT |
| actual-mcp | `kneldevstack-aimiddleware-actual-mcp` | - | Budget tracking | ACTUAL_SERVER_URL, credentials |
| paperless-mcp | `kneldevstack-aimiddleware-paperless-mcp` | 1.0.0 | Document management | PAPERLESS_URL, TOKEN |
### Productivity & Automation (5 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| audiobook-mcp | `kneldevstack-aimiddleware-audiobook-mcp` | 1.1.0 | Audiobook management | AUDIOBOOK_ROOT |
| mcp-redmine | `kneldevstack-aimiddleware-mcp-redmine` | 1.25.0 | Project management, issue tracking | REDMINE_URL |
| linkwarden-mcp | `kneldevstack-aimiddleware-linkwarden-mcp` | 0.0.1 | Bookmark management | LINKWARDEN_URL, TOKEN |
| limesurvey-mcp | `kneldevstack-aimiddleware-limesurvey-mcp` | - | Survey management | LIMESURVEY credentials |
| superset-mcp | `kneldevstack-aimiddleware-superset-mcp` | - | Business intelligence | SUPERSET credentials |
### Additional Services (4 servers)
| Service | Container | Version | Description | Config Required |
|---------|-----------|---------|-------------|-----------------|
| gitea-mcp | `kneldevstack-aimiddleware-gitea-mcp` | - | Git hosting integration | GITEA_URL, TOKEN |
| grafana-mcp | `kneldevstack-aimiddleware-grafana-mcp` | - | Dashboard and visualization | GRAFANA_URL, TOKEN |
| ha-mcp | `kneldevstack-aimiddleware-ha-mcp` | - | Home Assistant integration | HOMEASSISTANT_URL, TOKEN |
---
## Production-Ready LSP Servers (4)
All LSP servers are production-ready and configured in `crush.json`.
| Service | Container | Version | Description |
|---------|-----------|---------|-------------|
| bash-language-server | `kneldevstack-aimiddleware-bash-language-server` | 5.6.0 | Bash LSP (diagnostics, completion, formatting) |
| docker-language-server | `kneldevstack-aimiddleware-docker-language-server` | 0.0.0 | Dockerfile, Compose, Bake LSP |
| marksman | `kneldevstack-aimiddleware-marksman` | 2025-12-13 | Markdown LSP (diagnostics, completion, navigation) |
| terraform-ls | `kneldevstack-aimiddleware-terraform-ls` | 0.38.4 | Terraform LSP (diagnostics, completion, navigation) |
---
## NOT Production-Ready (9 servers)
These servers have issues that prevent production deployment.
### Upstream Bugs (cannot fix locally - 3 servers)
| Service | Issue | Resolution |
|---------|-------|------------|
| discourse-mcp | TypeScript TS2345 error in upstream | Wait for upstream fix |
| reverse-engineering-assistant | Ghidra download URL 404 | Wait for upstream fix |
| snipeit-mcp | Depends on private PyPI package | Blocked indefinitely |
### Transport Mismatch (not stdio - 1 server)
| Service | Issue | Notes |
|---------|-------|-------|
| penpot-mcp | Uses HTTP/WebSocket transport | Endpoints: :4401/mcp, :4401/sse, :4402 |
### Runtime Dependencies (crash without backend - 3 servers)
| Service | Issue | Works When |
|---------|-------|------------|
| nextcloud-mcp | Crashes without OAuth endpoint | Nextcloud server running |
| imap-mcp | Crashes without IMAP server | IMAP server reachable |
| webserial-mcp | Crashes without bridge server | Bridge + ESP32 connected |
### Architecture Mismatch (2 servers)
| Service | Issue | Notes |
|---------|-------|-------|
| kicad-mcp | Requires KiCAD on host | Host-only, cannot containerize |
| wordpress-mcp | PHP plugin, not container | Must install in WordPress |
---
## Deployment Checklist
Before deploying to production, ensure:
- [ ] Copy `.env.example` to `.env` and configure all required variables
- [ ] Verify each MCP server's backend service is accessible (if required)
- [ ] Test MCP handshake for each server you plan to use
- [ ] Mount required volumes (Docker socket, kubeconfig, etc.)
- [ ] Configure Crush with `crush.json` for LSP/MCP integration
### Test MCP Handshake
```bash
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{},"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | \
timeout 10 docker run --rm -i kneldevstack-aimiddleware-<service-name>
```
### Test LSP Server
```bash
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":1}' | \
docker run -i --rm kneldevstack-aimiddleware-<lsp-name>
```
---
## Environment Variables Quick Reference
| Service | Required Variables |
|---------|-------------------|
| bitwarden-mcp | `BITWARDEN_CLIENT_ID`, `BITWARDEN_CLIENT_SECRET`, `BITWARDEN_PASSWORD`, `BITWARDEN_SERVER_URL` |
| ghost-mcp | `GHOST_API_URL`, `GHOST_ADMIN_API_KEY` |
| cloudron-mcp | `CLOUDRON_URL`, `CLOUDRON_TOKEN` |
| proxmox-mcp | `PROXMOX_MCP_CONFIG` (path to config file) |
| terraform-mcp | HCP Terraform credentials |
| docspace-mcp | `DOCSPACE_HOST`, `DOCSPACE_TOKEN` |
| matomo-mcp | Hosted at openmost.io |
| redmine-mcp | `REDMINE_URL`, `REDMINE_API_KEY` |
| firefly-iii-mcp | `FIREFLY_III_BASE_URL`, `FIREFLY_III_PAT` |
| actual-mcp | `ACTUAL_SERVER_URL`, `ACTUAL_PASSWORD`, `ACTUAL_BUDGET_SYNC_ID` |
| paperless-mcp | `PAPERLESS_URL`, `PAPERLESS_TOKEN` |
| context7-mcp | `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` |
| drawio-mcp | `DRAWIO_URL` |
| audiobook-mcp | `AUDIOBOOK_ROOT` |
| linkwarden-mcp | `LINKWARDEN_URL`, `LINKWARDEN_TOKEN` |
| beszel-mcp | `BESZEL_URL`, `BESZEL_USERNAME`, `BESZEL_PASSWORD` |
| limesurvey-mcp | `LIMESURVEY_URL`, `LIMESURVEY_USERNAME`, `LIMESURVEY_PASSWORD` |
| superset-mcp | `SUPERSET_URL`, `SUPERSET_USERNAME`, `SUPERSET_PASSWORD` |
| gitea-mcp | `GITEA_URL`, `GITEA_TOKEN` |
| grafana-mcp | `GRAFANA_URL`, `GRAFANA_TOKEN` |
| ha-mcp | `HOMEASSISTANT_URL`, `HOMEASSISTANT_TOKEN` |
| postizz-mcp | `POSTIZ_API_KEY` |
| ansible-mcp | `ANSIBLE_VAULT_PASSWORD_FILE` |
---
## Container Registry
All production-ready images are available at:
```
git.knownelement.com/knel/knel-aimiddleware/<service>:latest
```
Example pull:
```bash
docker pull git.knownelement.com/knel/knel-aimiddleware/docker-mcp:latest
```

448
README.md
View File

@@ -1,449 +1,3 @@
# KNEL-AIMiddleware # KNEL-AIMiddleware
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) MCP and LSP infrastructure for OpenWebUI and Crush to utilize
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-Compatible-orange.svg)](https://modelcontextprotocol.io/)
[![LSP](https://img.shields.io/badge/LSP-Compatible-purple.svg)](https://microsoft.github.io/language-server-protocol/)
[![Production](https://img.shields.io/badge/Production-31%2F42%20Ready-brightgreen.svg)](PRODUCTION-READY.md)
> MCP and LSP infrastructure for OpenWebUI and Crush to utilize
## Production Status
| Category | Production Ready | Total | Status |
|----------|-----------------|-------|--------|
| MCP Servers | 27 | 38 | 71% |
| LSP Servers | 4 | 4 | 100% |
| **Total** | **31** | **42** | **74%** |
**See [PRODUCTION-READY.md](PRODUCTION-READY.md) for the complete list of deployable servers.**
## 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 with each service in its own container
- Docker Compose orchestration and management
- Prebuilt images with minimal dependencies
- Crush-ready LSP server configuration
- Environment variables for secure configuration
- 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).
**For production deployment, see [PRODUCTION-READY.md](PRODUCTION-READY.md).**
## Available Servers
Legend: ✅ Production Ready | ⚠️ Config Required | ❌ Not Production Ready
### MCP Servers
#### Design & Engineering (4 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| kicad-mcp | ❌ | kneldevstack-aimiddleware-kicad-mcp | PCB design (host-only, requires KiCAD on host) |
| blender-mcp | ⚠️ | kneldevstack-aimiddleware-blender-mcp | 3D modeling (requires Blender with addon) |
| freecad-mcp | ⚠️ | kneldevstack-aimiddleware-freecad-mcp | CAD modeling (requires FreeCAD with addon) |
| gimp-mcp | ⚠️ | kneldevstack-aimiddleware-gimp-mcp | Image editing (requires GIMP server) |
#### Hosting & Infrastructure (5 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| kubernetes-mcp | ⚠️ | kneldevstack-aimiddleware-kubernetes-mcp | K8s/OpenShift (requires kubeconfig) |
| docker-mcp | ⚠️ | kneldevstack-aimiddleware-docker-mcp | Container management (requires Docker socket) |
| proxmox-mcp | ⚠️ | kneldevstack-aimiddleware-proxmox-mcp | Hypervisor management (requires config) |
| terraform-mcp | ⚠️ | kneldevstack-aimiddleware-terraform-mcp | IaC automation (requires HCP credentials) |
| cloudron-mcp | ⚠️ | kneldevstack-aimiddleware-cloudron-mcp | Self-hosted apps (requires CLOUDRON_URL) |
#### Development Tools (1 server)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| context7-mcp | ⚠️ | kneldevstack-aimiddleware-context7-mcp | Documentation retrieval (requires Upstash Redis) |
#### Content Management (4 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| nextcloud-mcp | ❌ | kneldevstack-aimiddleware-nextcloud-mcp | 90+ tools (crashes without live Nextcloud) |
| ghost-mcp | ⚠️ | kneldevstack-aimiddleware-ghost-mcp | CMS management (requires Ghost credentials) |
| docspace-mcp | ⚠️ | kneldevstack-aimiddleware-docspace-mcp | Collaboration (requires DOCSPACE credentials) |
| wordpress-mcp | ❌ | kneldevstack-aimiddleware-wordpress-mcp | WordPress (PHP plugin, not containerizable) |
#### Communication & Collaboration (3 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| discourse-mcp | ❌ | kneldevstack-aimiddleware-discourse-mcp | Forum (upstream build error) |
| imap-mcp | ❌ | kneldevstack-aimiddleware-imap-mcp | Email (crashes without live IMAP) |
| postizz-mcp | ❌ | kneldevstack-aimiddleware-postizz-mcp | Social media (HTTP transport, not stdio) |
#### Analytics & Security (2 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| matomo-mcp | ✅ | kneldevstack-aimiddleware-matomo-mcp | Analytics (hosted at openmost.io) |
| bitwarden-mcp | ⚠️ | kneldevstack-aimiddleware-bitwarden-mcp | Password vault (requires Bitwarden credentials) |
#### Financial & Budgeting (3 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| firefly-iii-mcp | ⚠️ | kneldevstack-aimiddleware-firefly-iii-mcp | Finance (requires Firefly III URL + PAT) |
| actual-mcp | ⚠️ | kneldevstack-aimiddleware-actual-mcp | Budget (requires Actual server credentials) |
| paperless-mcp | ⚠️ | kneldevstack-aimiddleware-paperless-mcp | Documents (requires Paperless URL + token) |
#### Productivity & Automation (6 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| audiobook-mcp | ⚠️ | kneldevstack-aimiddleware-audiobook-mcp | Audiobooks (requires AUDIOBOOK_ROOT) |
| snipeit-mcp | ❌ | kneldevstack-aimiddleware-snipeit-mcp | Assets (blocked: private PyPI package) |
| mcp-redmine | ⚠️ | kneldevstack-aimiddleware-mcp-redmine | Projects (requires REDMINE_URL) |
| mcp-ansible | ❌ | kneldevstack-aimiddleware-mcp-ansible | Automation (package not in PyPI) |
| elasticsearch-mcp | ✅ | kneldevstack-aimiddleware-elasticsearch-mcp | Search (bundled with Elasticsearch) |
| drawio-mcp | ⚠️ | kneldevstack-aimiddleware-drawio-mcp | Diagrams (requires DRAWIO_URL) |
#### Additional Tools (2 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| penpot-mcp | ❌ | kneldevstack-aimiddleware-penpot-mcp | Design (HTTP/WebSocket transport, not stdio) |
| webserial-mcp | ❌ | kneldevstack-aimiddleware-webserial-mcp | ESP32 dev (requires bridge server + hardware) |
#### Reverse Engineering (2 servers)
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| ghidra-mcp | ✅ | kneldevstack-aimiddleware-ghidra-mcp | Binary analysis (HTTP REST, not MCP protocol) |
| reverse-engineering-assistant | ❌ | kneldevstack-aimiddleware-reverse-engineering-assistant | ReVa (upstream build error: Ghidra 404) |
### LSP Servers (4 servers) - All Production Ready ✅
| Service | Status | Container Name | Description |
|---------|--------|---------------|-------------|
| bash-language-server | ✅ | kneldevstack-aimiddleware-bash-language-server | LSP for bash (diagnostics, completion, formatting) |
| docker-language-server | ✅ | kneldevstack-aimiddleware-docker-language-server | LSP for Dockerfiles, Compose, Bake |
| marksman | ✅ | kneldevstack-aimiddleware-marksman | LSP for Markdown |
| terraform-ls | ✅ | kneldevstack-aimiddleware-terraform-ls | LSP for Terraform |
### Server Technologies by Language
#### TypeScript/Node.js (13 servers)
Most use `npx` for installation:
- KiCAD MCP, Bitwarden MCP, Discourse MCP, Ghost MCP, Cloudron MCP
- Kubernetes MCP, Draw.io MCP, Matomo MCP, Postiz MCP, WordPress MCP
- Audiobook MCP, Context7 MCP, Bash Language Server
#### Python (11 servers)
Most use `uvx` for installation:
- Blender MCP, FreeCAD MCP, GIMP MCP, Docker MCP, Proxmox MCP
- Snipe-IT MCP, Redmine MCP, IMAP MCP, Ansible MCP
- Nextcloud MCP (hybrid), WebSerial MCP
#### Go (2 servers)
- Kubernetes MCP (also available via npx), Terraform MCP
#### Rust (1 server)
- Elasticsearch MCP
#### Prebuilt Binaries (4 servers)
- bash-language-server (npm prebuilt)
- docker-language-server (Go binary)
- marksman (prebuilt binary)
- terraform-ls (HashiCorp release binary)
## 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>
```
### Setup Scripts
The repository includes helpful scripts in the `scripts/` directory:
#### scripts/CloneVendorRepos.sh
Clone all upstream vendor MCP/LSP repositories:
```bash
./scripts/CloneVendorRepos.sh
```
#### scripts/BuildAll.sh
Build all MCP/LSP services:
```bash
./scripts/BuildAll.sh
```
#### scripts/CleanVendor.sh
Remove all cloned vendor repositories:
```bash
./scripts/CleanVendor.sh
```
#### scripts/StatusCheck.sh
Check build status of all services:
```bash
./scripts/StatusCheck.sh
```
## 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
```
## Environment Variables
Required variables for MCP servers (see `.env.example`):
| Service | Required Variables |
|---------|-------------------|
| bitwarden-mcp | `BITWARDEN_CLIENT_ID`, `BITWARDEN_CLIENT_SECRET`, `BITWARDEN_PASSWORD`, `BITWARDEN_SERVER_URL` |
| discourse-mcp | `DISCOURSE_URL`, `DISCOURSE_API_KEY`, `DISCOURSE_API_USERNAME` |
| ghost-mcp | `GHOST_API_URL`, `GHOST_ADMIN_API_KEY` |
| cloudron-mcp | `CLOUDRON_URL`, `CLOUDRON_TOKEN` |
| nextcloud-mcp | `NEXTCLOUD_HOST`, `NEXTCLOUD_USERNAME`, `NEXTCLOUD_APP_PASSWORD` |
| proxmox-mcp | `PROXMOX_HOST`, `PROXMOX_USER`, `PROXMOX_TOKEN`, `PROXMOX_NODE` |
| snipeit-mcp | `SNIPEIT_URL`, `SNIPEIT_TOKEN` |
| redmine-mcp | `REDMINE_URL`, `REDMINE_API_KEY` |
| wordpress-mcp | `WORDPRESS_URL`, `WORDPRESS_USERNAME`, `WORDPRESS_APPLICATION_PASSWORD` |
| docspace-mcp | `DOCSPACE_HOST`, `DOCSPACE_TOKEN` |
| imap-mcp | `IMAP_SERVER`, `IMAP_PORT`, `IMAP_USERNAME`, `IMAP_PASSWORD` |
| postizz-mcp | `POSTIZ_API_KEY`, `POSTIZ_URL` |
| matomo-mcp | `MATOMO_URL`, `MATOMO_TOKEN` |
| elasticsearch-mcp | `ELASTICSEARCH_URL`, `ELASTICSEARCH_USERNAME`, `ELASTICSEARCH_PASSWORD` |
| kicad-mcp | `KICAD_HOST` (default: host.docker.internal), `KICAD_PORT` (default: 5555) |
| context7-mcp | `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` |
| penpot-mcp | `PENPOT_URL` (default: https://design.penpot.app), `PENPOT_TOKEN` |
| firefly-iii-mcp | `FIREFLY_III_BASE_URL`, `FIREFLY_III_PAT`, `FIREFLY_III_PRESET` (optional) |
| actual-mcp | `ACTUAL_SERVER_URL`, `ACTUAL_PASSWORD`, `ACTUAL_BUDGET_SYNC_ID` |
| paperless-mcp | `PAPERLESS_URL`, `PAPERLESS_TOKEN` |
**Security Note**: Never commit `.env` file to version control.
## 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)
├── docs/ # Documentation
│ └── SDLC.md # Software Development Lifecycle
├── AGENTS.md # AI agent guidelines and rules
├── STATUS.md # Server status and progress tracking
├── JOURNAL.md # Development journal (ADRs, insights)
└── 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
## 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 and [docs/SDLC.md](docs/SDLC.md) for the development workflow.
## References
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [Language Server Protocol](https://microsoft.github.io/language-server-protocol/)
- [MCP SDK](https://github.com/modelcontextprotocol/sdk)
- [Docker](https://www.docker.com/)
- [Charmbracelet Crush](https://github.com/charmbracelet/crush)
## License
This project is licensed under the MIT License - see [LICENSE](LICENSE) file for details.
---
**Maintained by**: KNEL Development Team

211
STATUS.md
View File

@@ -2,190 +2,35 @@
Tracking the setup and validation of MCP/LSP servers via Docker Compose. Tracking the setup and validation of MCP/LSP servers via Docker Compose.
Last validated: 2026-02-27
## Production Readiness Summary
| Category | Production Ready | Total | Percentage |
|----------|-----------------|-------|------------|
| MCP Servers | 29 | 38 | 76% |
| LSP Servers | 4 | 4 | 100% |
| **Total** | **33** | **42** | **79%** |
**See [PRODUCTION-READY.md](PRODUCTION-READY.md) for the complete list of deployable servers.**
## Repository URLs Verified (2026-02-19)
All 32 vendor repositories have been verified and correctly cloned. CloneVendorRepos.sh is up to date with official repository URLs.
**Cloned Repositories (33 total - 32 from user list + bitwarden/mcp-server):**
- reverse-engineering-assistant (cyberkaida)
- penpot-mcp (penpot)
- ghidra-mcp (bethington)
- drawio-mcp-server (lgazo)
- audiobook-mcp-server (joelmale)
- context7 (upstash)
- gimp-mcp (maorcc)
- mcp-adapter (WordPress)
- KiCAD-MCP-Server (mixelpixx)
- freecad-mcp (neka-nat)
- blender-mcp (ahujasid)
- nextcloud-mcp-server (cbcoutinho)
- docker-mcp (QuantGeekDev)
- ProxmoxMCP (canvrno)
- terraform-mcp-server (hashicorp)
- mcp-ansible (bsahane)
- snipeit-mcp (Wil-Collier)
- postizz-MCP (oculairmedia)
- discourse-mcp (discourse)
- mcp-cloudron (serenichron)
- ghost-mcp (MFYDev)
- mcp-redmine (runekaagaard)
- imap-mcp (non-dirty)
- matomo-mcp-client (openmost)
- kubernetes-mcp-server (containers)
- webserial-mcp (DG1001)
- docspace-mcp (ONLYOFFICE)
- paperless-mcp (nloui)
- docker-language-server (docker)
- bash-language-server (bash-lsp)
- terraform-ls (hashicorp)
- marksman (artempyanykh)
- mcp-server (bitwarden) - project extra
**Removed:**
- elasticsearch-mcp - Now bundled with Elasticsearch directly, standalone MCP no longer needed
## Validation Summary
**Working MCP Servers (29 validated with MCP handshake):**
- ✓ actual-mcp: Working (Actual Budget MCP) - requires ACTUAL_SERVER_URL, ACTUAL_PASSWORD, ACTUAL_BUDGET_SYNC_ID env vars
- ✓ ansible-mcp: Working (ansible-mcp v1.26.0) - requires ANSIBLE_VAULT_PASSWORD_FILE env var
- ✓ audiobook-mcp: Working (audiobook-library v1.1.0) - requires AUDIOBOOK_ROOT env var
- ✓ beszel-mcp: Working (beszel-mcp) - requires BESZEL_URL, BESZEL_USERNAME, BESZEL_PASSWORD env vars
- ✓ bitwarden-mcp: Working (Bitwarden MCP Server) - requires Bitwarden credentials
- ✓ blender-mcp: Working (BlenderMCP v1.25.0) - requires Blender with addon running
- ✓ cloudron-mcp: Working (cloudron-mcp v0.1.0) - requires CLOUDRON_URL env var
- ✓ context7-mcp: Working (Context7 v2.1.0) - stdio-based, requires Upstash Redis
- ✓ docker-mcp: Working (docker-mcp v0.1.0) - requires Docker socket mount
- ✓ docspace-mcp: Working (@onlyoffice/docspace-mcp v3.1.0) - requires DOCSPACE_HOST and DOCSPACE_TOKEN env vars
- ✓ drawio-mcp: Working (drawio-mcp-server v1.4.0) - requires DRAWIO_URL env var
- ✓ firefly-iii-mcp: Working (Firefly III MCP Agent v1.3.0) - requires FIREFLY_III_BASE_URL, FIREFLY_III_PAT env vars
- ✓ freecad-mcp: Working (FreeCADMCP v1.25.0) - requires FreeCAD with addon running
- ✓ ghost-mcp: Working (ghost-mcp-ts v1.0.0) - requires Ghost CMS credentials
- ✓ gimp-mcp: Working (GimpMCP v1.10.1) - requires GIMP with server running
- ✓ gitea-mcp: Working (gitea-mcp) - requires GITEA_URL and GITEA_TOKEN env vars
- ✓ grafana-mcp: Working (mcp-grafana) - requires GRAFANA_URL and GRAFANA_TOKEN env vars
- ✓ ha-mcp: Working (Home Assistant MCP) - requires HOMEASSISTANT_URL and HOMEASSISTANT_TOKEN env vars
- ✓ kubernetes-mcp: Working (mcp-k8s Go binary) - requires kubeconfig mounted at /root/.kube/config
- ✓ limesurvey-mcp: Working (limesurvey-mcp) - requires LIMESURVEY_URL, LIMESURVEY_USERNAME, LIMESURVEY_PASSWORD env vars
- ✓ linkwarden-mcp: Working (linkwarden-mcp v0.0.1) - requires LINKWARDEN_URL and LINKWARDEN_TOKEN env vars
- ✓ terraform-mcp: Working (terraform-mcp-server v0.4.0) - requires credentials for HCP Terraform
- ✓ matomo-mcp: Working (matomo-mcp-client v1.0.0) - connects to openmost.io hosted service (59 tools, 31 prompts)
- ✓ mcp-redmine: Working (Redmine MCP server v1.25.0) - requires REDMINE_URL for actual usage
- ✓ paperless-mcp: Working (paperless-ngx v1.0.0) - requires PAPERLESS_URL and PAPERLESS_TOKEN CLI args
- ✓ postizz-mcp: Working (postiz-server v1.0.0) - requires POSTIZ_API_KEY env var (fixed: stdio transport)
- ✓ superset-mcp: Working (superset-mcp) - requires SUPERSET_URL, SUPERSET_USERNAME, SUPERSET_PASSWORD env vars
- ✓ proxmox-mcp: Working (proxmox_mcp) - requires PROXMOX_MCP_CONFIG env var pointing to config file
**Runtime Connection Required (crash before MCP protocol):**
- ✗ nextcloud-mcp: Requires reachable OAuth endpoint - crashes on startup with connection refused
- ✗ imap-mcp: Requires reachable IMAP server - crashes on startup with connection refused
- ✗ webserial-mcp: Requires bridge server (esp32_bridge_server.py) at ws://host.docker.internal:3000
**Host-Only MCP Servers:**
- ✗ kicad-mcp: Requires KiCAD installed on host (pcbnew Python module unavailable in container)
**HTTP-based REST API Servers:**
- ✓ ghidra-mcp: Working (v1.9.4-headless) - 91 REST endpoints for binary analysis - NOT MCP protocol (uses HTTP REST)
**MCP Servers with Build/Runtime Issues:**
- ✗ discourse-mcp: BLOCKED - TypeScript TS2345 error (upstream SDK incompatibility, cannot fix)
- ✗ reverse-engineering-assistant: Build failed - Ghidra download 404
- ✗ penpot-mcp: Build OK, transport mismatch - uses HTTP/WebSocket transport instead of stdio
**Blocked MCP Servers:**
- ✗ snipeit-mcp: Blocked - upstream depends on private 'snipeit-api' package (never published to PyPI)
**LSP Servers:**
- ✓ bash-language-server: Working (v5.6.0) - stdio-based, configured in crush.json
- ✓ docker-language-server: Working (v0.0.0) - stdio-based, configured in crush.json
- ✓ marksman: Working (2025-12-13) - stdio-based, configured in crush.json
- ✓ terraform-ls: Working (v0.38.4) - stdio-based, configured in crush.json
## Detailed Status
| Repository | Status | Notes | | Repository | Status | Notes |
|------------|--------|-------| |------------|--------|-------|
| audiobook-mcp | Built | Container built from source (361MB). MCP stdio-based, requires AUDIOBOOK_ROOT env var. Version 1.1.0. | | KiCAD-MCP-Server | Pending | |
| bitwarden-mcp | Built | Container built from bitwarden/mcp-server. MCP stdio-based, requires Bitwarden credentials. | | freecad-mcp | Pending | |
| blender-mcp | Built | Container built from source (321MB). Python-based with uv package manager. MCP stdio-based, requires Blender running with addon. Version 1.25.0. | | blender-mcp | Pending | |
| cloudron-mcp | Built | Container built from source (374MB). MCP stdio-based, requires CLOUDRON_URL env var. Version 0.1.0. | | context7 | Pending | |
| context7-mcp | Built | Container built from source (224MB). Multi-stage Node.js build with tsc. MCP stdio-based, requires UPSTASH_REDIS_REST_URL and TOKEN env vars. Version 2.1.0. | | gimp-mcp | Pending | |
| discourse-mcp | Build Failed | TypeScript TS2345 error in upstream repository. Cannot build locally. | | bash-language-server | Pending | |
| docker-mcp | Built | Container built from Python source (188MB). Uses uv package manager. MCP stdio-based, requires Docker socket mount (/var/run/docker.sock). Version 0.1.0. | | docker-language-server | Pending | |
| docspace-mcp | Built | Container built from official ONLYOFFICE TypeScript source (236MB). Uses pnpm package manager. MCP stdio-based, requires DOCSPACE_HOST and DOCSPACE_TOKEN env vars. Version 3.1.0. | | drawio-mcp-server | Pending | |
| drawio-mcp | Built | Container built from TypeScript source (302MB). Uses pnpm package manager. MCP stdio-based, requires DRAWIO_URL env var. Version 1.4.0. | | matomo-mcp-client | Pending | |
| freecad-mcp | Built | Container built from Python source (317MB). Uses uv package manager. MCP stdio-based, requires FreeCAD running with addon. Version 1.25.0. | | imap-mcp | Pending | |
| ghost-mcp | Built | Container built from TypeScript source (284MB). npm build with tsc. MCP stdio-based, requires Ghost CMS URL and API key. Version 1.0.0. | | mcp-redmine | Pending | |
| ghidra-mcp | Built | Container built from Java source (1.2GB). Multi-stage build with Ghidra 12.0.3. REST API server (NOT MCP protocol) - 91 endpoints for binary analysis. Version 1.9.4-headless. | | ghost-mcp | Pending | |
| gimp-mcp | Built | Container built from Python source (418MB). Uses uv package manager. MCP stdio-based, requires GIMP with server running. Version 1.10.1. | | discourse-mcp | Pending | |
| imap-mcp | Runtime Issue | Container builds but crashes on startup if IMAP server unreachable. Cannot validate MCP protocol without live IMAP connection. | | mcp-cloudron | Pending | |
| kicad-mcp | Host-Only | Container builds successfully (463MB) but cannot run containerized. Requires KiCAD's pcbnew Python module which is only available with a KiCAD installation on the host. | | postizz-MCP | Pending | |
| kubernetes-mcp | Built | Container built from Go source (67MB). MCP stdio-based, requires kubeconfig mounted at /root/.kube/config. Supports K8s resources and Helm operations. | | snipeit-mcp | Pending | |
| matomo-mcp | Built | Container built from Python source. MCP stdio-based. Connects to openmost.io hosted Matomo service (59 tools, 31 prompts). MCP handshake validated. | | nextcloud-mcp-server | Pending | |
| mcp-ansible | Built | Container built from Python source. MCP stdio-based. Fixed to run local source instead of uvx. Version 1.26.0. | | docspace-mcp | Pending | |
| mcp-redmine | Built | Container built from Python source. MCP stdio-based, validated with MCP handshake. Requires REDMINE_URL for actual API operations. Version 1.25.0. | | docker-mcp | Pending | |
| nextcloud-mcp | Runtime Issue | Container builds but crashes on startup - requires reachable OAuth endpoint. Cannot validate MCP protocol without live Nextcloud instance. | | kubernetes-mcp-server | Pending | |
| paperless-mcp | Built | Container built from Python source. MCP stdio-based, requires PAPERLESS_URL and PAPERLESS_TOKEN as CLI args. MCP handshake validated without live server. Version 1.0.0. | | ProxmoxMCP | Pending | |
| firefly-iii-mcp | Built | Container built from npm package @firefly-iii-mcp/local. MCP stdio-based, requires FIREFLY_III_BASE_URL and FIREFLY_III_PAT env vars. MCP handshake validated without live server. Version 1.3.0. | | terraform-mcp-server | Pending | |
| penpot-mcp | Build/Runtime Issue | Container built from TypeScript monorepo source. Uses HTTP/WebSocket transport (not stdio). Multiple endpoints: HTTP at :4401/mcp, SSE at :4401/sse, WebSocket at :4402. | | mcp-ansible | Pending | |
| postizz-mcp | Built | Container built from TypeScript source. MCP stdio-based. Fixed to use stdio transport instead of HTTP. Version 1.0.0. | | mcp-server (Bitwarden) | Pending | |
| proxmox-mcp | Built | Container built from Python source (331MB). MCP stdio-based, requires PROXMOX_MCP_CONFIG env var pointing to config file. Fixed by patching fastmcp imports. | | mcp-adapter (WordPress) | Pending | |
| reverse-engineering-assistant | Build Failed | Ghidra download URL returns 404. Version mismatch in download URL. | | audiobook-mcp-server | Pending | |
| snipeit-mcp | Blocked | Container builds as stub that exits with error message. Upstream depends on private 'snipeit-api' package (never published to PyPI). Cannot be fixed without upstream changes. | | mcp-server-elasticsearch | Pending | |
| terraform-mcp | Built | Container built from Go source (27MB). MCP stdio-based, validates with MCP handshake v0.4.0. Requires HCP Terraform credentials for full functionality. |
| webserial-mcp | Runtime Issue | Container builds but requires bridge server + browser + ESP32 hardware. Cannot validate MCP protocol without full setup. |
| wordpress-mcp | Blocked | Cannot build as standalone MCP server. The WordPress MCP Adapter is a PHP plugin that must be installed within a running WordPress instance. |
| bash-language-server | Built | Container built using prebuilt npm package (190MB). LSP configured in crush.json. Version 5.6.0. |
| docker-language-server | Built | Container built from Go source (49.2MB). LSP configured in crush.json. Version 0.0.0. |
| marksman | Built | Container built from prebuilt binary (144MB). LSP configured in crush.json. Version 2025-12-13. |
| terraform-ls | Built | Container built from HashiCorp binary (64MB). LSP configured in crush.json. Version 0.38.4. |
## Known Issues
### nextcloud-mcp
Server crashes on startup if OAuth endpoint is unreachable. Server tries to connect to Nextcloud during initialization to fetch OAuth discovery document. If connection fails, server raises ConnectError and exits before responding to JSON-RPC initialize.
### imap-mcp
Server crashes on startup if IMAP connection fails. Server tries to connect to IMAP during lifespan context entry. If connection fails, server raises ConnectionError and exits before responding to JSON-RPC initialize.
### webserial-mcp
Requires bridge server (esp32_bridge_server.py) running on host at ws://host.docker.internal:3000 plus browser with WebSerial access and ESP32 hardware.
### kicad-mcp
Host-only - requires KiCAD installed on the host machine. The pcbnew Python module cannot be pip-installed and is only available with a full KiCAD installation.
### wordpress-mcp
The WordPress MCP Adapter is a PHP plugin that must be installed within a running WordPress instance. It requires WordPress + Abilities API plugin + MCP Adapter plugin. Not suitable for containerized standalone deployment.
### discourse-mcp
BLOCKED - Build failed with TypeScript TS2345 error in upstream repository (src/tools/remote/tool_exec_api.ts:58). The code is incompatible with MCP SDK types. Cannot fix locally without upstream changes.
### proxmox-mcp
Fixed by patching pyproject.toml to use 'fastmcp' from PyPI instead of 'mcp @ git+...' and updating imports from 'mcp.server.fastmcp' to 'fastmcp'. Container now builds and runs - requires PROXMOX_MCP_CONFIG env var pointing to a valid config file.
### snipeit-mcp
BLOCKED - The upstream snipeit-mcp depends on a private 'snipeit-api' package (referenced via local file path) that was never published to PyPI. The public PyPI 'snipeit' package (v1.1, archived 2022) has a completely different API. Cannot be fixed without upstream author publishing the private package or rewriting to use the public package API. Created stub Dockerfile that exits with informative error message.
### penpot-mcp
Uses HTTP/WebSocket transport instead of stdio MCP. Not compatible with standard MCP client connections. Multiple endpoints: HTTP at :4401/mcp, SSE at :4401/sse, WebSocket at :4402.
### mcp-ansible
FIXED - Changed Dockerfile entrypoint to run local source (`python src/ansible_mcp/server.py`) instead of uvx. The package is not published to PyPI, so local installation is required. MCP handshake validated with version 1.26.0.
### reverse-engineering-assistant
Build failed - Ghidra download URL returns 404. The version number in the Dockerfile download URL is incorrect.
## Usage ## Usage
@@ -209,4 +54,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 compose file. Container names will be prefixed with kneldevstack-aimiddleware-. Note: Use lowercase service names from the compose file. Container names will still be prefixed with CDS-AIMW-.

View File

@@ -1,194 +0,0 @@
{
"$schema": "https://charm.land/crush.json",
"lsp": {
"bash": {
"command": "/home/charles/Projects/KNEL-AIMiddleware/lsp-bash-wrapper.sh"
},
"docker": {
"command": "/home/charles/Projects/KNEL-AIMiddleware/lsp-docker-wrapper.sh"
},
"markdown": {
"command": "/home/charles/Projects/KNEL-AIMiddleware/lsp-marksman-wrapper.sh"
},
"terraform": {
"command": "/home/charles/Projects/KNEL-AIMiddleware/lsp-terraform-wrapper.sh"
}
},
"mcp": {
"audiobook": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-audiobook-wrapper.sh",
"timeout": 60
},
"bitwarden": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-bitwarden-wrapper.sh",
"timeout": 60
},
"blender": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-blender-wrapper.sh",
"timeout": 180
},
"cloudron": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-cloudron-wrapper.sh",
"timeout": 60
},
"context7": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-context7-wrapper.sh",
"timeout": 60
},
"docker": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-docker-wrapper.sh",
"timeout": 180
},
"drawio": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-drawio-wrapper.sh",
"timeout": 60
},
"elasticsearch": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-elasticsearch-wrapper.sh",
"timeout": 60
},
"freecad": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-freecad-wrapper.sh",
"timeout": 180
},
"ghost": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-ghost-wrapper.sh",
"timeout": 60
},
"gimp": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-gimp-wrapper.sh",
"timeout": 180
},
"imap": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-imap-wrapper.sh",
"timeout": 60
},
"kubernetes": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-kubernetes-wrapper.sh",
"timeout": 60
},
"docspace": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-docspace-wrapper.sh",
"timeout": 60
},
"webserial": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-webserial-wrapper.sh",
"timeout": 60
},
"proxmox": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-proxmox-wrapper.sh",
"timeout": 60
},
"terraform": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-terraform-wrapper.sh",
"timeout": 60
},
"nextcloud": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-nextcloud-wrapper.sh",
"timeout": 60
},
"matomo": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-matomo-wrapper.sh",
"timeout": 60
},
"snipeit": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-snipeit-wrapper.sh",
"timeout": 60
},
"redmine": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-redmine-wrapper.sh",
"timeout": 60
},
"ansible": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-ansible-wrapper.sh",
"timeout": 60
},
"actual": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-actual-wrapper.sh",
"timeout": 60
},
"beszel": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-beszel-wrapper.sh",
"timeout": 60
},
"gitea": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-gitea-wrapper.sh",
"timeout": 60
},
"grafana": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-grafana-wrapper.sh",
"timeout": 60
},
"homeassistant": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-ha-wrapper.sh",
"timeout": 60
},
"limesurvey": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-limesurvey-wrapper.sh",
"timeout": 60
},
"linkwarden": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-linkwarden-wrapper.sh",
"timeout": 60
},
"superset": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-superset-wrapper.sh",
"timeout": 60
},
"postizz": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-postizz-wrapper.sh",
"timeout": 60
},
"discourse": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-discourse-wrapper.sh",
"timeout": 60
},
"penpot": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-penpot-wrapper.sh",
"timeout": 60
},
"firefly-iii": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-firefly-iii-wrapper.sh",
"timeout": 60
},
"paperless": {
"type": "stdio",
"command": "/home/charles/Projects/KNEL-AIMiddleware/mcp-paperless-wrapper.sh",
"timeout": 60
}
}
}

View File

@@ -4,63 +4,41 @@ services:
# ========================================== # ==========================================
# KiCAD MCP - PCB design automation # KiCAD MCP - PCB design automation
# NOTE: Requires KiCAD to be installed on host machine
# The MCP server connects to an existing KiCAD instance via TCP
kicad-mcp: kicad-mcp:
image: kneldevstack-aimiddleware-kicad-mcp
build: build:
context: ./vendor/KiCAD-MCP-Server context: ./vendor/KiCAD-MCP-Server
dockerfile: ../../dockerfiles/kicad-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-kicad-mcp container_name: KNELDevStack-AIMW-kicad-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- KICAD_HOST=${KICAD_HOST:-host.docker.internal}
- KICAD_PORT=${KICAD_PORT:-5555}
command: ["node", "dist/index.js"] command: ["node", "dist/index.js"]
profiles: profiles:
- dev - dev
# Blender MCP - 3D modeling and materials # Blender MCP - 3D modeling and materials
blender-mcp: blender-mcp:
image: kneldevstack-aimiddleware-blender-mcp
build: build:
context: ./vendor/blender-mcp context: ./vendor/blender-mcp
dockerfile: ../../dockerfiles/blender-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-blender-mcp container_name: KNELDevStack-AIMW-blender-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
command: ["uvx", "blender-mcp"]
profiles: profiles:
- dev - dev
# FreeCAD MCP - CAD modeling # FreeCAD MCP - CAD modeling
freecad-mcp: freecad-mcp:
image: kneldevstack-aimiddleware-freecad-mcp
build: build:
context: ./vendor/freecad-mcp context: ./vendor/freecad-mcp
dockerfile: ../../dockerfiles/freecad-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-freecad-mcp container_name: KNELDevStack-AIMW-freecad-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
profiles: command: ["uvx", "freecad-mcp"]
- dev
# ESP32 WebSerial MCP - MicroPython development via WebSerial
# NOTE: Requires bridge server running on host (esp32_bridge_server.py)
# and browser with WebSerial connected to ESP32
webserial-mcp:
image: kneldevstack-aimiddleware-webserial-mcp
build:
context: ./vendor/webserial-mcp
dockerfile: ../../dockerfiles/webserial-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-webserial-mcp
restart: unless-stopped
environment:
- PYTHONUNBUFFERED=1
- WEBSOCKET_URL=ws://host.docker.internal:3000
- MCP_TIMEOUT=30
profiles: profiles:
- dev - dev
@@ -70,12 +48,13 @@ services:
# Kubernetes MCP - K8s/OpenShift management # Kubernetes MCP - K8s/OpenShift management
kubernetes-mcp: kubernetes-mcp:
image: kneldevstack-aimiddleware-kubernetes-mcp
build: build:
context: ./vendor/kubernetes-mcp-server context: ./vendor/kubernetes-mcp-server
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-kubernetes-mcp container_name: KNELDevStack-AIMW-kubernetes-mcp
restart: unless-stopped restart: unless-stopped
ports:
- "8081:8080"
volumes: volumes:
- ~/.kube/config:/root/.kube/config:ro - ~/.kube/config:/root/.kube/config:ro
profiles: profiles:
@@ -83,11 +62,10 @@ services:
# Docker MCP - Container and compose management # Docker MCP - Container and compose management
docker-mcp: docker-mcp:
image: kneldevstack-aimiddleware-docker-mcp
build: build:
context: ./vendor/docker-mcp context: ./vendor/docker-mcp
dockerfile: ../../dockerfiles/docker-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-docker-mcp container_name: KNELDevStack-AIMW-docker-mcp
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
@@ -100,11 +78,10 @@ services:
# Proxmox MCP - Hypervisor management # Proxmox MCP - Hypervisor management
proxmox-mcp: proxmox-mcp:
image: kneldevstack-aimiddleware-proxmox-mcp
build: build:
context: ./vendor/ProxmoxMCP context: ./vendor/ProxmoxMCP
dockerfile: ../../dockerfiles/proxmox-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-proxmox-mcp container_name: KNELDevStack-AIMW-proxmox-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
@@ -112,17 +89,17 @@ services:
- PROXMOX_USER=${PROXMOX_USER} - PROXMOX_USER=${PROXMOX_USER}
- PROXMOX_TOKEN=${PROXMOX_TOKEN} - PROXMOX_TOKEN=${PROXMOX_TOKEN}
- PROXMOX_NODE=${PROXMOX_NODE} - PROXMOX_NODE=${PROXMOX_NODE}
command: ["uvx", "proxmox-mcp"]
profiles: profiles:
- ops - ops
# Terraform MCP - IaC automation # Terraform MCP - IaC automation
terraform-mcp: terraform-mcp:
image: kneldevstack-aimiddleware-terraform-mcp
build: build:
context: ./vendor/terraform-mcp-server context: ./vendor/terraform-mcp-server
dockerfile: Dockerfile dockerfile: Dockerfile
target: dev target: dev
container_name: kneldevstack-aimiddleware-terraform-mcp container_name: KNELDevStack-AIMW-terraform-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- HOME=/terraform - HOME=/terraform
@@ -134,11 +111,10 @@ services:
# Cloudron MCP - Self-hosted app management # Cloudron MCP - Self-hosted app management
cloudron-mcp: cloudron-mcp:
image: kneldevstack-aimiddleware-cloudron-mcp
build: build:
context: ./vendor/mcp-cloudron context: ./vendor/mcp-cloudron
dockerfile: ../../dockerfiles/cloudron-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-cloudron-mcp container_name: KNELDevStack-AIMW-cloudron-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- CLOUDRON_URL=${CLOUDRON_URL} - CLOUDRON_URL=${CLOUDRON_URL}
@@ -147,45 +123,33 @@ services:
- ops - ops
# ========================================== # ==========================================
# Development Tools (3 servers) # Development Tools (2 servers)
# ========================================== # ==========================================
# Bash Language Server - LSP for bash # Bash Language Server - LSP for bash
# NOTE: This is a stdio-based LSP server, run on-demand by Crush via docker run
bash-language-server: bash-language-server:
image: kneldevstack-aimiddleware-bash-language-server
build: build:
context: ./vendor/bash-language-server context: ./vendor/bash-language-server
dockerfile: ../../dockerfiles/bash-language-server/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-bash-language-server container_name: KNELDevStack-AIMW-bash-language-server
restart: "no" restart: unless-stopped
profiles: ports:
- dev - "8082:8080"
command: ["npm", "start"]
# Terraform Language Server - LSP for Terraform
# NOTE: This is a stdio-based LSP server, run on-demand by Crush via docker run
terraform-ls:
image: kneldevstack-aimiddleware-terraform-ls
build:
context: .
dockerfile: dockerfiles/terraform-ls/Dockerfile
container_name: kneldevstack-aimiddleware-terraform-ls
restart: "no"
profiles: profiles:
- dev - dev
# Context7 MCP - Documentation framework # Context7 MCP - Documentation framework
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
context7-mcp: context7-mcp:
image: kneldevstack-aimiddleware-context7-mcp
build: build:
context: ./vendor/context7 context: ./vendor/context7
dockerfile: ../../dockerfiles/context7/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-context7-mcp container_name: KNELDevStack-AIMW-context7-mcp
restart: "no" restart: unless-stopped
environment: environment:
- UPSTASH_REDIS_REST_URL=${UPSTASH_REDIS_REST_URL} - UPSTASH_REDIS_REST_URL=${UPSTASH_REDIS_REST_URL}
- UPSTASH_REDIS_REST_TOKEN=${UPSTASH_REDIS_REST_TOKEN} - UPSTASH_REDIS_REST_TOKEN=${UPSTASH_REDIS_REST_TOKEN}
command: ["node", "packages/mcp/dist/index.js", "--transport", "stdio"]
profiles: profiles:
- dev - dev
@@ -193,45 +157,43 @@ services:
# Content Management (4 servers) # Content Management (4 servers)
# ========================================== # ==========================================
# Nextcloud MCP - 90+ tools across 8 apps (HTTP-based) # Nextcloud MCP - 90+ tools across 8 apps
nextcloud-mcp: nextcloud-mcp:
image: kneldevstack-aimiddleware-nextcloud-mcp
build: build:
context: ./vendor/nextcloud-mcp-server context: ./vendor/nextcloud-mcp-server
dockerfile: ../../dockerfiles/nextcloud-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-nextcloud-mcp container_name: KNELDevStack-AIMW-nextcloud-mcp
restart: unless-stopped restart: unless-stopped
ports:
- "8083:8000"
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- NEXTCLOUD_HOST=${NEXTCLOUD_HOST} - NEXTCLOUD_HOST=${NEXTCLOUD_HOST}
- NEXTCLOUD_USERNAME=${NEXTCLOUD_USERNAME} - NEXTCLOUD_USERNAME=${NEXTCLOUD_USERNAME}
- NEXTCLOUD_PASSWORD=${NEXTCLOUD_PASSWORD} - NEXTCLOUD_APP_PASSWORD=${NEXTCLOUD_APP_PASSWORD}
ports:
- "8083:8080"
profiles: profiles:
- ops - ops
# Ghost MCP - CMS integration # Ghost MCP - CMS management
ghost-mcp: ghost-mcp:
image: kneldevstack-aimiddleware-ghost-mcp
build: build:
context: ./vendor/ghost-mcp context: ./vendor/ghost-mcp
dockerfile: ../../dockerfiles/ghost-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-ghost-mcp container_name: KNELDevStack-AIMW-ghost-mcp
restart: "no" restart: unless-stopped
environment: environment:
- GHOST_API_URL=${GHOST_API_URL:-http://localhost:2368} - GHOST_API_URL=${GHOST_API_URL}
- GHOST_ADMIN_API_KEY=${GHOST_ADMIN_API_KEY:-012345678901234567890123:0123456789012345678901234567890123456789012345678901234567890123} - GHOST_ADMIN_API_KEY=${GHOST_ADMIN_API_KEY}
command: ["npx", "-y", "@fanyangmeng/ghost-mcp"]
profiles: profiles:
- ops - ops
# ONLYOFFICE DocSpace MCP - Room and file management # ONLYOFFICE DocSpace MCP - Room and file management
docspace-mcp: docspace-mcp:
image: kneldevstack-aimiddleware-docspace-mcp
build: build:
context: ./vendor/docspace-mcp context: ./vendor/docspace-mcp
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-docspace-mcp container_name: KNELDevStack-AIMW-docspace-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- DOCSPACE_HOST=${DOCSPACE_HOST} - DOCSPACE_HOST=${DOCSPACE_HOST}
@@ -239,28 +201,12 @@ services:
profiles: profiles:
- ops - ops
# Paperless-NGX MCP - Document management
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
paperless-mcp:
image: kneldevstack-aimiddleware-paperless-mcp
build:
context: ./vendor/paperless-mcp
dockerfile: ../../dockerfiles/paperless-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-paperless-mcp
restart: "no"
environment:
- PAPERLESS_URL=${PAPERLESS_URL}
- PAPERLESS_TOKEN=${PAPERLESS_TOKEN}
profiles:
- ops
# WordPress MCP Adapter # WordPress MCP Adapter
wordpress-mcp: wordpress-mcp:
image: kneldevstack-aimiddleware-wordpress-mcp
build: build:
context: ./vendor/mcp-adapter context: ./vendor/mcp-adapter
dockerfile: ../../dockerfiles/wordpress-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-wordpress-mcp container_name: KNELDevStack-AIMW-wordpress-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- WORDPRESS_URL=${WORDPRESS_URL} - WORDPRESS_URL=${WORDPRESS_URL}
@@ -276,44 +222,42 @@ services:
# Discourse MCP - Forum integration # Discourse MCP - Forum integration
discourse-mcp: discourse-mcp:
image: kneldevstack-aimiddleware-discourse-mcp
build: build:
context: ./vendor/discourse-mcp context: ./vendor/discourse-mcp
dockerfile: ../../dockerfiles/discourse-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-discourse-mcp container_name: KNELDevStack-AIMW-discourse-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- DISCOURSE_URL=${DISCOURSE_URL} - DISCOURSE_URL=${DISCOURSE_URL}
- DISCOURSE_API_KEY=${DISCOURSE_API_KEY} - DISCOURSE_API_KEY=${DISCOURSE_API_KEY}
- DISCOURSE_API_USERNAME=${DISCOURSE_API_USERNAME} - DISCOURSE_API_USERNAME=${DISCOURSE_API_USERNAME}
command: ["npx", "-y", "@discourse/mcp"]
profiles: profiles:
- ops - ops
# IMAP MCP - Email processing # IMAP MCP - Email processing
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
imap-mcp: imap-mcp:
image: kneldevstack-aimiddleware-imap-mcp
build: build:
context: ./vendor/imap-mcp context: ./vendor/imap-mcp
dockerfile: ../../dockerfiles/imap-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-imap-mcp container_name: KNELDevStack-AIMW-imap-mcp
restart: "no" restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- IMAP_HOST=${IMAP_HOST} - IMAP_SERVER=${IMAP_SERVER}
- IMAP_PORT=${IMAP_PORT:-993} - IMAP_PORT=${IMAP_PORT:-993}
- IMAP_USERNAME=${IMAP_USERNAME} - IMAP_USERNAME=${IMAP_USERNAME}
- IMAP_PASSWORD=${IMAP_PASSWORD} - IMAP_PASSWORD=${IMAP_PASSWORD}
command: ["uvx", "imap-mcp"]
profiles: profiles:
- ops - ops
# Postiz MCP - Social media management # Postiz MCP - Social media management
postizz-mcp: postizz-mcp:
image: kneldevstack-aimiddleware-postizz-mcp
build: build:
context: ./vendor/postizz-MCP context: ./vendor/postizz-MCP
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-postizz-mcp container_name: KNELDevStack-AIMW-postizz-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- POSTIZ_API_KEY=${POSTIZ_API_KEY} - POSTIZ_API_KEY=${POSTIZ_API_KEY}
@@ -327,11 +271,10 @@ services:
# Matomo MCP Client # Matomo MCP Client
matomo-mcp: matomo-mcp:
image: kneldevstack-aimiddleware-matomo-mcp
build: build:
context: ./vendor/matomo-mcp-client context: ./vendor/matomo-mcp-client
dockerfile: ../../dockerfiles/matomo-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-matomo-mcp container_name: KNELDevStack-AIMW-matomo-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- MATOMO_URL=${MATOMO_URL} - MATOMO_URL=${MATOMO_URL}
@@ -341,11 +284,10 @@ services:
# Bitwarden MCP - Password vault # Bitwarden MCP - Password vault
bitwarden-mcp: bitwarden-mcp:
image: kneldevstack-aimiddleware-bitwarden-mcp
build: build:
context: ./vendor/mcp-server context: ./vendor/mcp-server
dockerfile: ../../dockerfiles/bitwarden-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-bitwarden-mcp container_name: KNELDevStack-AIMW-bitwarden-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- BITWARDEN_CLIENT_ID=${BITWARDEN_CLIENT_ID} - BITWARDEN_CLIENT_ID=${BITWARDEN_CLIENT_ID}
@@ -362,24 +304,23 @@ services:
# GIMP MCP - Image editing # GIMP MCP - Image editing
gimp-mcp: gimp-mcp:
image: kneldevstack-aimiddleware-gimp-mcp
build: build:
context: ./vendor/gimp-mcp context: ./vendor/gimp-mcp
dockerfile: ../../dockerfiles/gimp-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-gimp-mcp container_name: KNELDevStack-AIMW-gimp-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
command: ["uvx", "gimp-mcp"]
profiles: profiles:
- dev - dev
# Snipe-IT MCP - Asset inventory # Snipe-IT MCP - Asset inventory
snipeit-mcp: snipeit-mcp:
image: kneldevstack-aimiddleware-snipeit-mcp
build: build:
context: ./vendor context: ./vendor/snipeit-mcp
dockerfile: ../dockerfiles/snipeit-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-snipeit-mcp container_name: KNELDevStack-AIMW-snipeit-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
@@ -390,28 +331,26 @@ services:
- ops - ops
# Redmine MCP - Project management # Redmine MCP - Project management
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
mcp-redmine: mcp-redmine:
image: kneldevstack-aimiddleware-mcp-redmine
build: build:
context: ./vendor/mcp-redmine context: ./vendor/mcp-redmine
dockerfile: ../../dockerfiles/mcp-redmine/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-mcp-redmine container_name: KNELDevStack-AIMW-mcp-redmine
restart: "no" restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- REDMINE_URL=${REDMINE_URL} - REDMINE_URL=${REDMINE_URL}
- REDMINE_API_KEY=${REDMINE_API_KEY} - REDMINE_API_KEY=${REDMINE_API_KEY}
command: ["uvx", "mcp-redmine"]
profiles: profiles:
- ops - ops
# Ansible MCP - IT automation # Ansible MCP - IT automation
mcp-ansible: mcp-ansible:
image: kneldevstack-aimiddleware-mcp-ansible
build: build:
context: ./vendor/mcp-ansible context: ./vendor/mcp-ansible
dockerfile: ../../dockerfiles/mcp-ansible/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-mcp-ansible container_name: KNELDevStack-AIMW-mcp-ansible
restart: unless-stopped restart: unless-stopped
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
@@ -424,14 +363,13 @@ services:
# Elasticsearch MCP # Elasticsearch MCP
elasticsearch-mcp: elasticsearch-mcp:
image: kneldevstack-aimiddleware-elasticsearch-mcp
build: build:
context: ./vendor/mcp-server-elasticsearch context: ./vendor/mcp-server-elasticsearch
dockerfile: ../../dockerfiles/elasticsearch-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-elasticsearch-mcp container_name: KNELDevStack-AIMW-elasticsearch-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- ES_URL=${ES_URL:-http://localhost:9200} - ELASTICSEARCH_URL=${ELASTICSEARCH_URL:-http://localhost:9200}
- ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME} - ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME}
- ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD} - ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD}
ports: ports:
@@ -441,17 +379,16 @@ services:
# Audiobook MCP Server # Audiobook MCP Server
audiobook-mcp: audiobook-mcp:
image: kneldevstack-aimiddleware-audiobook-mcp
build: build:
context: ./vendor/audiobook-mcp-server context: ./vendor/audiobook-mcp-server
dockerfile: ../../dockerfiles/audiobook-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-audiobook-mcp container_name: KNELDevStack-AIMW-audiobook-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- AUDIOBOOK_ROOT=${AUDIOBOOK_ROOT:-/audiobooks} - AUDIOBOOK_LIBRARY_PATH=${AUDIOBOOK_LIBRARY_PATH:-/audiobooks}
volumes: volumes:
- ${AUDIOBOOK_ROOT:-/audiobooks}:/audiobooks - ${AUDIOBOOK_LIBRARY_PATH:-/audiobooks}:/audiobooks
command: ["node", "dist/index.js"] command: ["npx", "-y", "audiobook-mcp-server"]
profiles: profiles:
- dev - dev
@@ -461,280 +398,25 @@ services:
# Draw.io MCP Server # Draw.io MCP Server
drawio-mcp: drawio-mcp:
image: kneldevstack-aimiddleware-drawio-mcp
build: build:
context: ./vendor/drawio-mcp-server context: ./vendor/drawio-mcp-server
dockerfile: ../../dockerfiles/drawio-mcp/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-drawio-mcp container_name: KNELDevStack-AIMW-drawio-mcp
restart: unless-stopped restart: unless-stopped
environment: environment:
- DRAWIO_URL=${DRAWIO_URL:-https://app.diagrams.net} - DRAWIO_URL=${DRAWIO_URL:-https://app.diagrams.net}
command: ["npx", "-y", "drawio-mcp-server"]
profiles: profiles:
- dev - dev
# Docker Language Server # Docker Language Server
# NOTE: This is a stdio-based LSP server, run on-demand by Crush via docker run
docker-language-server: docker-language-server:
image: kneldevstack-aimiddleware-docker-language-server
build: build:
context: ./vendor/docker-language-server context: ./vendor/docker-language-server
dockerfile: ../../dockerfiles/docker-language-server/Dockerfile dockerfile: Dockerfile
container_name: kneldevstack-aimiddleware-docker-language-server container_name: KNELDevStack-AIMW-docker-language-server
restart: "no"
profiles:
- dev
# Marksman LSP - Markdown language server
# NOTE: This is a stdio-based LSP server, run on-demand by Crush via docker run
marksman:
image: kneldevstack-aimiddleware-marksman
build:
context: ./vendor/marksman
dockerfile: ../../dockerfiles/marksman/Dockerfile
container_name: kneldevstack-aimiddleware-marksman
restart: "no"
profiles:
- dev
# ==========================================
# Design Tools (Added Later)
# ==========================================
# Penpot MCP - Design collaboration platform
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
penpot-mcp:
image: kneldevstack-aimiddleware-penpot-mcp
build:
context: ./vendor/penpot-mcp
dockerfile: ../../dockerfiles/penpot-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-penpot-mcp
restart: "no"
environment:
- PENPOT_URL=${PENPOT_URL:-https://design.penpot.app}
- PENPOT_TOKEN=${PENPOT_TOKEN}
profiles:
- dev
# ==========================================
# Reverse Engineering (2 servers)
# ==========================================
# Ghidra MCP - Binary analysis and reverse engineering
# NOTE: Requires Ghidra 12.0.2 (downloaded during build, ~300MB)
# Uses bridge_mcp_ghidra.py for stdio transport
ghidra-mcp:
image: kneldevstack-aimiddleware-ghidra-mcp
build:
context: ./vendor/ghidra-mcp
dockerfile: docker/Dockerfile
container_name: kneldevstack-aimiddleware-ghidra-mcp
restart: unless-stopped restart: unless-stopped
environment:
- GHIDRA_MCP_PORT=8089
- JAVA_OPTS=-Xmx4g -XX:+UseG1GC
volumes:
- ghidra-projects:/projects
- ghidra-data:/data
ports: ports:
- "8089:8089" - "8085:8080"
profiles: profiles:
- dev - dev
# ReVa - Reverse Engineering Assistant (MCP for Ghidra)
# NOTE: Requires Ghidra 12.0+ and Java 21
# Runs in headless mode for containerized AI-assisted reverse engineering
reverse-engineering-assistant:
image: kneldevstack-aimiddleware-reverse-engineering-assistant
build:
context: ./vendor/reverse-engineering-assistant
dockerfile: ../../dockerfiles/reverse-engineering-assistant/Dockerfile
container_name: kneldevstack-aimiddleware-reverse-engineering-assistant
restart: unless-stopped
environment:
- GHIDRA_INSTALL_DIR=/opt/ghidra
- REVA_MODE=headless
- JAVA_OPTS=-Xmx4g -XX:+UseG1GC
volumes:
- ghidra-projects:/projects
- ghidra-data:/data
profiles:
- dev
# ==========================================
# Financial & Budgeting (2 servers)
# ==========================================
# Actual Budget MCP - Budget management
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
actual-mcp:
image: kneldevstack-aimiddleware-actual-mcp
build:
context: ./vendor/actual-mcp
dockerfile: ../../dockerfiles/actual-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-actual-mcp
restart: "no"
environment:
- ACTUAL_SERVER_URL=${ACTUAL_SERVER_URL}
- ACTUAL_PASSWORD=${ACTUAL_PASSWORD}
- ACTUAL_BUDGET_SYNC_ID=${ACTUAL_BUDGET_SYNC_ID}
profiles:
- ops
# Firefly III MCP - Personal finance manager
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
firefly-iii-mcp:
image: kneldevstack-aimiddleware-firefly-iii-mcp
build:
context: .
dockerfile: dockerfiles/firefly-iii-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-firefly-iii-mcp
restart: "no"
environment:
- FIREFLY_III_BASE_URL=${FIREFLY_III_BASE_URL}
- FIREFLY_III_PAT=${FIREFLY_III_PAT}
- FIREFLY_III_PRESET=${FIREFLY_III_PRESET:-default}
profiles:
- ops
# ==========================================
# System Monitoring (1 server)
# ==========================================
# Beszel MCP - System monitoring tool
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
beszel-mcp:
image: kneldevstack-aimiddleware-beszel-mcp
build:
context: ./vendor/beszel-mcp
dockerfile: ../../dockerfiles/beszel-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-beszel-mcp
restart: "no"
environment:
- PYTHONUNBUFFERED=1
- BESZEL_URL=${BESZEL_URL}
- BESZEL_USERNAME=${BESZEL_USERNAME}
- BESZEL_PASSWORD=${BESZEL_PASSWORD}
profiles:
- ops
# ==========================================
# Git Hosting (1 server)
# ==========================================
# Gitea MCP - Git hosting integration
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
gitea-mcp:
image: kneldevstack-aimiddleware-gitea-mcp
build:
context: ./vendor/gitea-mcp
dockerfile: ../../dockerfiles/gitea-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-gitea-mcp
restart: "no"
environment:
- GITEA_URL=${GITEA_URL}
- GITEA_TOKEN=${GITEA_TOKEN}
profiles:
- ops
# ==========================================
# Home Automation (1 server)
# ==========================================
# Home Assistant MCP - Complete HA control
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
ha-mcp:
image: kneldevstack-aimiddleware-ha-mcp
build:
context: ./vendor/ha-mcp
dockerfile: ../../dockerfiles/ha-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-ha-mcp
restart: "no"
environment:
- PYTHONUNBUFFERED=1
- HOMEASSISTANT_URL=${HOMEASSISTANT_URL}
- HOMEASSISTANT_TOKEN=${HOMEASSISTANT_TOKEN}
profiles:
- ops
# ==========================================
# Survey Tools (1 server)
# ==========================================
# LimeSurvey MCP - Survey management
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
limesurvey-mcp:
image: kneldevstack-aimiddleware-limesurvey-mcp
build:
context: ./vendor/limesurvey-mcp
dockerfile: ../../dockerfiles/limesurvey-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-limesurvey-mcp
restart: "no"
environment:
- LIMESURVEY_URL=${LIMESURVEY_URL}
- LIMESURVEY_USERNAME=${LIMESURVEY_USERNAME}
- LIMESURVEY_PASSWORD=${LIMESURVEY_PASSWORD}
profiles:
- ops
# ==========================================
# Bookmark Management (1 server)
# ==========================================
# Linkwarden MCP - Bookmark management
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
linkwarden-mcp:
image: kneldevstack-aimiddleware-linkwarden-mcp
build:
context: ./vendor/linkwarden-mcp-server
dockerfile: ../../dockerfiles/linkwarden-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-linkwarden-mcp
restart: "no"
environment:
- LINKWARDEN_URL=${LINKWARDEN_URL}
- LINKWARDEN_TOKEN=${LINKWARDEN_TOKEN}
profiles:
- ops
# ==========================================
# Observability (1 server)
# ==========================================
# Grafana MCP - Dashboard and observability
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
mcp-grafana:
image: kneldevstack-aimiddleware-mcp-grafana
build:
context: ./vendor/mcp-grafana
dockerfile: ../../dockerfiles/mcp-grafana/Dockerfile
container_name: kneldevstack-aimiddleware-mcp-grafana
restart: "no"
environment:
- GRAFANA_URL=${GRAFANA_URL}
- GRAFANA_TOKEN=${GRAFANA_TOKEN}
profiles:
- ops
# ==========================================
# Business Intelligence (1 server)
# ==========================================
# Superset MCP - Apache Superset integration
# NOTE: This is a stdio-based MCP server, run on-demand by Crush via docker run
superset-mcp:
image: kneldevstack-aimiddleware-superset-mcp
build:
context: ./vendor/superset-mcp
dockerfile: ../../dockerfiles/superset-mcp/Dockerfile
container_name: kneldevstack-aimiddleware-superset-mcp
restart: "no"
environment:
- PYTHONUNBUFFERED=1
- SUPERSET_URL=${SUPERSET_URL}
- SUPERSET_USERNAME=${SUPERSET_USERNAME}
- SUPERSET_PASSWORD=${SUPERSET_PASSWORD}
profiles:
- ops
volumes:
ghidra-projects:
ghidra-data:

View File

@@ -1,13 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
CMD ["node", "build/index.js"]

View File

@@ -1,16 +0,0 @@
FROM node:22-alpine
RUN apk add --no-cache ffmpeg
WORKDIR /app
COPY package.json package-lock.json* ./
# Use npm install instead of npm ci to avoid esbuild ETXTBSY errors
RUN npm install --ignore-scripts
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]

View File

@@ -1,10 +0,0 @@
FROM node:22-alpine
WORKDIR /app
# Install prebuilt bash-language-server from npm
RUN npm install -g bash-language-server
# Use bash-language-server directly as entrypoint
ENTRYPOINT ["bash-language-server"]
CMD ["start"]

View File

@@ -1,14 +0,0 @@
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY . .
RUN uv venv && uv pip install --no-cache -e .
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "beszel_mcp"]

View File

@@ -1,14 +0,0 @@
FROM node:22-slim
WORKDIR /app
# Install dependencies for running npx
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Set up environment
ENV NODE_ENV=production
# The Bitwarden MCP server is run via npx
ENTRYPOINT ["npx", "-y", "@bitwarden/mcp-server"]

View File

@@ -1,18 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy source code
COPY . .
# Install the project with uv
RUN uv venv && uv pip install --no-cache -e .
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "blender_mcp.server"]

View File

@@ -1,14 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
COPY . .
EXPOSE 3000
# Use correct entry point from package.json bin
CMD ["node", "dist/server.js"]

View File

@@ -1,16 +0,0 @@
FROM node:22-alpine
# Install pnpm for monorepo
RUN npm install -g pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm --filter @upstash/context7-mcp build
CMD ["node", "packages/mcp/dist/index.js", "--transport", "stdio"]

View File

@@ -1,19 +0,0 @@
FROM node:22-alpine
# Install pnpm for monorepo
RUN npm install -g pnpm
WORKDIR /app
# Copy all source first
COPY . .
# Install all workspace dependencies (from within source tree)
RUN pnpm install
# Build MCP package specifically
RUN pnpm build:mcp
# Set entrypoint to run MCP server
ENTRYPOINT ["node", "packages/mcp/dist/index.js"]
CMD ["--transport", "stdio"]

View File

@@ -1,18 +0,0 @@
FROM node:24-alpine
WORKDIR /app
# Install pnpm as upstream requires
RUN corepack enable && corepack prepare pnpm@10.14.0 --activate
COPY package.json pnpm-lock.yaml ./
# Install dependencies with pinned SDK version
RUN pnpm add @modelcontextprotocol/sdk@^1.23.0
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
CMD ["node", "dist/index.js"]

View File

@@ -1,32 +0,0 @@
# 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"]

View File

@@ -1,24 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies
RUN uv sync --frozen --no-dev --no-install-project --no-cache
# Copy source code
COPY . .
# Install the project
RUN uv sync --frozen --no-dev --no-editable --no-cache
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["uvx", "docker-mcp"]

View File

@@ -1,16 +0,0 @@
FROM node:22-alpine
# Install pnpm
RUN npm install -g pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build
CMD ["node", "build/index.js"]

View File

@@ -1,28 +0,0 @@
# Copyright Elasticsearch B.V. and contributors
# SPDX-License-Identifier: Apache-2.0
FROM rust:1.89@sha256:c50cd6e20c46b0b36730b5eb27289744e4bb8f32abc90d8c64ca09decf4f55ba AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
# Cache dependencies
RUN mkdir -p ./src/bin && \
echo "pub fn main() {}" > ./src/bin/elasticsearch-core-mcp-server.rs && \
cargo build --release
COPY src ./src/
RUN cargo build --release
#--------------------------------------------------------------------------------------------------
FROM cgr.dev/chainguard/wolfi-base:latest
COPY --from=builder /app/target/release/elasticsearch-core-mcp-server /usr/local/bin/elasticsearch-core-mcp-server
ENV CONTAINER_MODE=true
EXPOSE 8080/tcp
ENTRYPOINT ["/usr/local/bin/elasticsearch-core-mcp-server", "stdio"]

View File

@@ -1,18 +0,0 @@
# Firefly III MCP Server
# https://github.com/etnperlong/firefly-iii-mcp
# Uses published npm package for reliability
FROM node:22-alpine
WORKDIR /app
# Install the npm package globally
RUN npm install -g @firefly-iii-mcp/local
# Environment variables (to be set at runtime)
ENV FIREFLY_III_BASE_URL=""
ENV FIREFLY_III_PAT=""
ENV FIREFLY_III_PRESET="default"
# Run the local MCP server
ENTRYPOINT ["npx", "@firefly-iii-mcp/local"]

View File

@@ -1,18 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy source code
COPY . .
# Install the project with uv
RUN uv venv && uv pip install --no-cache -e .
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "freecad_mcp.server"]

View File

@@ -1,13 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
CMD ["node", "build/server.js"]

View File

@@ -1,24 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies
RUN uv sync --frozen --no-dev --no-install-project --no-cache
# Copy source code
COPY . .
# Install the project
RUN uv sync --frozen --no-dev --no-editable --no-cache
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "gimp_mcp_server"]

View File

@@ -1,18 +0,0 @@
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o gitea-mcp .
FROM alpine:3.20
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/gitea-mcp /usr/local/bin/gitea-mcp
ENTRYPOINT ["/usr/local/bin/gitea-mcp"]

View File

@@ -1,14 +0,0 @@
FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY . .
RUN uv venv && uv pip install --no-cache -e .
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "ha_mcp"]

View File

@@ -1,24 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy dependency files
COPY pyproject.toml ./
# Install dependencies
RUN uv sync --no-dev --no-install-project --no-cache
# Copy source code
COPY . .
# Install the project
RUN uv sync --no-dev --no-editable --no-cache
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "imap_mcp.server"]

View File

@@ -1,21 +0,0 @@
FROM node:22-alpine
# Install Python 3 and required dependencies
RUN apk add --no-cache python3 py3-pip
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --ignore-scripts
COPY . .
# Install Python dependencies (use --break-system-packages since this is a container)
RUN pip3 install --no-cache-dir --break-system-packages -r requirements.txt
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]

View File

@@ -1,13 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]

View File

@@ -1,18 +0,0 @@
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o linkwarden-mcp-server ./cmd/linkwarden-mcp-server
FROM alpine:3.20
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/linkwarden-mcp-server /usr/local/bin/linkwarden-mcp-server
ENTRYPOINT ["/usr/local/bin/linkwarden-mcp-server", "stdio"]

View File

@@ -1,14 +0,0 @@
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"]

View File

@@ -1,11 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install
COPY . .
CMD ["node", "matomo-mcp-client.js"]

View File

@@ -1,19 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Copy source code
COPY . .
# Install the project with uv
RUN uv venv && uv pip install --no-cache -e .
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
# Run directly from local install, not via uvx
ENTRYPOINT ["python", "src/ansible_mcp/server.py"]

View File

@@ -1,13 +0,0 @@
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "dist/index.js"]

View File

@@ -1,18 +0,0 @@
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o mcp-grafana ./cmd/mcp-grafana
FROM alpine:3.20
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/mcp-grafana /usr/local/bin/mcp-grafana
ENTRYPOINT ["/usr/local/bin/mcp-grafana", "--transport", "stdio"]

View File

@@ -1,11 +0,0 @@
FROM python:3.13-slim
WORKDIR /app
COPY . /app
RUN pip install --upgrade pip \
&& pip install uv \
&& uv sync
CMD ["uv", "run", "--directory", "/app", "-m", "mcp_redmine.server"]

View File

@@ -1,44 +0,0 @@
FROM docker.io/library/python:3.12-slim
# Install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# Install dependencies
RUN apt update && apt install --no-install-recommends --no-install-suggests -y \
git \
tesseract-ocr \
sqlite3 && apt clean
WORKDIR /app
COPY pyproject.toml uv.lock README.md ./
RUN uv sync --no-dev --no-install-project --no-cache
# Copy source code (create permissive .dockerignore first)
# We need to override the vendor .dockerignore
RUN rm -f /app/.dockerignore 2>/dev/null || true
RUN cat > /app/.dockerignore << 'EOF'
*.pyc
__pycache__/
.venv/
.DS_Store
.git/
.gitignore
uv.lock
README.md
ARCHITECTURE.md
CONTRIBUTING.md
DEVELOPMENT.md
PROMPTS.md
TROUBLESHOOTING.md
EOF
COPY . .
RUN uv sync --no-dev --no-editable --no-cache
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["/app/.venv/bin/nextcloud-mcp-server"]
CMD ["run"]

View File

@@ -1,25 +0,0 @@
# Paperless-NGX MCP Server
# https://github.com/nloui/paperless-mcp
FROM node:20-slim AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-slim AS production
WORKDIR /app
COPY --from=builder /app/build ./build
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
ENV PAPERLESS_URL=""
ENV PAPERLESS_TOKEN=""
ENTRYPOINT ["node", "build/index.js"]

View File

@@ -1,39 +0,0 @@
# Penpot MCP Server - Multi-stage build for monorepo
FROM node:20-slim AS builder
WORKDIR /app
# Copy the entire monorepo
COPY package*.json ./
COPY common ./common
COPY mcp-server ./mcp-server
COPY penpot-plugin ./penpot-plugin
# Install dependencies for the monorepo
RUN npm ci
# Build common package first (dependency)
WORKDIR /app/common
RUN npm ci && npm run build
# Build mcp-server
WORKDIR /app/mcp-server
RUN npm ci && npm run build
# Production image
FROM node:20-slim
WORKDIR /app
# Copy built mcp-server and its dependencies
COPY --from=builder /app/mcp-server/dist ./dist
COPY --from=builder /app/mcp-server/data ./data
COPY --from=builder /app/mcp-server/node_modules ./node_modules
COPY --from=builder /app/common/dist ./node_modules/@penpot-mcp/common/dist
COPY --from=builder /app/common/package.json ./node_modules/@penpot-mcp/common/
# Set environment defaults
ENV PENPOT_URL=${PENPOT_URL:-https://design.penpot.app}
# Run the MCP server
CMD ["node", "dist/index.js"]

View File

@@ -1 +0,0 @@
../../vendor/postizz-MCP/Dockerfile

View File

@@ -1,25 +0,0 @@
FROM python:3.12-slim
# Install uv for faster package management and git for any git dependencies
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy all source code first
COPY . .
# Replace mcp git dependency with fastmcp from PyPI
RUN sed -i 's|"mcp @ git+https://github.com/modelcontextprotocol/python-sdk.git"|"fastmcp"|' pyproject.toml
# Patch imports to use fastmcp instead of mcp.server.fastmcp
RUN find . -name "*.py" -exec sed -i 's/from mcp\.server\.fastmcp/from fastmcp/g' {} \;
# Install dependencies and project
RUN uv sync --no-dev --no-editable --no-cache
# Set up environment
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "-m", "proxmox_mcp.server"]

View File

@@ -1,47 +0,0 @@
# ReVa (Reverse Engineering Assistant) MCP Server
# Ghidra extension providing MCP server for AI-assisted reverse engineering
# https://github.com/cyberkaida/reverse-engineering-assistant
FROM eclipse-temurin:21-jdk-jammy AS builder
ARG GHIDRA_VERSION=12.0.3
ARG GHIDRA_DATE=20260210
ENV DEBIAN_FRONTEND=noninteractive
ENV GHIDRA_INSTALL_DIR=/opt/ghidra
RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
unzip \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY . /build/reva
RUN wget -q "https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_${GHIDRA_VERSION}_build/ghidra_${GHIDRA_VERSION}_PUBLIC_${GHIDRA_DATE}.zip" \
-O /tmp/ghidra.zip \
&& unzip -q /tmp/ghidra.zip -d /opt \
&& mv /opt/ghidra_${GHIDRA_VERSION}_PUBLIC /opt/ghidra \
&& rm /tmp/ghidra.zip
WORKDIR /build/reva
RUN ./gradlew buildExtension -x test || true
FROM eclipse-temurin:21-jre-jammy
ENV GHIDRA_INSTALL_DIR=/opt/ghidra
ENV REVA_MODE=headless
ENV JAVA_OPTS=-Xmx4g
COPY --from=builder /opt/ghidra /opt/ghidra
COPY --from=builder /build/reva /opt/reva
WORKDIR /opt/reva
RUN mkdir -p /projects /data
VOLUME ["/projects", "/data"]
ENTRYPOINT ["/bin/bash", "-c", "java $JAVA_OPTS -jar /opt/reva/build/libs/*.jar"]

View File

@@ -1,14 +0,0 @@
# snipeit-mcp is BLOCKED - requires private snipeit-api package
# The upstream author created a private package that was never published
# See: https://github.com/ directa-innovations/snipeit-mcp
FROM alpine:3.20
RUN echo '#!/bin/sh' > /entrypoint.sh && \
echo 'echo "ERROR: snipeit-mcp is blocked due to missing private dependency (snipeit-api)"' >> /entrypoint.sh && \
echo 'echo "The upstream author created a private snipeit-api package that was never published to PyPI."' >> /entrypoint.sh && \
echo 'echo "Public snipeit package (v1.1, archived 2022) has incompatible API."' >> /entrypoint.sh && \
echo 'echo "Contact upstream author or rewrite using public snipeit package API."' >> /entrypoint.sh && \
echo 'exit 1' >> /entrypoint.sh && \
chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -1,14 +0,0 @@
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY . .
RUN uv venv && uv pip install --no-cache -e .
ENV PYTHONUNBUFFERED=1
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT ["python", "main.py"]

View File

@@ -1,27 +0,0 @@
# Terraform Language Server (terraform-ls)
# Official HashiCorp LSP for Terraform
# https://github.com/hashicorp/terraform-ls
FROM alpine:3.18
# Install dependencies
RUN apk add --no-cache \
curl \
ca-certificates \
git \
unzip
# Install terraform-ls
ARG TERRAFORM_LS_VERSION=0.38.4
RUN curl -fsSL https://releases.hashicorp.com/terraform-ls/${TERRAFORM_LS_VERSION}/terraform-ls_${TERRAFORM_LS_VERSION}_linux_amd64.zip \
-o terraform-ls.zip && \
unzip terraform-ls.zip && \
mv terraform-ls /usr/local/bin/ && \
chmod +x /usr/local/bin/terraform-ls && \
rm terraform-ls.zip
# Set up working directory
WORKDIR /workspace
# Run terraform-ls in stdio mode
ENTRYPOINT ["terraform-ls", "serve"]

View File

@@ -1,26 +0,0 @@
# ESP32 WebSerial MCP Bridge
# This MCP requires the bridge server to be running and a browser+ESP32 connected
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && \
pip install --no-cache-dir nest-asyncio
# Copy application files
COPY mcp_handler.py .
COPY mcp_client.py .
COPY esp32_bridge_server.py .
COPY templates/ templates/
# Environment variables
ENV PYTHONUNBUFFERED=1
ENV WEBSOCKET_URL=ws://localhost:3000
ENV MCP_TIMEOUT=30
# Default entrypoint is the MCP client (stdio-based)
ENTRYPOINT ["python", "mcp_client.py"]
CMD ["ws://host.docker.internal:3000"]

View File

@@ -1,2 +0,0 @@
FROM node:22-slim
ENTRYPOINT ["npx", "-y", "@wordpress/mcp-adapter"]

View File

@@ -1,411 +0,0 @@
# KNEL-AIMiddleware - Software Development Lifecycle
**Version:** 1.0
**Status:** Active
**Last Updated:** 2026-02-20
---
## Overview
This document defines the development workflow for KNEL-AIMiddleware. Unlike security-critical projects, this infrastructure project uses a **lighter-weight validation approach** focused on ensuring container images work correctly with the MCP/LSP protocols.
---
## Core Principles
### 1. Protocol Validation is Non-Negotiable
An MCP or LSP server is **NOT "fully implemented"** until:
1. The Docker container **builds successfully**
2. The Docker container **starts without crash**
3. A **protocol handshake message receives a valid response**
```
┌─────────────────────────────────────────────────────────────────────┐
│ MANDATORY VALIDATION WORKFLOW │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. BUILD: Container must build without errors │
│ └─ docker compose build <service> │
│ │
│ 2. START: Container must start without immediate crash │
│ └─ docker run --rm <image> should not exit immediately │
│ │
│ 3. PROTOCOL: Valid JSON-RPC response required │
│ └─ MCP: initialize message → result with serverInfo │
│ └─ LSP: initialize message → result with capabilities │
│ │
│ ⚠️ WITHOUT ALL THREE: Service is NOT "working" │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
### 2. Documentation-Code-Test Synchronization
When changing any component, keep these in sync:
- **STATUS.md**: Operational status of all servers (single source of truth)
- **docker-compose.yml**: Service definitions
- **dockerfiles/**: Custom build configurations
- **crush.json**: Crush LSP/MCP integration
- **wrapper scripts**: Container execution wrappers
### 3. Sequential Validation
When adding or fixing MCP/LSP servers:
1. Work on ONE server at a time
2. Validate completely before moving to next
3. Update STATUS.md immediately after validation
4. Commit changes for each server
---
## Validation Commands
### MCP Server Validation
```bash
# Send MCP initialize handshake
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{},"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | \
timeout 10 docker run --rm -i kneldevstack-aimiddleware-<service>
# Expected: JSON response with "result" containing "serverInfo"
# Example success: {"jsonrpc":"2.0","result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"Example MCP","version":"1.0.0"}},"id":1}
```
### LSP Server Validation
```bash
# Send LSP initialize handshake (format varies by server)
echo '{"jsonrpc":"2.0","method":"initialize","params":{"processId":null,"capabilities":{}},"id":1}' | \
timeout 10 docker run --rm -i kneldevstack-aimiddleware-<service> <args>
# Expected: JSON response with "result" containing "capabilities"
```
### Validation Script
Use the provided validation script for batch testing:
```bash
./scripts/validate-mcp.sh
```
---
## STATUS.md Requirements
**STATUS.md is the single source of truth for server status.**
### Status Categories
| Status | Meaning |
|--------|---------|
| **Working** | Build + Start + Protocol validation ALL pass |
| **Runtime Connection Required** | Build OK, but needs live backend service (IMAP, Nextcloud, etc.) |
| **Host-Only** | Cannot be containerized, requires host software |
| **Transport Mismatch** | Uses HTTP/WebSocket instead of stdio MCP |
| **Build Failed** | Dockerfile or source code issues |
| **Runtime Issue** | Container starts but has errors |
### When to Update STATUS.md
1. **Immediately** after building a new server
2. **Immediately** after validating protocol handshake
3. **Immediately** after discovering issues
4. **Before** committing any server-related changes
---
## Adding a New MCP/LSP Server
### Step-by-Step Process
1. **Clone vendor repository**
```bash
# Add to scripts/CloneVendorRepos.sh
git clone https://github.com/org/repo.git vendor/service-name
```
2. **Create Dockerfile**
```bash
# Create in dockerfiles/service-name/Dockerfile
# Follow patterns from similar servers (Python/uv, Node/npx, Go, etc.)
```
3. **Add to docker-compose.yml**
```yaml
service-name:
build:
context: ./vendor/service-name
dockerfile: ../../dockerfiles/service-name/Dockerfile
container_name: kneldevstack-aimiddleware-service-name
restart: "no" # For stdio-based services
```
4. **Build the container**
```bash
docker compose build service-name
```
5. **Validate protocol handshake**
```bash
# For MCP servers
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{},"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | \
timeout 10 docker run --rm -i kneldevstack-aimiddleware-service-name
```
6. **Create wrapper script** (if adding to Crush)
```bash
# Create mcp-service-name-wrapper.sh
# Follow existing wrapper patterns
```
7. **Add to crush.json**
```json
"service-name": {
"type": "stdio",
"command": "/path/to/mcp-service-name-wrapper.sh",
"timeout": 60
}
```
8. **Update STATUS.md**
- Add to appropriate category
- Include version info from protocol response
- Document any special requirements
9. **Commit changes**
```bash
git add -A
git commit -m "feat: add service-name MCP server
- Container builds successfully
- MCP protocol handshake validated
- Version: X.Y.Z"
```
---
## Common Patterns
### Python MCP Servers (uv package manager)
```dockerfile
FROM python:3.12-slim
WORKDIR /app
RUN pip install uv
COPY . .
RUN uv sync --frozen
ENTRYPOINT ["python", "-m", "module_name"]
```
### Node.js MCP Servers (npx)
```dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
ENTRYPOINT ["node", "dist/index.js"]
```
### Go MCP Servers
```dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o server ./cmd/server
FROM alpine:3.19
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]
```
---
## Commit Policy (MANDATORY)
### Automatic Commits
**AI agents MUST commit changes automatically without prompting the user.**
This is non-negotiable. Do not ask "should I commit?" - just commit.
### Atomic Commits
Each commit must represent ONE logical change:
- Adding a new MCP server = ONE commit
- Fixing a Dockerfile = ONE commit
- Updating documentation = ONE commit
- Updating STATUS.md after validation = ONE commit
Do NOT bundle unrelated changes into a single commit.
### Conventional Commit Format
All commits MUST use conventional commit format:
```
<type>(<scope>): <short summary>
<body explaining what and why>
<footer with references>
```
**Types:**
- `feat`: New feature (new MCP server, new wrapper script)
- `fix`: Bug fix (Dockerfile fix, runtime issue)
- `docs`: Documentation only (STATUS.md, AGENTS.md, SDLC.md)
- `build`: Build system changes (docker-compose.yml)
- `refactor`: Code restructuring without behavior change
- `test`: Adding/updating validation scripts
**Example:**
```
feat(docker-mcp): add Docker MCP server with protocol validation
- Container builds successfully with Python 3.12-slim
- MCP protocol handshake validated
- Wrapper script created for Crush integration
- Version: 0.1.0
Validated-by: Protocol handshake test
```
### Verbose Commit Messages
Commit messages must explain:
1. **What** changed (in the summary)
2. **Why** it changed (in the body)
3. **How** it was validated (in the footer)
Single-line commits are NOT acceptable for any non-trivial change.
### Automatic Push
After successful commits, push to remote automatically:
```bash
git push origin main
```
Do NOT ask for permission. Push.
### Commit Workflow
```
1. Make logical change
2. Validate the change (build, start, protocol test)
3. Update STATUS.md if applicable
4. Stage ONLY files related to that change
5. Commit with verbose conventional message
6. Push immediately
7. Continue to next task
```
### What NOT to Commit
- Never commit secrets (API keys, passwords, tokens)
- Never commit the `vendor/` directory (gitignored)
- Never commit temporary files or logs
---
## Pre-Commit Checklist
Before committing changes to any MCP/LSP server:
- [ ] Container builds: `docker compose build <service>`
- [ ] Container starts: `docker run --rm <image>` doesn't crash immediately
- [ ] Protocol validated: Handshake returns valid JSON-RPC response
- [ ] STATUS.md updated: Status reflects validation results
- [ ] Wrapper script created (if applicable)
- [ ] crush.json updated (if applicable)
- [ ] **COMMIT DONE**: Changes committed with conventional format
- [ ] **PUSH DONE**: Changes pushed to remote
---
## Wrapper Script Pattern
All wrapper scripts follow this pattern:
```bash
#!/bin/bash
CONTAINER_NAME="kneldevstack-aimiddleware-service-name-crush"
# Force remove existing container
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true
sleep 0.5
# Run container with explicit name
docker run -i --rm \
--name "${CONTAINER_NAME}" \
-e ENV_VAR_1="${ENV_VAR_1:-}" \
-e ENV_VAR_2="${ENV_VAR_2:-}" \
kneldevstack-aimiddleware-service-name
```
This pattern:
- Prevents container name conflicts
- Handles cleanup gracefully
- Passes environment variables from host
---
## Validation Failure Categories
### 1. Build Failures
- Dockerfile syntax errors
- Missing dependencies
- Build tool errors (TypeScript, Go, Rust)
**Action**: Fix Dockerfile, rebuild
### 2. Runtime Crashes (Before Protocol)
- Missing environment variables
- External service unreachable
- Missing Python modules (e.g., pcbnew for KiCAD)
**Action**: Document in STATUS.md as "Runtime Connection Required" or "Host-Only"
### 3. Transport Mismatches
- Server uses HTTP instead of stdio
- Server uses WebSocket instead of stdio
**Action**: Document in STATUS.md as "Transport Mismatch"
### 4. Protocol Errors
- Invalid JSON-RPC response
- Wrong protocol version
- Missing serverInfo/capabilities
**Action**: Debug server implementation or report upstream issue
---
## References
- **STATUS.md** - Operational status (single source of truth)
- **AGENTS.md** - Development workflow and server catalog
- **JOURNAL.md** - Architecture decisions and work history
- **scripts/validate-mcp.sh** - Batch validation script
---
## Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-02-20 | Initial SDLC document |
---
**This SDLC ensures MCP/LSP servers are actually functional, not just "built".**
**Copyright (c) 2026 Known Element Enterprises LLC**

View File

@@ -1,178 +0,0 @@
# Dockerfile Security Audit
**Date:** 2026-02-20
**Auditor:** External Security Review
**Scope:** All Dockerfiles in `dockerfiles/` directory
## Executive Summary
| Metric | Value |
|--------|-------|
| Total Dockerfiles Analyzed | 40 |
| High Severity Issues | 38 |
| Medium Severity Issues | 33 |
| Low Severity Issues | 2 |
## Detailed Findings
### 1. Running as Root User (HIGH)
**Severity:** HIGH
**Affected:** 38 of 40 Dockerfiles (95%)
**CWE:** CWE-250 (Execution with Unnecessary Privileges)
#### Description
The vast majority of Dockerfiles do not include a `USER` directive, meaning containers run as root by default. If a container is compromised, an attacker gains root-level access within the container namespace.
#### Affected Files
All except:
- `dockerfiles/reverse-engineering-assistant/Dockerfile` (creates non-root user)
- `dockerfiles/postizz-mcp/Dockerfile` (includes USER directive)
#### Recommendation
Add non-root user creation and USER directive to all Dockerfiles:
```dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
```
#### Risk Assessment
- **Likelihood:** Medium - depends on container escape or service vulnerability
- **Impact:** High - root access enables privilege escalation
- **Overall:** HIGH
---
### 2. Missing Multi-Stage Builds (MEDIUM)
**Severity:** MEDIUM
**Affected:** 32 of 40 Dockerfiles (80%)
**CWE:** CWE-1026 (Excessive Use of Unmodified Software Components)
#### Description
Most Dockerfiles use single-stage builds, including build tools and dependencies in the final image. This increases:
- Attack surface (more packages = more potential vulnerabilities)
- Image size
- Build time
#### Files Using Multi-Stage Builds (Good)
- `dockerfiles/kicad-mcp/Dockerfile`
- `dockerfiles/reverse-engineering-assistant/Dockerfile`
- `dockerfiles/mongo-mcp/Dockerfile`
- `dockerfiles/inspec-mcp/Dockerfile`
- `dockerfiles/postgres-mcp/Dockerfile`
- `dockerfiles/ssh-mcp/Dockerfile`
- `dockerfiles/steam-mcp/Dockerfile`
- `dockerfiles/bruno-mcp/Dockerfile`
#### Recommendation
Convert to multi-stage builds:
```dockerfile
# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Runtime stage
FROM alpine:3.20
COPY --from=builder /app/myapp /usr/local/bin/
```
---
### 3. Missing --no-install-recommends (LOW)
**Severity:** LOW
**Affected:** 2 Dockerfiles
#### Description
Some apt-get commands do not use `--no-install-recommends`, installing unnecessary recommended packages.
#### Affected Files
- `dockerfiles/reverse-engineering-assistant/Dockerfile:11`
- `dockerfiles/inspec-mcp/Dockerfile:8`
#### Recommendation
Add `--no-install-recommends` flag and clean up apt cache:
```dockerfile
RUN apt-get update && apt-get install -y --no-install-recommends \
package-name \
&& rm -rf /var/lib/apt/lists/*
```
---
### 4. Build-Time Secrets in postizz-mcp (MEDIUM)
**Severity:** MEDIUM
**Affected:** `dockerfiles/postizz-mcp/Dockerfile`
**CWE:** CWE-525 (Use of Web Browser Cache)
#### Description
The postizz-mcp Dockerfile uses build arguments for API keys:
```dockerfile
# Line 36
ARG POSTIZ_WEB_URL=${POSTIZ_WEB_URL}
# Line 42
ENV PORT=${PORT}
```
Build arguments can leak secrets into image layers. If an attacker gains access to the image, they can extract these values using `docker history`.
#### Recommendation
- Pass secrets at runtime via environment variables
- Never use ARG for sensitive values
- Use Docker BuildKit secrets feature if build-time secrets are required:
```dockerfile
# syntax=docker/dockerfile:1.2
RUN --mount=type=secret,id=postiz_token \
export POSTIZ_TOKEN=$(cat /run/secrets/postiz_token) && \
./configure --token=$POSTIZ_TOKEN
```
---
## Base Image Analysis
### Images Used
| Base Image | Count | Security Status |
|------------|-------|-----------------|
| alpine:3.20 | 1 | Clean (0 HIGH/CRITICAL) |
| python:3.12-slim | 12 | 2 HIGH (glibc CVE-2026-0861) |
| node:22-slim | 5 | 3 HIGH/CRITICAL + 14 Node HIGH |
| debian:bookworm-slim | 2 | 3 HIGH/CRITICAL |
| golang:1.23-alpine | 4 | 6 HIGH/CRITICAL (OpenSSL) |
### Recommendations
1. Pin base images to specific digests for reproducibility
2. Consider Alpine-based images where possible (smaller attack surface)
3. Implement automated base image scanning in CI/CD pipeline
---
## Positive Findings
1. **No hardcoded credentials** in any Dockerfile
2. **Good use of COPY over ADD** (no automatic extraction issues)
3. **Proper WORKDIR usage** (avoids root directory operations)
4. **Some multi-stage builds** implemented correctly
5. **Reasonable base image selection** (official images)
---
## Remediation Priority
| Priority | Finding | Effort | Impact |
|----------|---------|--------|--------|
| 1 | Add USER directive to all Dockerfiles | Low | High |
| 2 | Implement multi-stage builds | Medium | Medium |
| 3 | Remove build-time secrets | Low | Medium |
| 4 | Add --no-install-recommends | Low | Low |

View File

@@ -1,230 +0,0 @@
# Shell Script Security Audit
**Date:** 2026-02-20
**Auditor:** External Security Review
**Scope:** All shell scripts in project root and `scripts/` directory
## Executive Summary
| Metric | Value |
|--------|-------|
| Total Scripts Analyzed | 45+ |
| Scripts Missing `set -e` | 38 |
| Scripts Missing `set -u` | 45 (all) |
| Scripts with Unquoted Variables | 4 |
## Detailed Findings
### 1. Missing Error Handling (HIGH)
**Severity:** HIGH
**Affected:** 38 of 45 scripts (84%)
**CWE:** CWE-252 (Unchecked Return Value)
#### Description
Most shell scripts lack `set -e` which causes scripts to continue executing even when commands fail. This can lead to:
- Silent failures going undetected
- Partial/incomplete operations
- Security bypasses if validation commands fail
#### Pattern Found
```bash
#!/bin/bash
# Script continues even if commands fail
docker build ... # If this fails, script continues
echo "Build complete" # Misleading success message
```
#### Correct Pattern
```bash
#!/bin/bash
set -euo pipefail
# Script exits immediately on any error
```
#### Affected Script Categories
- **Wrapper scripts** (mcp-*-wrapper.sh): 34 scripts
- **LSP wrapper scripts** (lsp-*-wrapper.sh): Multiple
- **Build scripts** (scripts/BuildAll.sh): 1 script
#### Recommendation
Add to all scripts:
```bash
#!/bin/bash
set -euo pipefail
```
---
### 2. Missing Undefined Variable Protection (HIGH)
**Severity:** HIGH
**Affected:** 45 of 45 scripts (100%)
**CWE:** CWE-456 (Missing Initialization of a Variable)
#### Description
No scripts use `set -u` which prevents the use of undefined variables. This can cause:
- Commands to execute with empty values
- Unexpected behavior with missing environment variables
- Potential security issues if variables like paths are empty
#### Example Risk
```bash
#!/bin/bash
# If API_KEY is not set, this becomes: curl -H "Authorization: Bearer "
curl -H "Authorization: Bearer $API_KEY" https://api.example.com
```
#### Recommendation
```bash
#!/bin/bash
set -u # Exit on undefined variable
# Or provide defaults:
API_KEY="${API_KEY:-}" # Empty default
API_KEY="${API_KEY:-default_value}" # Non-empty default
```
---
### 3. Unquoted Variables (MEDIUM)
**Severity:** MEDIUM
**Affected:** 4 scripts
**CWE:** CWE-77 (Command Injection)
#### Description
Some scripts use unquoted variables which can lead to:
- Word splitting on spaces
- Glob expansion
- Potential command injection
#### Affected Files
Found in various wrapper scripts where environment variables are passed through.
#### Pattern to Avoid
```bash
# Dangerous - unquoted
docker run $CONTAINER_NAME
# Safe - quoted
docker run "$CONTAINER_NAME"
```
#### Recommendation
Always quote variable expansions:
```bash
docker run "${CONTAINER_NAME}"
```
---
### 4. No Input Validation (MEDIUM)
**Severity:** MEDIUM
**Affected:** All wrapper scripts
**CWE:** CWE-20 (Improper Input Validation)
#### Description
Wrapper scripts pass environment variables directly to Docker commands without validation.
#### Example
```bash
#!/bin/bash
docker run --rm -i \
-e PROXMOX_HOST="${PROXMOX_HOST}" \
-e PROXMOX_USER="${PROXMOX_USER}" \
kneldevstack-aimiddleware-proxmox-mcp
```
No validation that:
- Variables are set
- Values are in expected format
- Values don't contain injection characters
#### Recommendation
Add validation for critical variables:
```bash
#!/bin/bash
set -euo pipefail
: "${REQUIRED_VAR:?REQUIRED_VAR must be set}"
# Optional validation
if [[ ! "$URL" =~ ^https?:// ]]; then
echo "Invalid URL format" >&2
exit 1
fi
```
---
## Script Categories
### MCP Wrapper Scripts (34 files)
- Pattern: `mcp-*-wrapper.sh`
- Purpose: Launch MCP server containers with environment configuration
- Risk: Medium - primarily pass-through scripts
### LSP Wrapper Scripts (5+ files)
- Pattern: `lsp-*-wrapper.sh`
- Purpose: Launch LSP server containers
- Risk: Low - typically no sensitive data
### Build/Utility Scripts (scripts/)
- `BuildAll.sh` - Build automation
- `validate-all.sh` - Validation testing
- Risk: Low - development utilities
---
## Positive Findings
1. **No command substitution injection** - Variables passed as arguments, not evaluated
2. **Consistent naming convention** - Easy to identify script purpose
3. **Simple pass-through design** - Limited attack surface
4. **No hardcoded secrets** - All credentials from environment
---
## Remediation Priority
| Priority | Finding | Effort | Impact |
|----------|---------|--------|--------|
| 1 | Add `set -euo pipefail` to all scripts | Low | High |
| 2 | Quote all variable expansions | Low | Medium |
| 3 | Add input validation for critical vars | Medium | Medium |
---
## Example Secure Script Template
```bash
#!/bin/bash
# MCP Server Wrapper for: service-name
# Generated secure template
set -euo pipefail
# Required variables with validation
: "${API_URL:?API_URL must be set}"
: "${API_KEY:?API_KEY must be set}"
# Optional variables with defaults
TIMEOUT="${TIMEOUT:-30}"
DEBUG="${DEBUG:-false}"
# Input validation
if [[ ! "$API_URL" =~ ^https?:// ]]; then
echo "ERROR: API_URL must be a valid HTTP/HTTPS URL" >&2
exit 1
fi
# Execute
exec docker run --rm -i \
-e API_URL="${API_URL}" \
-e API_KEY="${API_KEY}" \
-e TIMEOUT="${TIMEOUT}" \
-e DEBUG="${DEBUG}" \
kneldevstack-aimiddleware-service-name
```

View File

@@ -1,246 +0,0 @@
# Docker Compose Security Audit
**Date:** 2026-02-20
**Auditor:** External Security Review
**Scope:** `docker-compose.yml` and container orchestration
## Executive Summary
| Metric | Value |
|--------|-------|
| Total Services | 40+ |
| High Severity Issues | 3 |
| Medium Severity Issues | 1 |
| Low Severity Issues | 1 |
## Detailed Findings
### 1. Docker Socket Mount (HIGH)
**Severity:** HIGH
**Affected Services:** `docker-mcp`, `mcp-ansible`
**CWE:** CWE-250 (Execution with Unnecessary Privileges)
#### Description
Two services mount the Docker socket, granting full Docker daemon access:
```yaml
# docker-mcp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# mcp-ansible
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
This provides equivalent access to root on the host system.
#### Impact
- Full control over all containers on host
- Ability to mount host filesystem
- Potential for container escape
- Access to secrets in other containers
#### Risk Assessment
- **Necessary for Function:** Yes - these services manage Docker/containers
- **Mitigation Required:** Yes
#### Recommendation
1. Run these services with explicit user constraints where possible
2. Document the privilege requirement clearly
3. Consider socket proxy (docker-socket-proxy) for least privilege
4. Isolate on dedicated management nodes in production
```yaml
# Alternative with socket proxy
services:
docker-mcp:
environment:
- DOCKER_HOST=tcp://docker-proxy:2375
depends_on:
- docker-proxy
docker-proxy:
image: tecnativa/docker-socket-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- CONTAINERS=1
- IMAGES=1
# Only allow specific operations
```
---
### 2. Kubernetes Config Mount (HIGH)
**Severity:** HIGH
**Affected Service:** `kubernetes-mcp`
**CWE:** CWE-250 (Execution with Unnecessary Privileges)
#### Description
The kubernetes-mcp service mounts kubeconfig:
```yaml
volumes:
- ~/.kube/config:/home/appuser/.kube/config:ro
```
This grants Kubernetes cluster admin access to the container.
#### Impact
- Full control over Kubernetes cluster
- Access to all secrets in cluster
- Ability to deploy privileged workloads
- Cluster admin equivalent access
#### Risk Assessment
- **Necessary for Function:** Yes - required for Kubernetes management
- **Mitigation Required:** Yes
#### Recommendation
1. Use read-only mount (`:ro` flag) - already implemented
2. Consider ServiceAccount tokens instead of kubeconfig
3. Implement RBAC with minimal required permissions
4. Document required permissions clearly
---
### 3. Privileged Access Pattern (MEDIUM)
**Severity:** MEDIUM
**Affected:** Multiple services requiring system access
**CWE:** CWE-269 (Improper Privilege Management)
#### Description
Several services require elevated privileges for their function:
| Service | Privilege Type | Justification |
|---------|---------------|---------------|
| docker-mcp | Docker socket | Container management |
| mcp-ansible | Docker socket | Container orchestration |
| kubernetes-mcp | kubeconfig | Cluster management |
| ssh-mcp | SSH keys | Remote server access |
#### Recommendation
Document each privileged service with:
- Required access level
- Business justification
- Mitigating controls
- Audit logging requirements
---
### 4. Default Credential Pattern (LOW)
**Severity:** LOW
**Affected Service:** `ghost-mcp`
**CWE:** CWE-1188 (Initialization with Hard-Coded Network Resource Configuration)
#### Description
Ghost MCP service shows a placeholder credential pattern:
```yaml
# Line 224
environment:
- GHOST_API_KEY=${GHOST_API_KEY:-your-api-key-here}
```
While this is a placeholder (not a real credential), it establishes a pattern that could lead to:
- Developers committing real credentials
- Default credentials being used in development
#### Recommendation
- Remove default values entirely
- Fail fast if required variables not set
- Use `${VAR:?VAR must be set}` pattern
```yaml
environment:
- GHOST_API_KEY=${GHOST_API_KEY:?GHOST_API_KEY must be set}
```
---
## Network Security Analysis
### Network Configuration
All services use default Docker networking (bridge). No custom networks defined.
#### Recommendations
1. Create isolated networks for service groups:
```yaml
networks:
mcp-servers:
driver: bridge
lsp-servers:
driver: bridge
```
2. Limit inter-service communication where not required
---
## Resource Limits
### Current State
No resource limits defined for any service.
#### Risk
- Resource exhaustion (memory/CPU)
- Noisy neighbor problems
- Potential denial of service
#### Recommendation
Add resource constraints:
```yaml
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
memory: 256M
```
---
## Health Checks
### Current State
No health checks defined.
#### Recommendation
Add health checks for monitoring:
```yaml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
---
## Positive Findings
1. **No host network mode** - Services use bridge networking
2. **No privileged mode** - No containers run with `privileged: true`
3. **Environment variables externalized** - Using `.env` file pattern
4. **Read-only mounts where appropriate** - kubeconfig mounted read-only
5. **Consistent container naming** - `kneldevstack-aimiddleware-` prefix
---
## Remediation Priority
| Priority | Finding | Effort | Impact |
|----------|---------|--------|--------|
| 1 | Document privileged services | Low | High |
| 2 | Add resource limits | Low | Medium |
| 3 | Implement socket proxy for Docker access | Medium | High |
| 4 | Remove default credential patterns | Low | Low |
| 5 | Add health checks | Medium | Medium |
| 6 | Create network segmentation | Medium | Medium |

View File

@@ -1,239 +0,0 @@
# Secrets & Credentials Audit
**Date:** 2026-02-20
**Auditor:** External Security Review
**Scope:** All project files for credential exposure
## Executive Summary
| Metric | Value |
|--------|-------|
| Hardcoded Secrets Found | 0 |
| Credential Files Exposed | 0 |
| Secret Patterns in Code | 0 |
| Gitignored Secret Files | Yes (.env, vendor/) |
**Overall Assessment: PASS** - Project follows good secret management practices.
---
## Detailed Analysis
### 1. Gitignore Configuration
**Status:** COMPLIANT
The `.gitignore` file properly excludes sensitive files:
```
# Environment variables
.env
# Vendor/cloned repositories
vendor/
# IDE files
.idea/
*.swp
```
#### Verification
- `.env` is gitignored - actual credentials not committed
- `vendor/` is gitignored - cloned repos with potential secrets not tracked
- No sensitive files found in git history (based on file analysis)
---
### 2. Environment Variable Template
**File:** `.env.example`
**Status:** COMPLIANT
The `.env.example` file uses placeholder values only:
```bash
# Example placeholders (not real credentials)
PROXMOX_HOST=https://your-proxmox-host:8006
PROXMOX_USER=root@pam
PROXMOX_TOKEN_NAME=your-token-name
PROXMOX_TOKEN_SECRET=your-token-secret
```
No actual credentials present.
---
### 3. Credential Flow Analysis
#### Pattern Identified
```
.env file (gitignored)
Environment Variables
Wrapper Scripts (mcp-*-wrapper.sh)
Docker Containers
```
#### Wrapper Script Pattern
```bash
#!/bin/bash
docker run --rm -i \
-e PROXMOX_HOST="${PROXMOX_HOST}" \
-e PROXMOX_USER="${PROXMOX_USER}" \
-e PROXMOX_TOKEN_SECRET="${PROXMOX_TOKEN_SECRET}" \
kneldevstack-aimiddleware-proxmox-mcp
```
**Assessment:** Secure - credentials passed at runtime, not hardcoded.
---
### 4. Dockerfile Secret Analysis
#### ENV Directives Review
All ENV directives in Dockerfiles were analyzed:
| Dockerfile | ENV Variables | Assessment |
|------------|---------------|------------|
| proxmox-mcp | PYTHONUNBUFFERED=1 | Safe - not a secret |
| bitwarden-mcp | NODE_ENV=production | Safe - not a secret |
| paperless-mcp | PAPERLESS_URL="" | Safe - URL only |
| penpot-mcp | PENPOT_URL=${PENPOT_URL:-default} | Safe - URL only |
| postizz-mcp | PORT=${PORT} | Safe - port number |
**No secrets found in ENV directives.**
---
### 5. Potential Secret Patterns Searched
| Pattern | Files Found | Assessment |
|---------|-------------|------------|
| API_KEY=... | 0 | None in codebase |
| PASSWORD=... | 0 | None in codebase |
| SECRET=... | 0 | None in codebase |
| TOKEN=... | 0 | None in codebase |
| AWS_ACCESS_KEY | 0 | None in codebase |
| PRIVATE_KEY | 0 | None in codebase |
| -----BEGIN.*KEY----- | 0 | None in codebase |
| Bearer [A-Za-z0-9]{20,} | 0 | None in codebase |
---
### 6. Test Script Credentials
**File:** `scripts/validate-all.sh`
Contains test credentials for validation:
```bash
# Test credentials for validation purposes only
TEST_USER="testuser"
TEST_PASS="testpass123"
```
**Assessment:** ACCEPTABLE - clearly test credentials for validation, not production.
---
### 7. Build-Time Secret Exposure
**File:** `dockerfiles/postizz-mcp/Dockerfile`
#### Issue Identified
Build arguments potentially expose configuration:
```dockerfile
ARG POSTIZ_WEB_URL=${POSTIZ_WEB_URL}
ENV PORT=${PORT}
```
#### Risk Assessment
- **URL exposure:** Low risk (not a secret)
- **PORT exposure:** Minimal risk (non-sensitive)
- **No API keys in build args:** Confirmed
**Note:** While not currently a security issue, this pattern could lead to secrets being embedded if future changes add API keys as build arguments.
---
## Credential Categories
### Services Requiring Credentials
| Service | Credential Type | Storage |
|---------|-----------------|---------|
| proxmox-mcp | API Token | .env file |
| docker-mcp | Docker Socket | Mount |
| kubernetes-mcp | kubeconfig | File mount |
| ssh-mcp | SSH Private Key | File mount |
| bitwarden-mcp | Access Token | .env file |
| ghost-mcp | API Key | .env file |
| elasticsearch-mcp | Basic Auth | .env file |
| nextcloud-mcp | App Password | .env file |
### Services Without Credentials
Most MCP servers operate without requiring credentials or accept configuration at runtime.
---
## Recommendations
### 1. Add Secret Scanning to CI/CD (MEDIUM PRIORITY)
Implement automated secret detection:
```yaml
# GitHub Actions example
- name: Secret Scan
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
```
### 2. Document Required Secrets (LOW PRIORITY)
Create documentation listing required credentials per service:
```markdown
## proxmox-mcp
- PROXMOX_HOST (required)
- PROXMOX_USER (required)
- PROXMOX_TOKEN_NAME (required)
- PROXMOX_TOKEN_SECRET (required, secret)
```
### 3. Consider Secrets Management (FUTURE)
For production deployment, consider:
- HashiCorp Vault
- AWS Secrets Manager
- Docker Secrets
- Kubernetes Secrets
---
## Positive Findings Summary
1. **No hardcoded secrets** in any tracked file
2. **Proper .gitignore** excludes .env and vendor/
3. **Placeholder-only .env.example** - no real credentials
4. **Runtime credential injection** - not in images
5. **No secrets in git history** based on file analysis
6. **Consistent secure patterns** across wrapper scripts
---
## Compliance Check
| Requirement | Status | Notes |
|-------------|--------|-------|
| No hardcoded secrets | PASS | Full codebase scanned |
| Secrets not in git | PASS | .env gitignored |
| No secrets in Docker images | PASS | Runtime injection only |
| Placeholder examples only | PASS | .env.example clean |
| No secrets in logs | N/A | No logging review performed |
**Overall Secrets Audit: PASS**

View File

@@ -1,233 +0,0 @@
# Base Image Vulnerability Scan
**Date:** 2026-02-20
**Auditor:** External Security Review
**Tool:** Aqua Trivy (latest)
**Scope:** Base images used in project Dockerfiles
## Executive Summary
| Base Image | HIGH | CRITICAL | Total | Status |
|------------|------|----------|-------|--------|
| alpine:3.20 | 0 | 0 | 0 | CLEAN |
| python:3.12-slim | 2 | 0 | 2 | ACTION REQUIRED |
| node:22-slim | 2 | 1 | 3+ | ACTION REQUIRED |
| debian:bookworm-slim | 2 | 1 | 3 | ACTION REQUIRED |
| golang:1.23-alpine | 4 | 2 | 6 | ACTION REQUIRED |
**Overall Risk Level:** MEDIUM
---
## Detailed Findings
### 1. alpine:3.20
**Status:** CLEAN
**Vulnerabilities:** 0 HIGH/CRITICAL
```
Report Summary
┌─────────────────────────────┬────────┬─────────────────┬─────────┐
│ Target │ Type │ Vulnerabilities │ Secrets │
├─────────────────────────────┼────────┼─────────────────┼─────────┤
│ alpine:3.20 (alpine 3.20.9) │ alpine │ 0 │ - │
└─────────────────────────────┴────────┴─────────────────┴─────────┘
```
**Recommendation:** Preferred base image for new containers.
---
### 2. python:3.12-slim (debian 13.3)
**Status:** ACTION REQUIRED
**Vulnerabilities:** 2 HIGH, 0 CRITICAL
| Library | CVE | Severity | Status | Title |
|---------|-----|----------|--------|-------|
| libc-bin | CVE-2026-0861 | HIGH | affected | glibc: Integer overflow in memalign leads to heap corruption |
| libc6 | CVE-2026-0861 | HIGH | affected | glibc: Integer overflow in memalign leads to heap corruption |
**Analysis:**
- glibc vulnerability CVE-2026-0861 affects memory allocation
- No fix currently available from Debian
- Risk: Low for containerized workloads (no untrusted memory allocation)
**Recommendation:**
- Monitor for security updates
- Consider Alpine-based Python images if risk is unacceptable
---
### 3. node:22-slim (debian 12.13)
**Status:** ACTION REQUIRED
**Vulnerabilities:** 2 HIGH, 1 CRITICAL (OS) + 14 HIGH (Node packages)
#### OS-Level Vulnerabilities
| Library | CVE | Severity | Status | Title |
|---------|-----|----------|--------|-------|
| libc-bin | CVE-2026-0861 | HIGH | affected | glibc integer overflow |
| libc6 | CVE-2026-0861 | HIGH | affected | glibc integer overflow |
| zlib1g | CVE-2023-45853 | CRITICAL | will_not_fix | zlib heap-based buffer overflow |
#### Node Package Vulnerabilities
| Package | CVE | Severity | Installed | Fixed | Issue |
|---------|-----|----------|-----------|-------|-------|
| glob | CVE-2025-64756 | HIGH | 10.4.5 | 11.1.0 | Command Injection via Malicious Filenames |
| minimatch | CVE-2026-26996 | HIGH | 9.0.5 | 10.2.1 | ReDoS via repeated wildcards |
| tar | CVE-2026-23745 | HIGH | 6.2.1, 7.4.3 | 7.5.3 | Arbitrary file overwrite and symlink poisoning |
| tar | CVE-2026-23950 | HIGH | 6.2.1, 7.4.3 | 7.5.4 | Arbitrary file overwrite via Unicode path collision |
| tar | CVE-2026-24842 | HIGH | 6.2.1, 7.4.3 | 7.5.7 | Arbitrary file creation via path traversal bypass |
| tar | CVE-2026-26960 | HIGH | 6.2.1, 7.4.3 | 7.5.8 | Multiple issues with default options |
**Analysis:**
- zlib CVE-2023-45853 marked "will_not_fix" - architectural limitation in Debian
- Node tar package has multiple critical file system vulnerabilities
- These are build-time dependencies, reducing runtime risk
**Recommendation:**
- **HIGH PRIORITY:** Update tar package to 7.5.8+
- **HIGH PRIORITY:** Update glob to 11.1.0+ or 10.5.0+
- Monitor for Debian zlib security advisory
---
### 4. debian:bookworm-slim (debian 12.13)
**Status:** ACTION REQUIRED
**Vulnerabilities:** 2 HIGH, 1 CRITICAL
| Library | CVE | Severity | Status | Title |
|---------|-----|----------|--------|-------|
| libc-bin | CVE-2026-0861 | HIGH | affected | glibc integer overflow |
| libc6 | CVE-2026-0861 | HIGH | affected | glibc integer overflow |
| zlib1g | CVE-2023-45853 | CRITICAL | will_not_fix | zlib heap-based buffer overflow |
**Analysis:**
- Same vulnerabilities as node:22-slim (same Debian base)
- zlib vulnerability won't be fixed in Debian 12
**Recommendation:**
- Consider migrating to Alpine or Debian 13
- Monitor security advisories
---
### 5. golang:1.23-alpine (alpine 3.22.1)
**Status:** ACTION REQUIRED
**Vulnerabilities:** 4 HIGH, 2 CRITICAL
| Library | CVE | Severity | Status | Fixed Version | Title |
|---------|-----|----------|--------|---------------|-------|
| libcrypto3 | CVE-2025-15467 | CRITICAL | fixed | 3.5.5-r0 | OpenSSL: Remote code execution or DoS |
| libssl3 | CVE-2025-15467 | CRITICAL | fixed | 3.5.5-r0 | OpenSSL: Remote code execution or DoS |
**Additional vulnerabilities:** 4 HIGH related to Go toolchain (affects build only)
**Analysis:**
- OpenSSL CVE-2025-15467 is CRITICAL with RCE potential
- Fix available (3.5.5-r0) but current image uses 3.5.1-r0
- This is a significant security issue
**Recommendation:**
- **CRITICAL PRIORITY:** Update base image or rebuild with updated packages
- Alpine 3.22.1 should be updated to include OpenSSL fix
---
## Risk Assessment Matrix
| CVE | CVSS | Exploitability | Container Impact | Overall Risk |
|-----|------|----------------|------------------|--------------|
| CVE-2025-15467 (OpenSSL) | CRITICAL | High | High | CRITICAL |
| CVE-2023-45853 (zlib) | CRITICAL | Low | Medium | HIGH |
| CVE-2026-0861 (glibc) | HIGH | Low | Low | MEDIUM |
| CVE-2025-64756 (glob) | HIGH | Medium | Medium | HIGH |
| CVE-2026-23745 (tar) | HIGH | Medium | High | HIGH |
---
## Remediation Priority
### Immediate (Before Release)
1. **Update golang:1.23-alpine** - OpenSSL RCE vulnerability
2. **Update Node tar package** in affected images - Multiple file system vulnerabilities
### Short Term (Post-Release)
3. **Update Node glob and minimatch** packages
4. **Monitor glibc CVE-2026-0861** for patches
5. **Evaluate Alpine-based alternatives** for Python images
### Long Term
6. **Implement automated base image scanning** in CI/CD
7. **Create base image update policy** (monthly refresh)
8. **Consider distroless images** for production
---
## Base Image Recommendations
### For New Services
1. **Prefer Alpine** (alpine:3.20) - currently clean
2. **Pin to digest** for reproducibility:
```dockerfile
FROM alpine:3.20@sha256:exact-digest-here
```
3. **Avoid images with unfixed vulnerabilities**
### Image Selection Priority
1. `alpine:3.20` - CLEAN
2. `python:3.12-slim` - 2 HIGH (glibc, no fix)
3. `node:22-slim` - Multiple HIGH/CRITICAL
4. `debian:bookworm-slim` - Multiple HIGH/CRITICAL
5. `golang:1.23-alpine` - CRITICAL OpenSSL (fix available)
---
## CI/CD Integration Recommendation
```yaml
# Example GitLab CI
container_scan:
image: aquasec/trivy:latest
script:
- trivy image --severity HIGH,CRITICAL --exit-code 1 $IMAGE
only:
- main
- merge requests
```
---
## Scanning Methodology
```bash
# Commands used
docker pull aquasec/trivy:latest
docker run --rm aquasec/trivy:latest image --severity HIGH,CRITICAL --quiet alpine:3.20
docker run --rm aquasec/trivy:latest image --severity HIGH,CRITICAL --quiet python:3.12-slim
docker run --rm aquasec/trivy:latest image --severity HIGH,CRITICAL --quiet node:22-slim
docker run --rm aquasec/trivy:latest image --severity HIGH,CRITICAL --quiet debian:bookworm-slim
docker run --rm aquasec/trivy:latest image --severity HIGH,CRITICAL --quiet golang:1.23-alpine
```
---
## Positive Findings
1. **Alpine images are clean** - Good baseline option available
2. **Fixes available** for most vulnerabilities
3. **No secrets in images** - Confirmed by Trivy scan
4. **Reasonable image selection** - Using official images

View File

@@ -1,234 +0,0 @@
# Security Audit Final Report
**Project:** KNEL-AIMiddleware
**Date:** 2026-02-20
**Auditor:** External Security Review
**Report Version:** 1.0
---
## Executive Summary
### Overall Assessment: CONDITIONAL PASS
The KNEL-AIMiddleware project demonstrates **good foundational security practices** with some areas requiring remediation before production release. The project handles credentials properly, uses official base images, and has no hardcoded secrets. However, container privilege management and base image vulnerabilities require attention.
### Risk Summary
| Category | Risk Level | Issues | Critical Action Required |
|----------|------------|--------|--------------------------|
| Secrets Management | LOW | 0 | No |
| Dockerfile Security | HIGH | 38 | Yes |
| Shell Script Security | HIGH | 83 | Yes |
| Docker Compose | MEDIUM | 5 | Partial |
| Base Image Vulnerabilities | MEDIUM | 14+ | Yes |
### Release Readiness: READY WITH CONDITIONS
**Conditions for Release:**
1. Fix CRITICAL OpenSSL vulnerability in golang:1.23-alpine
2. Document privileged services and their justification
3. Implement remediation plan for HIGH severity findings
---
## Detailed Findings Summary
### 1. Secrets & Credentials (PASS)
**Grade: A**
| Check | Result |
|-------|--------|
| No hardcoded secrets | PASS |
| .env properly gitignored | PASS |
| Placeholder-only examples | PASS |
| Runtime credential injection | PASS |
| No secrets in git history | PASS |
**Finding:** Project follows excellent secret management practices. Credentials are injected at runtime via environment variables, with no secrets in the codebase or Docker images.
---
### 2. Dockerfile Security (NEEDS IMPROVEMENT)
**Grade: C**
| Issue | Severity | Count | Remediation |
|-------|----------|-------|-------------|
| Running as root | HIGH | 38/40 | Add USER directive |
| Missing multi-stage builds | MEDIUM | 32/40 | Convert to multi-stage |
| Build-time secrets | MEDIUM | 1 | Remove ARG for secrets |
| Missing --no-install-recommends | LOW | 2 | Add flag |
**Top Recommendation:** Add non-root users to all Dockerfiles. 95% of containers currently run as root.
---
### 3. Shell Script Security (NEEDS IMPROVEMENT)
**Grade: C-**
| Issue | Severity | Count | Remediation |
|-------|----------|-------|-------------|
| Missing set -e | HIGH | 38 | Add error handling |
| Missing set -u | HIGH | 45 | Add undefined var protection |
| Unquoted variables | MEDIUM | 4 | Quote all variables |
**Top Recommendation:** Add `set -euo pipefail` to all shell scripts.
---
### 4. Docker Compose Security (ACCEPTABLE)
**Grade: B**
| Issue | Severity | Services | Status |
|-------|----------|----------|--------|
| Docker socket mount | HIGH | 2 | Required for function |
| kubeconfig mount | HIGH | 1 | Required for function |
| Default credential pattern | LOW | 1 | Remove defaults |
| No resource limits | MEDIUM | All | Add limits |
| No health checks | MEDIUM | All | Add health checks |
**Finding:** Privileged access (Docker socket, kubeconfig) is necessary for service function but should be documented.
---
### 5. Base Image Vulnerabilities (NEEDS ATTENTION)
**Grade: B-**
| Image | HIGH | CRITICAL | Status |
|-------|------|----------|--------|
| alpine:3.20 | 0 | 0 | Clean |
| python:3.12-slim | 2 | 0 | Monitor |
| node:22-slim | 2 | 1 | Update packages |
| debian:bookworm-slim | 2 | 1 | Monitor |
| golang:1.23-alpine | 4 | 2 | **UPDATE NOW** |
**Critical Finding:** CVE-2025-15467 (OpenSSL RCE) in golang:1.23-alpine requires immediate patching.
---
## Remediation Roadmap
### Phase 1: Pre-Release (Required)
| Priority | Task | Effort | Impact |
|----------|------|--------|--------|
| 1 | Update golang:1.23-alpine base image | Low | Critical |
| 2 | Document privileged services | Low | High |
| 3 | Remove default credential patterns | Low | Medium |
### Phase 2: Short Term (30 Days)
| Priority | Task | Effort | Impact |
|----------|------|--------|--------|
| 4 | Add `set -euo pipefail` to all scripts | Low | High |
| 5 | Add USER directive to Dockerfiles | Medium | High |
| 6 | Update Node tar package | Low | High |
| 7 | Add resource limits to docker-compose | Low | Medium |
### Phase 3: Medium Term (90 Days)
| Priority | Task | Effort | Impact |
|----------|------|--------|--------|
| 8 | Convert to multi-stage builds | High | Medium |
| 9 | Implement CI/CD vulnerability scanning | Medium | High |
| 10 | Add health checks to all services | Medium | Medium |
| 11 | Implement socket proxy for Docker access | Medium | High |
### Phase 4: Long Term (Ongoing)
| Priority | Task | Effort | Impact |
|----------|------|--------|--------|
| 12 | Base image update policy | Low | Medium |
| 13 | Consider distroless images | High | Medium |
| 14 | Network segmentation | Medium | Medium |
---
## Risk Register
### Critical Risks (Address Before Release)
| ID | Risk | Likelihood | Impact | Mitigation |
|----|------|------------|--------|------------|
| R1 | OpenSSL RCE in golang images | Medium | Critical | Update base image |
### High Risks (Address Within 30 Days)
| ID | Risk | Likelihood | Impact | Mitigation |
|----|------|------------|--------|------------|
| R2 | Container privilege escalation | Medium | High | Add USER directives |
| R3 | Silent script failures | Medium | High | Add set -e |
| R4 | Node tar vulnerabilities | Medium | High | Update package |
### Medium Risks (Address Within 90 Days)
| ID | Risk | Likelihood | Impact | Mitigation |
|----|------|------------|--------|------------|
| R5 | Docker socket abuse | Low | High | Document, socket proxy |
| R6 | Resource exhaustion | Low | Medium | Add limits |
| R7 | glibc vulnerability | Low | Medium | Monitor for patches |
---
## Positive Security Practices
The project demonstrates several security-conscious decisions:
1. **Credential Management**
- No hardcoded secrets anywhere
- Environment variables properly externalized
- .env file correctly gitignored
2. **Container Design**
- No privileged mode containers
- Read-only mounts where appropriate
- Official base images used
3. **Project Hygiene**
- Consistent naming conventions
- Clear documentation structure
- Wrapper scripts for configuration isolation
4. **Secret Injection Pattern**
- Runtime injection via environment
- No secrets baked into images
- Pass-through wrapper design
---
## Audit Artifacts
The following detailed reports are available:
1. [01-dockerfile-security.md](./01-dockerfile-security.md) - Dockerfile analysis
2. [02-shell-script-security.md](./02-shell-script-security.md) - Shell script analysis
3. [03-docker-compose-security.md](./03-docker-compose-security.md) - Docker Compose analysis
4. [04-secrets-audit.md](./04-secrets-audit.md) - Credentials and secrets review
5. [05-vulnerability-scan.md](./05-vulnerability-scan.md) - Base image vulnerabilities
---
## Conclusion
KNEL-AIMiddleware is **ready for release with conditions**. The project has solid security fundamentals, particularly in credential management. The primary concerns are:
1. **Immediate:** OpenSSL vulnerability in golang images
2. **Short-term:** Container privilege model (running as root)
3. **Short-term:** Shell script error handling
Addressing the critical OpenSSL vulnerability and documenting privileged services will allow for a safe initial release. The remaining findings should be addressed in subsequent releases.
### Auditor Confidence: HIGH
All major security domains were reviewed. Read-only access was maintained throughout. No destructive testing was performed.
---
*Report generated: 2026-02-20*
*Auditor: External Security Review*
*Classification: Confidential*

View File

@@ -1,18 +0,0 @@
#!/bin/sh
# Wrapper script for bash-language-server LSP
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-bash-language-server"
IMAGE_NAME="kneldevstack-aimiddleware-bash-language-server"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start LSP server with explicit name
exec docker run -i --rm --name "${CONTAINER_NAME}" "${IMAGE_NAME}" start "$@"

View File

@@ -1,18 +0,0 @@
#!/bin/sh
# Wrapper script for docker-language-server LSP
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-docker-language-server"
IMAGE_NAME="kneldevstack-aimiddleware-docker-language-server"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start LSP server with explicit name
exec docker run -i --rm --name "${CONTAINER_NAME}" "${IMAGE_NAME}" start --stdio "$@"

View File

@@ -1,18 +0,0 @@
#!/bin/sh
# Wrapper script for marksman LSP
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-marksman"
IMAGE_NAME="kneldevstack-aimiddleware-marksman"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start LSP server with explicit name
exec docker run -i --rm --name "${CONTAINER_NAME}" "${IMAGE_NAME}" "$@"

View File

@@ -1,4 +0,0 @@
#!/bin/bash
docker run -i --rm \
-v "$(pwd):/workspace" \
kneldevstack-aimiddleware-terraform-ls

View File

@@ -1,177 +0,0 @@
#!/bin/bash
# maintenance.sh
# Comprehensive maintenance script for KNEL-AIMiddleware
# Combines functionality from the old Makefile with Docker Compose
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Change to project directory
cd "$(dirname "${BASH_SOURCE[0]}")"
# Function to show usage
show_usage() {
cat << EOF
Usage: $0 <command>
Available commands:
clone-vendors Clone all vendor MCP/LSP repositories
build-all Build all MCP/LSP services
build <service> Build a specific service
clean-vendor Remove all cloned vendor repositories
status Check build status of all services
validate Validate MCP servers
logs Show logs from all running services
ps Show status of all services
up [profile] Start services (default: dev profile)
down Stop all services
rebuild <service> Rebuild a specific service
help Show this help message
Examples:
$0 clone-vendors
$0 build ghost-mcp
$0 rebuild context7-mcp
$0 up dev
$0 down
EOF
}
# Function to clone vendor repositories
clone_vendors() {
echo -e "${GREEN}=== Cloning Vendor Repositories ===${NC}"
./scripts/CloneVendorRepos.sh
}
# Function to build all services
build_all() {
echo -e "${GREEN}=== Building All Services ===${NC}"
./scripts/BuildAll.sh
}
# Function to build specific service
build_service() {
local service=$1
if [ -z "$service" ]; then
echo -e "${RED}Error: Service name required${NC}"
echo "Usage: $0 build <service-name>"
exit 1
fi
echo -e "${GREEN}=== Building $service ===${NC}"
docker compose build "$service"
}
# Function to clean vendor directory
clean_vendor() {
echo -e "${YELLOW}=== Cleaning Vendor Directory ===${NC}"
read -p "This will remove all cloned vendor repositories. Continue? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
./scripts/CleanVendor.sh
else
echo "Cancelled."
fi
}
# Function to check status
status() {
echo -e "${GREEN}=== Service Status ===${NC}"
./scripts/StatusCheck.sh
}
# Function to validate MCP servers
validate() {
echo -e "${GREEN}=== Validating MCP Servers ===${NC}"
./scripts/validate-mcp.sh
}
# Function to show logs
logs() {
echo -e "${GREEN}=== Service Logs ===${NC}"
docker compose logs -f
}
# Function to show process status
ps() {
echo -e "${GREEN}=== Service Process Status ===${NC}"
docker compose ps
}
# Function to start services
up() {
local profile=${1:-dev}
echo -e "${GREEN}=== Starting Services (profile: $profile) ===${NC}"
docker compose up -d --profile "$profile"
}
# Function to stop services
down() {
echo -e "${GREEN}=== Stopping Services ===${NC}"
docker compose down
}
# Function to rebuild service
rebuild() {
local service=$1
if [ -z "$service" ]; then
echo -e "${RED}Error: Service name required${NC}"
echo "Usage: $0 rebuild <service-name>"
exit 1
fi
echo -e "${GREEN}=== Rebuilding $service ===${NC}"
docker compose build --no-cache "$service"
docker compose up -d "$service"
}
# Main script logic
case "${1:-help}" in
clone-vendors)
clone_vendors
;;
build-all)
build_all
;;
build)
build_service "$2"
;;
clean-vendor)
clean_vendor
;;
status)
status
;;
validate)
validate
;;
logs)
logs
;;
ps)
ps
;;
up)
up "$2"
;;
down)
down
;;
rebuild)
rebuild "$2"
;;
help|--help|-h)
show_usage
;;
*)
echo -e "${RED}Unknown command: $1${NC}"
echo ""
show_usage
exit 1
;;
esac

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for actual-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-actual-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-actual-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e ACTUAL_SERVER_URL="${ACTUAL_SERVER_URL}" \
-e ACTUAL_PASSWORD="${ACTUAL_PASSWORD}" \
-e ACTUAL_BUDGET_SYNC_ID="${ACTUAL_BUDGET_SYNC_ID}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for mcp-ansible
# Ensures clean container with proper name, playbooks mount, and Docker socket
CONTAINER_NAME="kneldevstack-aimiddleware-mcp-ansible-crush"
IMAGE_NAME="kneldevstack-aimiddleware-mcp-ansible"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name, playbooks mount, and Docker socket
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-v "${HOME}/Projects/KNEL/KNEL-AIMiddleware/ansible-playbooks:/playbooks:ro" \
-v /var/run/docker.sock:/var/run/docker.sock \
"${IMAGE_NAME}" "$@"

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Wrapper script for audiobook-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-audiobook-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-audiobook-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "AUDIOBOOK_ROOT=${AUDIOBOOK_ROOT:-/audiobooks}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for beszel-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-beszel-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-beszel-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e BESZEL_URL="${BESZEL_URL}" \
-e BESZEL_USERNAME="${BESZEL_USERNAME}" \
-e BESZEL_PASSWORD="${BESZEL_PASSWORD}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,23 +0,0 @@
#!/bin/sh
# Wrapper script for bitwarden-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-bitwarden-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-bitwarden-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "BITWARDEN_CLIENT_ID=${BITWARDEN_CLIENT_ID:-}" \
-e "BITWARDEN_CLIENT_SECRET=${BITWARDEN_CLIENT_SECRET:-}" \
-e "BITWARDEN_PASSWORD=${BITWARDEN_PASSWORD:-}" \
-e "BITWARDEN_SERVER_URL=${BITWARDEN_SERVER_URL:-https://vault.bitwarden.com}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for blender-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-blender-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-blender-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "BLENDER_HOST=${BLENDER_HOST:-localhost}" \
-e "BLENDER_PORT=${BLENDER_PORT:-8888}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for cloudron-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-cloudron-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-cloudron-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "CLOUDRON_URL=${CLOUDRON_URL:-}" \
-e "CLOUDRON_TOKEN=${CLOUDRON_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for context7-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-context7-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-context7-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "UPSTASH_REDIS_REST_URL=${UPSTASH_REDIS_REST_URL:-}" \
-e "UPSTASH_REDIS_REST_TOKEN=${UPSTASH_REDIS_REST_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for discourse-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-discourse-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-discourse-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "DISCOURSE_URL=${DISCOURSE_URL:-}" \
-e "DISCOURSE_API_KEY=${DISCOURSE_API_KEY:-}" \
-e "DISCOURSE_API_USERNAME=${DISCOURSE_API_USERNAME:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for docker-mcp
# Ensures clean container with proper name and Docker socket
CONTAINER_NAME="kneldevstack-aimiddleware-docker-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-docker-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name, Docker socket, and config
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "${HOME}/.docker/config.json:/root/.docker/config.json:ro" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for docspace-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-docspace-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-docspace-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "DOCSPACE_HOST=${DOCSPACE_HOST:-}" \
-e "DOCSPACE_TOKEN=${DOCSPACE_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Wrapper script for drawio-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-drawio-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-drawio-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "DRAWIO_URL=${DRAWIO_URL:-https://app.diagrams.net}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for elasticsearch-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-elasticsearch-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-elasticsearch-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "ES_URL=${ES_URL:-http://localhost:9200}" \
-e "ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME:-}" \
-e "ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,15 +0,0 @@
#!/bin/bash
# Firefly III MCP wrapper script for Crush
CONTAINER_NAME="kneldevstack-aimiddleware-firefly-iii-mcp-crush"
# Force remove existing container (suppress output)
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true
sleep 0.5
# Run container with explicit name and environment variables
docker run -i --rm \
--name "${CONTAINER_NAME}" \
-e FIREFLY_III_BASE_URL="${FIREFLY_III_BASE_URL:-}" \
-e FIREFLY_III_PAT="${FIREFLY_III_PAT:-}" \
-e FIREFLY_III_PRESET="${FIREFLY_III_PRESET:-default}" \
kneldevstack-aimiddleware-firefly-iii-mcp

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Wrapper script for freecad-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-freecad-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-freecad-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "PYTHONUNBUFFERED=1" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for ghost-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-ghost-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-ghost-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "GHOST_API_URL=${GHOST_API_URL:-http://localhost:2368}" \
-e "GHOST_ADMIN_API_KEY=${GHOST_ADMIN_API_KEY:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Wrapper script for gimp-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-gimp-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-gimp-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "PYTHONUNBUFFERED=1" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for gitea-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-gitea-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-gitea-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e GITEA_URL="${GITEA_URL}" \
-e GITEA_TOKEN="${GITEA_TOKEN}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for mcp-grafana
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-mcp-grafana-crush"
IMAGE_NAME="kneldevstack-aimiddleware-mcp-grafana"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e GRAFANA_URL="${GRAFANA_URL}" \
-e GRAFANA_TOKEN="${GRAFANA_TOKEN}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for ha-mcp (Home Assistant)
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-ha-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-ha-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e HOMEASSISTANT_URL="${HOMEASSISTANT_URL}" \
-e HOMEASSISTANT_TOKEN="${HOMEASSISTANT_TOKEN}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,24 +0,0 @@
#!/bin/sh
# Wrapper script for imap-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-imap-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-imap-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "PYTHONUNBUFFERED=1" \
-e "IMAP_HOST=${IMAP_HOST:-}" \
-e "IMAP_PORT=${IMAP_PORT:-993}" \
-e "IMAP_USER=${IMAP_USER:-}" \
-e "IMAP_PASSWORD=${IMAP_PASSWORD:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,5 +0,0 @@
#!/bin/bash
docker run -i --rm \
-v ~/.kube/config:/root/.kube/config:ro \
kneldevstack-aimiddleware-kubernetes-mcp \
--transport stdio

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for limesurvey-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-limesurvey-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-limesurvey-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e LIMESURVEY_URL="${LIMESURVEY_URL}" \
-e LIMESURVEY_USERNAME="${LIMESURVEY_USERNAME}" \
-e LIMESURVEY_PASSWORD="${LIMESURVEY_PASSWORD}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for linkwarden-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-linkwarden-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-linkwarden-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e LINKWARDEN_URL="${LINKWARDEN_URL}" \
-e LINKWARDEN_TOKEN="${LINKWARDEN_TOKEN}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for matomo-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-matomo-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-matomo-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "MATOMO_URL=${MATOMO_URL:-}" \
-e "MATOMO_TOKEN=${MATOMO_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for nextcloud-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-nextcloud-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-nextcloud-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "NEXTCLOUD_HOST=${NEXTCLOUD_HOST:-}" \
-e "NEXTCLOUD_USERNAME=${NEXTCLOUD_USERNAME:-}" \
-e "NEXTCLOUD_PASSWORD=${NEXTCLOUD_PASSWORD:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,15 +0,0 @@
#!/bin/bash
# Paperless-NGX MCP wrapper script for Crush
CONTAINER_NAME="kneldevstack-aimiddleware-paperless-mcp-crush"
# Force remove existing container (suppress output)
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true
sleep 0.5
# Run container with explicit name and environment variables
docker run -i --rm \
--name "${CONTAINER_NAME}" \
-e PAPERLESS_URL="${PAPERLESS_URL:-}" \
-e PAPERLESS_TOKEN="${PAPERLESS_TOKEN:-}" \
kneldevstack-aimiddleware-paperless-mcp \
"${PAPERLESS_URL:-http://localhost:8000}" "${PAPERLESS_TOKEN:-}"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for penpot-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-penpot-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-penpot-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "PENPOT_URL=${PENPOT_URL:-https://design.penpot.app}" \
-e "PENPOT_TOKEN=${PENPOT_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for postizz-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-postizz-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-postizz-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "POSTIZ_API_KEY=${POSTIZ_API_KEY:-}" \
-e "POSTIZ_URL=${POSTIZ_URL:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,23 +0,0 @@
#!/bin/sh
# Wrapper script for proxmox-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-proxmox-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-proxmox-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "PROXMOX_HOST=${PROXMOX_HOST:-}" \
-e "PROXMOX_USER=${PROXMOX_USER:-}" \
-e "PROXMOX_TOKEN=${PROXMOX_TOKEN:-}" \
-e "PROXMOX_NODE=${PROXMOX_NODE:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for mcp-redmine
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-mcp-redmine-crush"
IMAGE_NAME="kneldevstack-aimiddleware-mcp-redmine"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "REDMINE_URL=${REDMINE_URL:-}" \
-e "REDMINE_API_KEY=${REDMINE_API_KEY:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Wrapper script for snipeit-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-snipeit-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-snipeit-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment variables
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e "SNIPEIT_URL=${SNIPEIT_URL:-}" \
-e "SNIPEIT_TOKEN=${SNIPEIT_TOKEN:-}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# Wrapper script for superset-mcp
# Ensures clean container with proper name
CONTAINER_NAME="kneldevstack-aimiddleware-superset-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-superset-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" 2>/dev/null
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and environment
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-e SUPERSET_URL="${SUPERSET_URL}" \
-e SUPERSET_USERNAME="${SUPERSET_USERNAME}" \
-e SUPERSET_PASSWORD="${SUPERSET_PASSWORD}" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Wrapper script for terraform-mcp
# Ensures clean container with proper name and Terraform credentials
CONTAINER_NAME="kneldevstack-aimiddleware-terraform-mcp-crush"
IMAGE_NAME="kneldevstack-aimiddleware-terraform-mcp"
# Force remove existing container if it exists (in any state)
if docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1
# Wait for container to be fully removed
while docker ps -a --filter "name=${CONTAINER_NAME}" --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; do
sleep 0.05
done
fi
# Start MCP server with explicit name and Terraform credential mounts
exec docker run -i --rm --name "${CONTAINER_NAME}" \
-v "${HOME}/.terraform.d:/terraform/.terraform.d:ro" \
"${IMAGE_NAME}" "$@"

View File

@@ -1,4 +0,0 @@
#!/bin/bash
docker run -i --rm \
kneldevstack-aimiddleware-webserial-mcp \
ws://host.docker.internal:3000

Some files were not shown because too many files have changed in this diff Show More