// Command nexus is the MCP Nexus control plane binary. // // Subcommands: // // nexus serve Run the aggregating MCP gateway (the control plane). // nexus connect Bridge a local stdio agent to a Nexus gateway endpoint. // nexus demo-mcp Run the built-in demo MCP server over stdio. // nexus version Print version information. package main import ( "context" "flag" "fmt" "log/slog" "os" "os/signal" "syscall" "gitea.thetempleofdoom.com/drjones/mcp-gateway-nexus/internal/app" "gitea.thetempleofdoom.com/drjones/mcp-gateway-nexus/internal/bridge" "gitea.thetempleofdoom.com/drjones/mcp-gateway-nexus/internal/config" "gitea.thetempleofdoom.com/drjones/mcp-gateway-nexus/internal/demomcp" "gitea.thetempleofdoom.com/drjones/mcp-gateway-nexus/internal/version" ) func main() { if len(os.Args) < 2 { usage() os.Exit(2) } cmd := os.Args[1] args := os.Args[2:] var err error switch cmd { case "serve": err = runServe(args) case "connect": err = runConnect(args) case "demo-mcp": err = demomcp.Run(os.Stdin, os.Stdout) case "version", "--version", "-v": fmt.Println("mcp-nexus", version.String()) case "help", "-h", "--help": usage() default: fmt.Fprintf(os.Stderr, "unknown command %q\n\n", cmd) usage() os.Exit(2) } if err != nil { fmt.Fprintln(os.Stderr, "error:", err) os.Exit(1) } } func runServe(args []string) error { fs := flag.NewFlagSet("serve", flag.ExitOnError) cfgPath := fs.String("config", "config.yaml", "path to config file") logFormat := fs.String("log", "text", "log format: text|json") _ = fs.Parse(args) log := newLogger(*logFormat) cfg, err := config.Load(*cfgPath) if err != nil { return err } if cfg.Gateway.Version == "" { cfg.Gateway.Version = version.Version } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() return app.Serve(ctx, cfg, log) } func runConnect(args []string) error { fs := flag.NewFlagSet("connect", flag.ExitOnError) url := fs.String("url", "http://localhost:8080/mcp", "Nexus gateway MCP endpoint") _ = fs.Parse(args) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() return bridge.Run(ctx, *url, os.Stdin, os.Stdout) } func newLogger(format string) *slog.Logger { // Logs go to stderr so stdio-transport subcommands keep stdout clean. var h slog.Handler if format == "json" { h = slog.NewJSONHandler(os.Stderr, nil) } else { h = slog.NewTextHandler(os.Stderr, nil) } return slog.New(h) } func usage() { fmt.Fprint(os.Stderr, `mcp-nexus — the control plane for MCP Usage: nexus serve [-config config.yaml] [-log text|json] Run the aggregating MCP gateway nexus connect [-url http://localhost:8080/mcp] Bridge a local stdio agent to a gateway nexus demo-mcp Run the built-in demo MCP server (stdio) nexus version Print version `) }