request_handler.go

  1// Code generated by `go generate`. DO NOT EDIT.
  2// source: server/internal/gen/request_handler.go.tmpl
  3package server
  4
  5import (
  6	"context"
  7	"encoding/json"
  8	"fmt"
  9
 10	"github.com/mark3labs/mcp-go/mcp"
 11)
 12
 13// HandleMessage processes an incoming JSON-RPC message and returns an appropriate response
 14func (s *MCPServer) HandleMessage(
 15	ctx context.Context,
 16	message json.RawMessage,
 17) mcp.JSONRPCMessage {
 18	// Add server to context
 19	ctx = context.WithValue(ctx, serverKey{}, s)
 20	var err *requestError
 21
 22	var baseMessage struct {
 23		JSONRPC string        `json:"jsonrpc"`
 24		Method  mcp.MCPMethod `json:"method"`
 25		ID      any           `json:"id,omitempty"`
 26		Result  any           `json:"result,omitempty"`
 27	}
 28
 29	if err := json.Unmarshal(message, &baseMessage); err != nil {
 30		return createErrorResponse(
 31			nil,
 32			mcp.PARSE_ERROR,
 33			"Failed to parse message",
 34		)
 35	}
 36
 37	// Check for valid JSONRPC version
 38	if baseMessage.JSONRPC != mcp.JSONRPC_VERSION {
 39		return createErrorResponse(
 40			baseMessage.ID,
 41			mcp.INVALID_REQUEST,
 42			"Invalid JSON-RPC version",
 43		)
 44	}
 45
 46	if baseMessage.ID == nil {
 47		var notification mcp.JSONRPCNotification
 48		if err := json.Unmarshal(message, &notification); err != nil {
 49			return createErrorResponse(
 50				nil,
 51				mcp.PARSE_ERROR,
 52				"Failed to parse notification",
 53			)
 54		}
 55		s.handleNotification(ctx, notification)
 56		return nil // Return nil for notifications
 57	}
 58
 59	if baseMessage.Result != nil {
 60		// this is a response to a request sent by the server (e.g. from a ping
 61		// sent due to WithKeepAlive option)
 62		return nil
 63	}
 64
 65	handleErr := s.hooks.onRequestInitialization(ctx, baseMessage.ID, message)
 66	if handleErr != nil {
 67		return createErrorResponse(
 68			baseMessage.ID,
 69			mcp.INVALID_REQUEST,
 70			handleErr.Error(),
 71		)
 72	}
 73
 74	switch baseMessage.Method {
 75	case mcp.MethodInitialize:
 76		var request mcp.InitializeRequest
 77		var result *mcp.InitializeResult
 78		if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
 79			err = &requestError{
 80				id:   baseMessage.ID,
 81				code: mcp.INVALID_REQUEST,
 82				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
 83			}
 84		} else {
 85			s.hooks.beforeInitialize(ctx, baseMessage.ID, &request)
 86			result, err = s.handleInitialize(ctx, baseMessage.ID, request)
 87		}
 88		if err != nil {
 89			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
 90			return err.ToJSONRPCError()
 91		}
 92		s.hooks.afterInitialize(ctx, baseMessage.ID, &request, result)
 93		return createResponse(baseMessage.ID, *result)
 94	case mcp.MethodPing:
 95		var request mcp.PingRequest
 96		var result *mcp.EmptyResult
 97		if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
 98			err = &requestError{
 99				id:   baseMessage.ID,
100				code: mcp.INVALID_REQUEST,
101				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
102			}
103		} else {
104			s.hooks.beforePing(ctx, baseMessage.ID, &request)
105			result, err = s.handlePing(ctx, baseMessage.ID, request)
106		}
107		if err != nil {
108			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
109			return err.ToJSONRPCError()
110		}
111		s.hooks.afterPing(ctx, baseMessage.ID, &request, result)
112		return createResponse(baseMessage.ID, *result)
113	case mcp.MethodSetLogLevel:
114		var request mcp.SetLevelRequest
115		var result *mcp.EmptyResult
116		if s.capabilities.logging == nil {
117			err = &requestError{
118				id:   baseMessage.ID,
119				code: mcp.METHOD_NOT_FOUND,
120				err:  fmt.Errorf("logging %w", ErrUnsupported),
121			}
122		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
123			err = &requestError{
124				id:   baseMessage.ID,
125				code: mcp.INVALID_REQUEST,
126				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
127			}
128		} else {
129			s.hooks.beforeSetLevel(ctx, baseMessage.ID, &request)
130			result, err = s.handleSetLevel(ctx, baseMessage.ID, request)
131		}
132		if err != nil {
133			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
134			return err.ToJSONRPCError()
135		}
136		s.hooks.afterSetLevel(ctx, baseMessage.ID, &request, result)
137		return createResponse(baseMessage.ID, *result)
138	case mcp.MethodResourcesList:
139		var request mcp.ListResourcesRequest
140		var result *mcp.ListResourcesResult
141		if s.capabilities.resources == nil {
142			err = &requestError{
143				id:   baseMessage.ID,
144				code: mcp.METHOD_NOT_FOUND,
145				err:  fmt.Errorf("resources %w", ErrUnsupported),
146			}
147		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
148			err = &requestError{
149				id:   baseMessage.ID,
150				code: mcp.INVALID_REQUEST,
151				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
152			}
153		} else {
154			s.hooks.beforeListResources(ctx, baseMessage.ID, &request)
155			result, err = s.handleListResources(ctx, baseMessage.ID, request)
156		}
157		if err != nil {
158			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
159			return err.ToJSONRPCError()
160		}
161		s.hooks.afterListResources(ctx, baseMessage.ID, &request, result)
162		return createResponse(baseMessage.ID, *result)
163	case mcp.MethodResourcesTemplatesList:
164		var request mcp.ListResourceTemplatesRequest
165		var result *mcp.ListResourceTemplatesResult
166		if s.capabilities.resources == nil {
167			err = &requestError{
168				id:   baseMessage.ID,
169				code: mcp.METHOD_NOT_FOUND,
170				err:  fmt.Errorf("resources %w", ErrUnsupported),
171			}
172		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
173			err = &requestError{
174				id:   baseMessage.ID,
175				code: mcp.INVALID_REQUEST,
176				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
177			}
178		} else {
179			s.hooks.beforeListResourceTemplates(ctx, baseMessage.ID, &request)
180			result, err = s.handleListResourceTemplates(ctx, baseMessage.ID, request)
181		}
182		if err != nil {
183			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
184			return err.ToJSONRPCError()
185		}
186		s.hooks.afterListResourceTemplates(ctx, baseMessage.ID, &request, result)
187		return createResponse(baseMessage.ID, *result)
188	case mcp.MethodResourcesRead:
189		var request mcp.ReadResourceRequest
190		var result *mcp.ReadResourceResult
191		if s.capabilities.resources == nil {
192			err = &requestError{
193				id:   baseMessage.ID,
194				code: mcp.METHOD_NOT_FOUND,
195				err:  fmt.Errorf("resources %w", ErrUnsupported),
196			}
197		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
198			err = &requestError{
199				id:   baseMessage.ID,
200				code: mcp.INVALID_REQUEST,
201				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
202			}
203		} else {
204			s.hooks.beforeReadResource(ctx, baseMessage.ID, &request)
205			result, err = s.handleReadResource(ctx, baseMessage.ID, request)
206		}
207		if err != nil {
208			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
209			return err.ToJSONRPCError()
210		}
211		s.hooks.afterReadResource(ctx, baseMessage.ID, &request, result)
212		return createResponse(baseMessage.ID, *result)
213	case mcp.MethodPromptsList:
214		var request mcp.ListPromptsRequest
215		var result *mcp.ListPromptsResult
216		if s.capabilities.prompts == nil {
217			err = &requestError{
218				id:   baseMessage.ID,
219				code: mcp.METHOD_NOT_FOUND,
220				err:  fmt.Errorf("prompts %w", ErrUnsupported),
221			}
222		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
223			err = &requestError{
224				id:   baseMessage.ID,
225				code: mcp.INVALID_REQUEST,
226				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
227			}
228		} else {
229			s.hooks.beforeListPrompts(ctx, baseMessage.ID, &request)
230			result, err = s.handleListPrompts(ctx, baseMessage.ID, request)
231		}
232		if err != nil {
233			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
234			return err.ToJSONRPCError()
235		}
236		s.hooks.afterListPrompts(ctx, baseMessage.ID, &request, result)
237		return createResponse(baseMessage.ID, *result)
238	case mcp.MethodPromptsGet:
239		var request mcp.GetPromptRequest
240		var result *mcp.GetPromptResult
241		if s.capabilities.prompts == nil {
242			err = &requestError{
243				id:   baseMessage.ID,
244				code: mcp.METHOD_NOT_FOUND,
245				err:  fmt.Errorf("prompts %w", ErrUnsupported),
246			}
247		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
248			err = &requestError{
249				id:   baseMessage.ID,
250				code: mcp.INVALID_REQUEST,
251				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
252			}
253		} else {
254			s.hooks.beforeGetPrompt(ctx, baseMessage.ID, &request)
255			result, err = s.handleGetPrompt(ctx, baseMessage.ID, request)
256		}
257		if err != nil {
258			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
259			return err.ToJSONRPCError()
260		}
261		s.hooks.afterGetPrompt(ctx, baseMessage.ID, &request, result)
262		return createResponse(baseMessage.ID, *result)
263	case mcp.MethodToolsList:
264		var request mcp.ListToolsRequest
265		var result *mcp.ListToolsResult
266		if s.capabilities.tools == nil {
267			err = &requestError{
268				id:   baseMessage.ID,
269				code: mcp.METHOD_NOT_FOUND,
270				err:  fmt.Errorf("tools %w", ErrUnsupported),
271			}
272		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
273			err = &requestError{
274				id:   baseMessage.ID,
275				code: mcp.INVALID_REQUEST,
276				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
277			}
278		} else {
279			s.hooks.beforeListTools(ctx, baseMessage.ID, &request)
280			result, err = s.handleListTools(ctx, baseMessage.ID, request)
281		}
282		if err != nil {
283			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
284			return err.ToJSONRPCError()
285		}
286		s.hooks.afterListTools(ctx, baseMessage.ID, &request, result)
287		return createResponse(baseMessage.ID, *result)
288	case mcp.MethodToolsCall:
289		var request mcp.CallToolRequest
290		var result *mcp.CallToolResult
291		if s.capabilities.tools == nil {
292			err = &requestError{
293				id:   baseMessage.ID,
294				code: mcp.METHOD_NOT_FOUND,
295				err:  fmt.Errorf("tools %w", ErrUnsupported),
296			}
297		} else if unmarshalErr := json.Unmarshal(message, &request); unmarshalErr != nil {
298			err = &requestError{
299				id:   baseMessage.ID,
300				code: mcp.INVALID_REQUEST,
301				err:  &UnparsableMessageError{message: message, err: unmarshalErr, method: baseMessage.Method},
302			}
303		} else {
304			s.hooks.beforeCallTool(ctx, baseMessage.ID, &request)
305			result, err = s.handleToolCall(ctx, baseMessage.ID, request)
306		}
307		if err != nil {
308			s.hooks.onError(ctx, baseMessage.ID, baseMessage.Method, &request, err)
309			return err.ToJSONRPCError()
310		}
311		s.hooks.afterCallTool(ctx, baseMessage.ID, &request, result)
312		return createResponse(baseMessage.ID, *result)
313	default:
314		return createErrorResponse(
315			baseMessage.ID,
316			mcp.METHOD_NOT_FOUND,
317			fmt.Sprintf("Method %s not found", baseMessage.Method),
318		)
319	}
320}