package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/ThinkInAIXYZ/go-mcp/protocol"
"github.com/ThinkInAIXYZ/go-mcp/server"
"github.com/ThinkInAIXYZ/go-mcp/transport"
)
type currentTimeReq struct {
}
var srv *server.Server
func main() {
var err error
stateMode := "stateful"
addr := "127.0.0.1:8080"
log.Printf("start current time mcp server with streamable_http transport, listen %s", addr)
opts := transport.WithStreamableHTTPServerTransportOptionStateMode(transport.StateMode(stateMode))
t := transport.NewStreamableHTTPServerTransport(addr, opts)
srv, err = server.NewServer(
t,
server.WithServerInfo(protocol.Implementation{
Name: "current-time-v2-server",
Version: "1.0.0",
}),
)
if err != nil {
log.Fatalf("Failed to create server: %v", err)
}
tool1, err := protocol.NewTool("current_time", "Get current time with timezone, Asia/Shanghai is default", currentTimeReq{})
if err != nil {
log.Fatalf("Failed to create tool: %v", err)
return
}
srv.RegisterTool(tool1, currentTime)
errCh := make(chan error)
go func() {
errCh <- srv.Run()
}()
if err = signalWaiter(errCh); err != nil {
log.Fatalf("signal waiter: %v", err)
return
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("Shutdown error: %v", err)
}
}
func currentTime(ctx context.Context, request *protocol.CallToolRequest) (*protocol.CallToolResult, error) {
text := fmt.Sprintf(`%s`, time.Now().Format(time.DateTime))
return &protocol.CallToolResult{
Content: []protocol.Content{
&protocol.TextContent{
Type: "text",
Text: text,
},
},
}, nil
}
func signalWaiter(errCh chan error) error {
signalToNotify := []os.Signal{syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM}
if signal.Ignored(syscall.SIGHUP) {
signalToNotify = []os.Signal{syscall.SIGINT, syscall.SIGTERM}
}
signals := make(chan os.Signal, 1)
signal.Notify(signals, signalToNotify...)
select {
case sig := <-signals:
switch sig {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM:
log.Printf("Received signal: %s\n", sig)
// graceful shutdown
return nil
}
case err := <-errCh:
return err
}
return nil
}