From 8e77c5e58d13accea1dfd96b2c384f9b85ffa83b Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 12:56:30 +0000 Subject: [PATCH] feat(mcp): auto-select unix socket transport Co-Authored-By: Virgil --- cmd/mcpcmd/cmd_mcp.go | 11 +++++--- pkg/mcp/mcp.go | 7 +++++ pkg/mcp/transport_unix_test.go | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 pkg/mcp/transport_unix_test.go diff --git a/cmd/mcpcmd/cmd_mcp.go b/cmd/mcpcmd/cmd_mcp.go index 392f0d8..cb2b3ad 100644 --- a/cmd/mcpcmd/cmd_mcp.go +++ b/cmd/mcpcmd/cmd_mcp.go @@ -10,10 +10,10 @@ import ( "os/signal" "syscall" - "forge.lthn.ai/core/cli/pkg/cli" "dappco.re/go/mcp/pkg/mcp" "dappco.re/go/mcp/pkg/mcp/agentic" "dappco.re/go/mcp/pkg/mcp/brain" + "forge.lthn.ai/core/cli/pkg/cli" ) var workspaceFlag string @@ -27,13 +27,18 @@ var mcpCmd = &cli.Command{ var serveCmd = &cli.Command{ Use: "serve", Short: "Start the MCP server", - Long: `Start the MCP server on stdio (default) or TCP. + Long: `Start the MCP server on stdio (default), TCP, Unix socket, or HTTP. The server provides file operations, RAG tools, and metrics tools for AI assistants. Environment variables: MCP_ADDR TCP address to listen on (e.g., "localhost:9999") - If not set, uses stdio transport. + MCP_UNIX_SOCKET + Unix socket path to listen on (e.g., "/tmp/core-mcp.sock") + Selected after MCP_ADDR and before stdio. + MCP_HTTP_ADDR + HTTP address to listen on (e.g., "127.0.0.1:9101") + Selected before MCP_ADDR and stdio. Examples: # Start with stdio transport (for Claude Code integration) diff --git a/pkg/mcp/mcp.go b/pkg/mcp/mcp.go index 29107b4..dc2b94e 100644 --- a/pkg/mcp/mcp.go +++ b/pkg/mcp/mcp.go @@ -716,6 +716,10 @@ func supportedLanguages() []LanguageInfo { // os.Setenv("MCP_ADDR", "127.0.0.1:9100") // svc.Run(ctx) // +// // Unix socket (set MCP_UNIX_SOCKET): +// os.Setenv("MCP_UNIX_SOCKET", "/tmp/core-mcp.sock") +// svc.Run(ctx) +// // // HTTP (set MCP_HTTP_ADDR): // os.Setenv("MCP_HTTP_ADDR", "127.0.0.1:9101") // svc.Run(ctx) @@ -726,6 +730,9 @@ func (s *Service) Run(ctx context.Context) error { if addr := core.Env("MCP_ADDR"); addr != "" { return s.ServeTCP(ctx, addr) } + if socketPath := core.Env("MCP_UNIX_SOCKET"); socketPath != "" { + return s.ServeUnix(ctx, socketPath) + } return s.ServeStdio(ctx) } diff --git a/pkg/mcp/transport_unix_test.go b/pkg/mcp/transport_unix_test.go new file mode 100644 index 0000000..c5446f9 --- /dev/null +++ b/pkg/mcp/transport_unix_test.go @@ -0,0 +1,47 @@ +package mcp + +import ( + "context" + "net" + "testing" + "time" +) + +func TestRun_Good_UnixTrigger(t *testing.T) { + s, err := New(Options{}) + if err != nil { + t.Fatalf("Failed to create service: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + socketPath := shortSocketPath(t, "run") + t.Setenv("MCP_UNIX_SOCKET", socketPath) + t.Setenv("MCP_HTTP_ADDR", "") + t.Setenv("MCP_ADDR", "") + + errCh := make(chan error, 1) + go func() { + errCh <- s.Run(ctx) + }() + + var conn net.Conn + deadline := time.Now().Add(2 * time.Second) + for time.Now().Before(deadline) { + conn, err = net.DialTimeout("unix", socketPath, 200*time.Millisecond) + if err == nil { + break + } + time.Sleep(50 * time.Millisecond) + } + if err != nil { + t.Fatalf("Failed to connect to Unix socket at %s: %v", socketPath, err) + } + conn.Close() + + cancel() + if err := <-errCh; err != nil { + t.Fatalf("Run failed: %v", err) + } +}