
Audio System Enhancements: - Complete PipeWire configuration with WirePlumber session management - AI-powered noise suppression using RNNoise plugin - GUI applications: EasyEffects, pavucontrol, Helvum, qpwgraph, pwvucontrol - Pre-configured audio presets for microphone noise suppression - Desktop integration with auto-start and helper scripts - Validation tools and interactive audio management utilities - Real-time audio processing with RTKit optimization - Cross-application compatibility (Discord, Zoom, OBS, etc.) MCP (Model Context Protocol) Implementation in Guile Scheme: - Modular MCP server architecture with clean separation of concerns - JSON-RPC transport layer with WebSocket and stdio support - Protocol compliance with MCP specification - Comprehensive error handling and validation - Router system for tool and resource management - Integration layer for NixOS Home Lab management - Full test suite with unit and integration tests - Documentation and usage examples Technical Details: - Removed conflicting ALSA udev rules while maintaining compatibility - Fixed package dependencies and service configurations - Successfully deployed and tested on congenital-optimist machine - Functional programming approach using Guile Scheme modules - Type-safe protocol implementation with validation - Async/await pattern support for concurrent operations This represents a significant enhancement to the Home Lab infrastructure, providing both professional-grade audio capabilities and a robust MCP server implementation for AI assistant integration.
280 lines
12 KiB
Scheme
280 lines
12 KiB
Scheme
;; MCP Server Integration with Guile Infrastructure
|
|
;; This module integrates the MCP server with existing Guile-based home lab infrastructure
|
|
|
|
(define-module (mcp server integration)
|
|
#:use-module (ice-9 match)
|
|
#:use-module (ice-9 receive)
|
|
#:use-module (ice-9 popen)
|
|
#:use-module (ice-9 rdelim)
|
|
#:use-module (json)
|
|
#:use-module (srfi srfi-1)
|
|
#:use-module (srfi srfi-9)
|
|
#:use-module (srfi srfi-26)
|
|
#:use-module (mcp server jsonrpc)
|
|
#:use-module (mcp server protocol)
|
|
#:use-module (mcp server transport)
|
|
#:use-module (mcp server router)
|
|
#:use-module (mcp server validation)
|
|
#:use-module (mcp server error-handling)
|
|
#:export (create-integrated-mcp-server
|
|
register-lab-tools
|
|
register-lab-resources
|
|
register-lab-prompts
|
|
lab-command-executor
|
|
lab-config-reader
|
|
lab-status-checker
|
|
setup-mcp-server
|
|
start-mcp-server))
|
|
|
|
;; Lab command executor - integrates with existing shell commands
|
|
(define (lab-command-executor command args)
|
|
"Execute a lab command and return the result"
|
|
(catch #t
|
|
(lambda ()
|
|
(let* ((cmd-string (string-join (cons command args) " "))
|
|
(port (open-input-pipe cmd-string))
|
|
(output (read-string port))
|
|
(exit-code (close-pipe port)))
|
|
(if (= exit-code 0)
|
|
`(("success" . #t)
|
|
("output" . ,output)
|
|
("exit_code" . ,exit-code))
|
|
`(("success" . #f)
|
|
("output" . ,output)
|
|
("error" . "Command failed")
|
|
("exit_code" . ,exit-code)))))
|
|
(lambda (key . args)
|
|
`(("success" . #f)
|
|
("error" . ,(format #f "Exception: ~a" key))
|
|
("details" . ,args)))))
|
|
|
|
;; Configuration reader - reads lab configuration
|
|
(define (lab-config-reader config-path)
|
|
"Read lab configuration from file"
|
|
(catch #t
|
|
(lambda ()
|
|
(if (file-exists? config-path)
|
|
(call-with-input-file config-path
|
|
(lambda (port)
|
|
(json->scm port)))
|
|
`(("error" . "Configuration file not found")
|
|
("path" . ,config-path))))
|
|
(lambda (key . args)
|
|
`(("error" . ,(format #f "Failed to read config: ~a" key))
|
|
("details" . ,args)))))
|
|
|
|
;; Status checker - checks lab infrastructure status
|
|
(define (lab-status-checker)
|
|
"Check the status of lab infrastructure"
|
|
(let ((services '("ssh" "docker" "nixos-rebuild"))
|
|
(status-results '()))
|
|
|
|
(for-each
|
|
(lambda (service)
|
|
(let ((result (lab-command-executor "systemctl" (list "is-active" service))))
|
|
(set! status-results
|
|
(cons `(,service . ,result) status-results))))
|
|
services)
|
|
|
|
`(("timestamp" . ,(current-time))
|
|
("services" . ,status-results))))
|
|
|
|
;; Tool registration functions
|
|
(define (register-lab-tools server)
|
|
"Register lab management tools with the MCP server"
|
|
|
|
;; Machine management tools
|
|
(register-route (mcp-server-handlers server) "tools/machine/list"
|
|
(lambda (server params)
|
|
(lab-command-executor "ls" '("/etc/nixos/machines"))))
|
|
|
|
(register-route (mcp-server-handlers server) "tools/machine/status"
|
|
(lambda (server params)
|
|
(let ((machine (hash-ref params "machine" #f)))
|
|
(if machine
|
|
(lab-command-executor "ping" (list "-c" "1" machine))
|
|
'(("error" . "Machine name required"))))))
|
|
|
|
(register-route (mcp-server-handlers server) "tools/machine/deploy"
|
|
(lambda (server params)
|
|
(let ((machine (hash-ref params "machine" #f))
|
|
(config (hash-ref params "config" #f)))
|
|
(if (and machine config)
|
|
(lab-command-executor "nixos-rebuild"
|
|
(list "switch" "--target-host" machine
|
|
"--flake" config))
|
|
'(("error" . "Machine and config required"))))))
|
|
|
|
;; Service management tools
|
|
(register-route (mcp-server-handlers server) "tools/service/status"
|
|
(lambda (server params)
|
|
(let ((service (hash-ref params "service" #f)))
|
|
(if service
|
|
(lab-command-executor "systemctl" (list "status" service))
|
|
'(("error" . "Service name required"))))))
|
|
|
|
(register-route (mcp-server-handlers server) "tools/service/restart"
|
|
(lambda (server params)
|
|
(let ((service (hash-ref params "service" #f)))
|
|
(if service
|
|
(lab-command-executor "systemctl" (list "restart" service))
|
|
'(("error" . "Service name required"))))))
|
|
|
|
;; Docker management tools
|
|
(register-route (mcp-server-handlers server) "tools/docker/ps"
|
|
(lambda (server params)
|
|
(lab-command-executor "docker" '("ps" "--format" "json"))))
|
|
|
|
(register-route (mcp-server-handlers server) "tools/docker/logs"
|
|
(lambda (server params)
|
|
(let ((container (hash-ref params "container" #f))
|
|
(lines (hash-ref params "lines" "100")))
|
|
(if container
|
|
(lab-command-executor "docker"
|
|
(list "logs" "--tail" lines container))
|
|
'(("error" . "Container name required"))))))
|
|
|
|
;; Network tools
|
|
(register-route (mcp-server-handlers server) "tools/network/scan"
|
|
(lambda (server params)
|
|
(let ((network (hash-ref params "network" "192.168.1.0/24")))
|
|
(lab-command-executor "nmap" (list "-sn" network)))))
|
|
|
|
;; Configuration tools
|
|
(register-route (mcp-server-handlers server) "tools/config/validate"
|
|
(lambda (server params)
|
|
(let ((config-path (hash-ref params "path" "/etc/nixos/configuration.nix")))
|
|
(lab-command-executor "nixos-rebuild" (list "dry-build" "--flake" config-path))))))
|
|
|
|
(define (register-lab-resources server)
|
|
"Register lab infrastructure resources with the MCP server"
|
|
|
|
;; Configuration files
|
|
(register-route (mcp-server-handlers server) "resources/config/nixos"
|
|
(lambda (server params)
|
|
(lab-config-reader "/etc/nixos/configuration.nix")))
|
|
|
|
(register-route (mcp-server-handlers server) "resources/config/machines"
|
|
(lambda (server params)
|
|
(lab-command-executor "find" '("/etc/nixos/machines" "-name" "*.nix"))))
|
|
|
|
;; System information
|
|
(register-route (mcp-server-handlers server) "resources/system/info"
|
|
(lambda (server params)
|
|
`(("hostname" . ,(gethostname))
|
|
("uptime" . ,(lab-command-executor "uptime" '()))
|
|
("load" . ,(lab-command-executor "cat" '("/proc/loadavg")))
|
|
("memory" . ,(lab-command-executor "free" '("-h"))))))
|
|
|
|
;; Network information
|
|
(register-route (mcp-server-handlers server) "resources/network/interfaces"
|
|
(lambda (server params)
|
|
(lab-command-executor "ip" '("addr" "show"))))
|
|
|
|
(register-route (mcp-server-handlers server) "resources/network/routes"
|
|
(lambda (server params)
|
|
(lab-command-executor "ip" '("route" "show"))))
|
|
|
|
;; Storage information
|
|
(register-route (mcp-server-handlers server) "resources/storage/disk"
|
|
(lambda (server params)
|
|
(lab-command-executor "df" '("-h"))))
|
|
|
|
(register-route (mcp-server-handlers server) "resources/storage/zfs"
|
|
(lambda (server params)
|
|
(lab-command-executor "zfs" '("list"))))
|
|
|
|
;; Log files
|
|
(register-route (mcp-server-handlers server) "resources/logs/system"
|
|
(lambda (server params)
|
|
(let ((lines (hash-ref params "lines" "100")))
|
|
(lab-command-executor "journalctl" (list "--lines" lines "--no-pager")))))
|
|
|
|
(register-route (mcp-server-handlers server) "resources/logs/service"
|
|
(lambda (server params)
|
|
(let ((service (hash-ref params "service" #f))
|
|
(lines (hash-ref params "lines" "100")))
|
|
(if service
|
|
(lab-command-executor "journalctl"
|
|
(list "-u" service "--lines" lines "--no-pager"))
|
|
'(("error" . "Service name required")))))))
|
|
|
|
(define (register-lab-prompts server)
|
|
"Register lab management prompts with the MCP server"
|
|
|
|
;; Deployment prompts
|
|
(register-route (mcp-server-handlers server) "prompts/deploy/machine"
|
|
(lambda (server params)
|
|
`(("prompt" . "Deploy configuration to machine")
|
|
("description" . "Deploy NixOS configuration to a target machine")
|
|
("parameters" . (("machine" . (("type" . "string")
|
|
("description" . "Target machine hostname")))
|
|
("config" . (("type" . "string")
|
|
("description" . "Configuration flake path")))
|
|
("dry_run" . (("type" . "boolean")
|
|
("description" . "Perform dry run only"))))))))
|
|
|
|
;; Troubleshooting prompts
|
|
(register-route (mcp-server-handlers server) "prompts/troubleshoot/service"
|
|
(lambda (server params)
|
|
`(("prompt" . "Troubleshoot service issues")
|
|
("description" . "Diagnose and troubleshoot service problems")
|
|
("parameters" . (("service" . (("type" . "string")
|
|
("description" . "Service name to troubleshoot")))
|
|
("include_logs" . (("type" . "boolean")
|
|
("description" . "Include service logs"))))))))
|
|
|
|
;; Monitoring prompts
|
|
(register-route (mcp-server-handlers server) "prompts/monitor/system"
|
|
(lambda (server params)
|
|
`(("prompt" . "Monitor system health")
|
|
("description" . "Check overall system health and performance")
|
|
("parameters" . (("detailed" . (("type" . "boolean")
|
|
("description" . "Include detailed metrics")))
|
|
("alerts_only" . (("type" . "boolean")
|
|
("description" . "Show only alerts and warnings")))))))))
|
|
|
|
;; Main integration setup
|
|
(define* (setup-mcp-server #:key (name "home-lab-mcp") (version "1.0.0") (transport-type 'stdio) (port 8080))
|
|
"Set up and configure the integrated MCP server"
|
|
(let* ((server (create-mcp-server name version))
|
|
(router (create-default-router))
|
|
(error-handler (create-default-error-handler))
|
|
(transport (case transport-type
|
|
((stdio) (stdio-transport))
|
|
((http) (http-transport port))
|
|
((websocket) (websocket-transport port))
|
|
(else (stdio-transport)))))
|
|
|
|
;; Register lab-specific handlers
|
|
(register-lab-tools server)
|
|
(register-lab-resources server)
|
|
(register-lab-prompts server)
|
|
|
|
;; Return configured server and transport
|
|
(values server transport router error-handler)))
|
|
|
|
(define* (start-mcp-server #:key (transport-type 'stdio) (port 8080))
|
|
"Start the integrated MCP server"
|
|
(receive (server transport router error-handler)
|
|
(setup-mcp-server #:transport-type transport-type #:port port)
|
|
|
|
(format (current-error-port) "Starting MCP server with ~a transport~%" transport-type)
|
|
|
|
;; Start the server
|
|
(catch #t
|
|
(lambda ()
|
|
(run-mcp-server server transport))
|
|
(lambda (key . args)
|
|
(handle-error error-handler 'internal-error
|
|
(cons key args)
|
|
"MCP server startup")))
|
|
|
|
(format (current-error-port) "MCP server stopped~%")))
|
|
|
|
;; Convenience function for creating integrated server
|
|
(define (create-integrated-mcp-server)
|
|
"Create a fully integrated MCP server with all lab tools"
|
|
(receive (server transport router error-handler)
|
|
(setup-mcp-server)
|
|
server))
|