commit c00bb0b7b44459c09cbf9c3507aca04cecb1b778 Author: 张献维 Date: Wed May 14 16:22:50 2025 +0800 初始化 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96c142f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/go.sum +/.idea/ diff --git a/client/main.go b/client/main.go new file mode 100644 index 0000000..603879e --- /dev/null +++ b/client/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + mcp "github.com/metoro-io/mcp-golang" + "github.com/metoro-io/mcp-golang/transport/stdio" + "log" + "os" + "os/exec" +) + +// CalculateArgs Define type-safe arguments +type CalculateArgs struct { + Operation string `json:"operation"` + A int `json:"a"` + B int `json:"b"` +} + +func main() { + cmd := exec.Command("go", "run", "./server/main.go") + stdin, err := cmd.StdinPipe() + if err != nil { + log.Fatalf("Failed to get stdin pipe: %v", err) + } + stdout, err := cmd.StdoutPipe() + if err != nil { + log.Fatalf("Failed to get stdout pipe: %v", err) + } + + if err := cmd.Start(); err != nil { + log.Fatalf("Failed to start server: %v", err) + } + defer func(Process *os.Process) { + err := Process.Kill() + if err != nil { + log.Fatalf("Failed to kill server: %v", err) + } + }(cmd.Process) + // Create and initialize client + transport := stdio.NewStdioServerTransportWithIO(stdout, stdin) + client := mcp.NewClient(transport) + + if _, err := client.Initialize(context.Background()); err != nil { + log.Fatalf("Failed to initialize: %v", err) + } + + // Call a tool with typed arguments + args := CalculateArgs{ + Operation: "add", + A: 10, + B: 5, + } + + response, err := client.CallTool(context.Background(), "calculate", args) + if err != nil { + log.Fatalf("Failed to call tool: %v", err) + } + + if response != nil && len(response.Content) > 0 { + log.Printf("Result: %s", response.Content[0].TextContent.Text) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0e4492f --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module mcp-golang-demo + +go 1.24.1 + +require github.com/metoro-io/mcp-golang v0.12.0 + +require ( + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..af08209 --- /dev/null +++ b/server/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "github.com/metoro-io/mcp-golang" + "github.com/metoro-io/mcp-golang/transport/stdio" +) + +// Content Tool arguments are just structs, annotated with jsonschema tags +// More at https://mcpgolang.com/tools#schema-generation +type Content struct { + Title string `json:"title" jsonschema:"required,description=The title to submit"` + Description *string `json:"description" jsonschema:"description=The description to submit"` +} +type MyFunctionsArguments struct { + Submitter string `json:"submitter" jsonschema:"required,description=The name of the thing calling this tool (openai, google, claude, etc)"` + Content Content `json:"content" jsonschema:"required,description=The content of the message"` +} + +func main() { + done := make(chan struct{}) + + server := mcp_golang.NewServer(stdio.NewStdioServerTransport()) + err := server.RegisterTool("hello", "Say hello to a person", func(arguments MyFunctionsArguments) (*mcp_golang.ToolResponse, error) { + return mcp_golang.NewToolResponse(mcp_golang.NewTextContent(fmt.Sprintf("Hello, %server!", arguments.Submitter))), nil + }) + if err != nil { + panic(err) + } + + err = server.RegisterPrompt("promt_test", "This is a test prompt", func(arguments Content) (*mcp_golang.PromptResponse, error) { + return mcp_golang.NewPromptResponse("description", mcp_golang.NewPromptMessage(mcp_golang.NewTextContent(fmt.Sprintf("Hello, %server!", arguments.Title)), mcp_golang.RoleUser)), nil + }) + if err != nil { + panic(err) + } + + err = server.RegisterResource("test://resource", "resource_test", "This is a test resource", "application/json", func() (*mcp_golang.ResourceResponse, error) { + return mcp_golang.NewResourceResponse(mcp_golang.NewTextEmbeddedResource("test://resource", "This is a test resource", "application/json")), nil + }) + + err = server.Serve() + if err != nil { + panic(err) + } + + <-done +}