// aio-mcp:aio-system 的自定义 MCP 服务器。 // // 作为 AI Agent 的「手」,以 MCP 协议对外暴露工具。 // 默认以 stdio 传输运行(本地 Agent 直接拉起),也可切换为 // streamable HTTP 供远程客户端访问。 package main import ( "context" "flag" "fmt" "log/slog" "net/http" "os" "github.com/modelcontextprotocol/go-sdk/mcp" "aio-mcp/internal/server" ) // version 可用 -ldflags "-X main.version=..." 在构建时覆盖。 var version = "0.1.0" func main() { transport := flag.String("transport", "stdio", "传输方式:stdio(默认,供本地 Agent 拉起)或 http") addr := flag.String("addr", "localhost:8000", "http 模式下的监听地址") flag.Parse() // 日志统一走 stderr:stdio 模式下 stdout 是 MCP 协议通道,绝不能混入日志。 slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil))) svr := server.New(version) switch *transport { case "stdio": slog.Info("aio-mcp starting", "transport", "stdio") // server.Run 会阻塞,直到 stdin 关闭或出错。 if err := svr.Run(context.Background(), &mcp.StdioTransport{}); err != nil { slog.Error("stdio server failed", "err", err) os.Exit(1) } case "http": handler := mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server { return svr }, nil) slog.Info("aio-mcp starting", "transport", "http", "addr", *addr) if err := http.ListenAndServe(*addr, handler); err != nil { slog.Error("http server failed", "err", err) os.Exit(1) } default: fmt.Fprintf(os.Stderr, "未知 transport: %q(支持: stdio, http)\n", *transport) os.Exit(2) } }