server.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package mcpservers
  2. import (
  3. "context"
  4. "encoding/json"
  5. "runtime"
  6. "github.com/bytedance/sonic"
  7. "github.com/bytedance/sonic/ast"
  8. "github.com/mark3labs/mcp-go/client/transport"
  9. "github.com/mark3labs/mcp-go/mcp"
  10. )
  11. type Server interface {
  12. HandleMessage(ctx context.Context, message json.RawMessage) mcp.JSONRPCMessage
  13. }
  14. type client2Server struct {
  15. client transport.Interface
  16. }
  17. func (s *client2Server) HandleMessage(
  18. ctx context.Context,
  19. message json.RawMessage,
  20. ) mcp.JSONRPCMessage {
  21. methodNode, err := sonic.GetWithOptions(message, ast.SearchOptions{}, "method")
  22. if err != nil {
  23. return CreateMCPErrorResponse(nil, mcp.PARSE_ERROR, err.Error())
  24. }
  25. method, err := methodNode.String()
  26. if err != nil {
  27. return CreateMCPErrorResponse(nil, mcp.PARSE_ERROR, err.Error())
  28. }
  29. switch method {
  30. case "notifications/initialized":
  31. req := mcp.JSONRPCNotification{}
  32. err := sonic.Unmarshal(message, &req)
  33. if err != nil {
  34. return CreateMCPErrorResponse(nil, mcp.PARSE_ERROR, err.Error())
  35. }
  36. err = s.client.SendNotification(ctx, req)
  37. if err != nil {
  38. return CreateMCPErrorResponse(nil, mcp.PARSE_ERROR, err.Error())
  39. }
  40. return nil
  41. default:
  42. req := transport.JSONRPCRequest{}
  43. err := sonic.Unmarshal(message, &req)
  44. if err != nil {
  45. return CreateMCPErrorResponse(nil, mcp.PARSE_ERROR, err.Error())
  46. }
  47. resp, err := s.client.SendRequest(ctx, req)
  48. if err != nil {
  49. return CreateMCPErrorResponse(nil, mcp.INTERNAL_ERROR, err.Error())
  50. }
  51. if resp.Error != nil {
  52. return CreateMCPErrorResponse(
  53. resp.ID,
  54. resp.Error.Code,
  55. resp.Error.Message,
  56. resp.Error.Data,
  57. )
  58. }
  59. return CreateMCPResultResponse(
  60. resp.ID,
  61. resp.Result,
  62. )
  63. }
  64. }
  65. func WrapMCPClient2Server(client transport.Interface) Server {
  66. return &client2Server{client: client}
  67. }
  68. func WrapMCPClient2ServerWithCleanup(client transport.Interface) Server {
  69. server := &client2Server{client: client}
  70. _ = runtime.AddCleanup(server, func(client transport.Interface) {
  71. _ = client.Close()
  72. }, server.client)
  73. return server
  74. }
  75. type JSONRPCNoErrorResponse struct {
  76. JSONRPC string `json:"jsonrpc"`
  77. ID mcp.RequestId `json:"id"`
  78. Result json.RawMessage `json:"result"`
  79. }
  80. func CreateMCPResultResponse(
  81. id any,
  82. result json.RawMessage,
  83. ) mcp.JSONRPCMessage {
  84. return &JSONRPCNoErrorResponse{
  85. JSONRPC: mcp.JSONRPC_VERSION,
  86. ID: mcp.NewRequestId(id),
  87. Result: result,
  88. }
  89. }
  90. func CreateMCPErrorResponse(
  91. id any,
  92. code int,
  93. message string,
  94. data ...any,
  95. ) mcp.JSONRPCMessage {
  96. var d any
  97. if len(data) > 0 {
  98. d = data[0]
  99. }
  100. return mcp.JSONRPCError{
  101. JSONRPC: mcp.JSONRPC_VERSION,
  102. ID: mcp.NewRequestId(id),
  103. Error: struct {
  104. Code int `json:"code"`
  105. Message string `json:"message"`
  106. Data any `json:"data,omitempty"`
  107. }{
  108. Code: code,
  109. Message: message,
  110. Data: d,
  111. },
  112. }
  113. }