feat(mcp): auto-select unix socket transport
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
e09f3518e0
commit
8e77c5e58d
3 changed files with 62 additions and 3 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
47
pkg/mcp/transport_unix_test.go
Normal file
47
pkg/mcp/transport_unix_test.go
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue