@@ -180,6 +180,158 @@ func generateAI400ErrorResponse(op OpenAPIOperation, inputSchemaJSON []byte, arg
180180 return response .String ()
181181}
182182
183+ // generateAIFriendlyDescription creates a comprehensive, AI-optimized description for an operation
184+ // that includes all the information an AI agent needs to understand how to use the tool.
185+ func generateAIFriendlyDescription (op OpenAPIOperation , inputSchema map [string ]any , apiKeyHeader string ) string {
186+ var desc strings.Builder
187+
188+ // Start with the original description or summary
189+ if op .Description != "" {
190+ desc .WriteString (op .Description )
191+ } else if op .Summary != "" {
192+ desc .WriteString (op .Summary )
193+ }
194+
195+ // Add HTTP method and path info
196+ desc .WriteString (fmt .Sprintf ("\n \n HTTP: %s %s" , strings .ToUpper (op .Method ), op .Path ))
197+
198+ // Add authentication requirements if any
199+ if len (op .Security ) > 0 {
200+ desc .WriteString ("\n \n AUTHENTICATION: " )
201+ var authMethods []string
202+ for _ , secReq := range op .Security {
203+ for schemeName := range secReq {
204+ authMethods = append (authMethods , schemeName )
205+ }
206+ }
207+ desc .WriteString ("Required (" + strings .Join (authMethods , " OR " ) + "). " )
208+ desc .WriteString ("Set environment variables: API_KEY, BEARER_TOKEN, or BASIC_AUTH" )
209+ }
210+
211+ // Extract required parameters first
212+ var requiredParams []string
213+ switch req := inputSchema ["required" ].(type ) {
214+ case []any :
215+ for _ , r := range req {
216+ if str , ok := r .(string ); ok {
217+ requiredParams = append (requiredParams , str )
218+ }
219+ }
220+ case []string :
221+ requiredParams = req
222+ }
223+
224+ // Add parameter information with examples
225+ if properties , ok := inputSchema ["properties" ].(map [string ]any ); ok && len (properties ) > 0 {
226+ desc .WriteString ("\n \n PARAMETERS:" )
227+
228+ if len (requiredParams ) > 0 {
229+ desc .WriteString ("\n • Required:" )
230+ for _ , reqStr := range requiredParams {
231+ if prop , ok := properties [reqStr ].(map [string ]any ); ok {
232+ desc .WriteString (fmt .Sprintf ("\n - %s" , reqStr ))
233+ if typeStr , ok := prop ["type" ].(string ); ok {
234+ desc .WriteString (fmt .Sprintf (" (%s)" , typeStr ))
235+ }
236+ if propDesc , ok := prop ["description" ].(string ); ok && propDesc != "" {
237+ desc .WriteString (": " + propDesc )
238+ }
239+ // Add enum values if present
240+ if enum , ok := prop ["enum" ].([]any ); ok && len (enum ) > 0 {
241+ var enumStrs []string
242+ for _ , e := range enum {
243+ enumStrs = append (enumStrs , fmt .Sprintf ("%v" , e ))
244+ }
245+ desc .WriteString (" [values: " + strings .Join (enumStrs , ", " ) + "]" )
246+ }
247+ }
248+ }
249+ }
250+
251+ // Optional parameters
252+ var optionalParams []string
253+ for paramName , paramDef := range properties {
254+ isRequired := false
255+ for _ , reqParam := range requiredParams {
256+ if reqParam == paramName {
257+ isRequired = true
258+ break
259+ }
260+ }
261+ if ! isRequired {
262+ if prop , ok := paramDef .(map [string ]any ); ok {
263+ paramInfo := fmt .Sprintf (" - %s" , paramName )
264+ if typeStr , ok := prop ["type" ].(string ); ok {
265+ paramInfo += fmt .Sprintf (" (%s)" , typeStr )
266+ }
267+ if propDesc , ok := prop ["description" ].(string ); ok && propDesc != "" {
268+ paramInfo += ": " + propDesc
269+ }
270+ if enum , ok := prop ["enum" ].([]any ); ok && len (enum ) > 0 {
271+ var enumStrs []string
272+ for _ , e := range enum {
273+ enumStrs = append (enumStrs , fmt .Sprintf ("%v" , e ))
274+ }
275+ paramInfo += " [values: " + strings .Join (enumStrs , ", " ) + "]"
276+ }
277+ optionalParams = append (optionalParams , paramInfo )
278+ }
279+ }
280+ }
281+ if len (optionalParams ) > 0 {
282+ desc .WriteString ("\n • Optional:" )
283+ for _ , param := range optionalParams {
284+ desc .WriteString ("\n " + param )
285+ }
286+ }
287+ }
288+
289+ // Add example usage
290+ desc .WriteString ("\n \n EXAMPLE: call " + op .OperationID + " " )
291+ exampleArgs := make (map [string ]any )
292+
293+ // Generate example based on actual parameters
294+ if properties , ok := inputSchema ["properties" ].(map [string ]any ); ok {
295+ // Add required parameters to example
296+ for _ , reqStr := range requiredParams {
297+ if prop , ok := properties [reqStr ].(map [string ]any ); ok {
298+ exampleArgs [reqStr ] = generateExampleValue (prop )
299+ }
300+ }
301+ // Add one or two optional parameters to show structure
302+ count := 0
303+ for paramName , paramDef := range properties {
304+ if _ , exists := exampleArgs [paramName ]; ! exists && count < 2 {
305+ if prop , ok := paramDef .(map [string ]any ); ok {
306+ // Skip adding optional params if there are already many required ones
307+ if len (exampleArgs ) < 3 {
308+ exampleArgs [paramName ] = generateExampleValue (prop )
309+ count ++
310+ }
311+ }
312+ }
313+ }
314+ }
315+
316+ exampleJSON , _ := json .Marshal (exampleArgs )
317+ desc .WriteString (string (exampleJSON ))
318+
319+ // Add response format info
320+ if op .Method == "get" || op .Method == "post" || op .Method == "put" {
321+ desc .WriteString ("\n \n RESPONSE: Returns HTTP status, headers, and response body. " )
322+ desc .WriteString ("Success responses (2xx) return the data. " )
323+ desc .WriteString ("Error responses include troubleshooting guidance." )
324+ }
325+
326+ // Add safety note for dangerous operations
327+ if op .Method == "delete" || op .Method == "put" || op .Method == "post" {
328+ desc .WriteString ("\n \n ⚠️ SAFETY: This operation modifies data. " )
329+ desc .WriteString ("You will be asked to confirm before execution." )
330+ }
331+
332+ return desc .String ()
333+ }
334+
183335// generateExampleValue creates appropriate example values based on the parameter schema
184336func generateExampleValue (prop map [string ]any ) any {
185337 typeStr , _ := prop ["type" ].(string )
@@ -516,10 +668,8 @@ func RegisterOpenAPITools(server *mcpserver.MCPServer, ops []OpenAPIOperation, d
516668 inputSchema = opts .PostProcessSchema (op .OperationID , inputSchema )
517669 }
518670 inputSchemaJSON , _ := json .MarshalIndent (inputSchema , "" , " " )
519- desc := op .Description
520- if desc == "" {
521- desc = op .Summary
522- }
671+ // Generate AI-friendly description
672+ desc := generateAIFriendlyDescription (op , inputSchema , apiKeyHeader )
523673 name := op .OperationID
524674 if opts != nil && opts .NameFormat != nil {
525675 name = opts .NameFormat (name )
0 commit comments