go-ai/mcp/transport_unix.go

53 lines
1.3 KiB
Go
Raw Normal View History

package mcp
import (
"context"
"net"
"os"
"forge.lthn.ai/core/go/pkg/log"
)
// ServeUnix starts a Unix domain socket server for the MCP service.
// The socket file is created at the given path and removed on shutdown.
// It accepts connections and spawns a new MCP server session for each connection.
func (s *Service) ServeUnix(ctx context.Context, socketPath string) error {
// Clean up any stale socket file
if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {
s.logger.Warn("Failed to remove stale socket", "path", socketPath, "err", err)
}
listener, err := net.Listen("unix", socketPath)
if err != nil {
return err
}
defer func() {
_ = listener.Close()
_ = os.Remove(socketPath)
}()
// Close listener when context is cancelled to unblock Accept
go func() {
<-ctx.Done()
_ = listener.Close()
}()
s.logger.Security("MCP Unix server listening", "path", socketPath, "user", log.Username())
for {
conn, err := listener.Accept()
if err != nil {
select {
case <-ctx.Done():
return nil
default:
s.logger.Error("MCP Unix accept error", "err", err, "user", log.Username())
continue
}
}
s.logger.Security("MCP Unix connection accepted", "user", log.Username())
go s.handleConnection(ctx, conn)
}
}