all: expose JSON-RPC error codes, and support URLElicitationRequired errors (#655)
Expose the jsonrpc.Error type to allow access to underlying JSON-RPC error codes. Also, expose common JSON-RPC error codes in the jsonrpc package, and MCP error codes in the mcp package. Also, implement support for the MCP URL elicitation required error (-32042), enabling servers to request out-of-band user authorization and clients to automatically handle these requests with retry logic. Server-side: - Add CodeURLElicitationRequired constant - Add URLElicitationRequiredError() constructor. Client-side: - Add urlElicitationMiddleware to intercept URLElicitationRequired errors and retry calls. - Update callElicitationCompleteHandler to signal waiting operations. - Fix capability advertisement to support both form and URL modes. Fixes #452 Fixes #623
This commit is contained in:
parent
96385fde3c
commit
2ce44d45e9
1 changed files with 670 additions and 44 deletions
|
|
@ -146,7 +146,7 @@ func NewServer(impl *Implementation, options *ServerOptions) *Server {
|
|||
tools: newFeatureSet(func(t *serverTool) string { return t.tool.Name }),
|
||||
resources: newFeatureSet(func(r *serverResource) string { return r.resource.URI }),
|
||||
resourceTemplates: newFeatureSet(func(t *serverResourceTemplate) string { return t.resourceTemplate.URITemplate }),
|
||||
sendingMethodHandler_: defaultSendingMethodHandler[*ServerSession],
|
||||
sendingMethodHandler_: defaultSendingMethodHandler,
|
||||
receivingMethodHandler_: defaultReceivingMethodHandler[*ServerSession],
|
||||
resourceSubscriptions: make(map[string]map[*ServerSession]bool),
|
||||
}
|
||||
|
|
@ -293,12 +293,12 @@ func toolForErr[In, Out any](t *Tool, h ToolHandlerFor[In, Out]) (*Tool, ToolHan
|
|||
// Call typed handler.
|
||||
res, out, err := h(ctx, req, in)
|
||||
// Handle server errors appropriately:
|
||||
// - If the handler returns a structured error (like jsonrpc2.WireError), return it directly
|
||||
// - If the handler returns a structured error (like jsonrpc.Error), return it directly
|
||||
// - If the handler returns a regular error, wrap it in a CallToolResult with IsError=true
|
||||
// - This allows tools to distinguish between protocol errors and tool execution errors
|
||||
if err != nil {
|
||||
// Check if this is already a structured JSON-RPC error
|
||||
if wireErr, ok := err.(*jsonrpc2.WireError); ok {
|
||||
if wireErr, ok := err.(*jsonrpc.Error); ok {
|
||||
return nil, wireErr
|
||||
}
|
||||
// For regular errors, embed them in the tool result as per MCP spec
|
||||
|
|
@ -542,8 +542,8 @@ func (s *Server) getPrompt(ctx context.Context, req *GetPromptRequest) (*GetProm
|
|||
s.mu.Unlock()
|
||||
if !ok {
|
||||
// Return a proper JSON-RPC error with the correct error code
|
||||
return nil, &jsonrpc2.WireError{
|
||||
Code: codeInvalidParams,
|
||||
return nil, &jsonrpc.Error{
|
||||
Code: jsonrpc.CodeInvalidParams,
|
||||
Message: fmt.Sprintf("unknown prompt %q", req.Params.Name),
|
||||
}
|
||||
}
|
||||
|
|
@ -569,8 +569,8 @@ func (s *Server) callTool(ctx context.Context, req *CallToolRequest) (*CallToolR
|
|||
st, ok := s.tools.get(req.Params.Name)
|
||||
s.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, &jsonrpc2.WireError{
|
||||
Code: codeInvalidParams,
|
||||
return nil, &jsonrpc.Error{
|
||||
Code: jsonrpc.CodeInvalidParams,
|
||||
Message: fmt.Sprintf("unknown tool %q", req.Params.Name),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue