Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add tool annotations
  • Loading branch information
mattt committed Aug 14, 2025
commit 8fe3b7e45448c211e2bb09236ba3396cef0e4d69
36 changes: 36 additions & 0 deletions internal/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ func RegisterTools(server *mcp.Server, specData []byte, client *http.Client) err
addParamToSchema(schema, param)
}
}

// Operation parameters
if op.op.Parameters != nil {
for _, param := range op.op.Parameters {
addParamToSchema(schema, param)
}
}

// Request body (application/json)
if op.op.RequestBody != nil && op.op.RequestBody.Content != nil {
if mediaType, ok := op.op.RequestBody.Content.Get("application/json"); ok && mediaType != nil {
Expand All @@ -115,10 +117,44 @@ func RegisterTools(server *mcp.Server, specData []byte, client *http.Client) err
}
}

// Derive MCP ToolAnnotations from REST conventions
title := op.op.Summary
if title == "" {
title = fmt.Sprintf("%s %s", op.method, p)
}
openWorld := true
destructiveTrue := true
ann := &mcp.ToolAnnotations{
Title: title,
OpenWorldHint: &openWorld,
}
switch op.method {
case "GET":
ann.ReadOnlyHint = true
ann.IdempotentHint = true
case "POST":
ann.ReadOnlyHint = false
ann.IdempotentHint = false
ann.DestructiveHint = &destructiveTrue
case "PUT":
ann.ReadOnlyHint = false
ann.IdempotentHint = true
ann.DestructiveHint = &destructiveTrue
case "PATCH":
ann.ReadOnlyHint = false
ann.IdempotentHint = false
ann.DestructiveHint = &destructiveTrue
case "DELETE":
ann.ReadOnlyHint = false
ann.IdempotentHint = true
ann.DestructiveHint = &destructiveTrue
}

tool := &mcp.Tool{
Name: toolName,
Description: desc,
InputSchema: schema,
Annotations: ann,
}

// Capture for handler
Expand Down