Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 15, 2025

MCP Configuration Error Message Improvements ✅

Successfully improved all MCP (Model Context Protocol) configuration error messages to follow the error message style guide's three-part template: what's wrong + what's expected + example.

Summary of Changes

Files Modified

  1. pkg/workflow/mcp-config.go - 4 error messages improved and reformatted
  2. pkg/parser/mcp.go - 11 error messages improved and reformatted
  3. pkg/workflow/mcp_error_messages_test.go - Comprehensive test suite (380+ lines)

Recent Updates (Latest Commit)

  • ✅ Merged main branch
  • ✅ Reformatted long error message lines for better code readability
  • ✅ Split error messages across multiple lines with proper concatenation
  • ✅ Maintained three-part template structure in all messages
  • ✅ All tests pass
  • ✅ Linting passes

Error Messages Enhanced

pkg/workflow/mcp-config.go:

  • ✅ Unknown property - Lists all valid properties with example (reformatted)
  • ✅ Unable to determine MCP type - Explains required fields with example (reformatted)
  • ✅ HTTP missing url - Shows complete HTTP MCP configuration example (reformatted)
  • ✅ Unsupported MCP type - Lists valid types with example (reformatted)

pkg/parser/mcp.go:

  • ✅ Invalid mcp-servers section type - Shows received type (%T) and example
  • ✅ Invalid mcp configuration format - Shows received type and example
  • ✅ Type field must be string - Shows received type, lists valid types, provides example
  • ✅ Unable to determine MCP type - Explains required fields with example
  • ✅ Registry must be string - Shows received type and registry example
  • ✅ Command must be string - Shows received type and example
  • ✅ stdio requires command or container - Explains mutual exclusivity with both examples (reformatted)
  • ✅ url must be string - Shows received type and HTTP example (reformatted)
  • ✅ http missing url - Shows complete HTTP example with headers (reformatted)
  • ✅ Unsupported MCP type - Lists valid types with example

Key Improvements

  1. Type Information: All type validation errors show received type using %T
  2. Valid Options: Errors list all valid options (properties, types, fields)
  3. YAML Examples: Multi-line YAML examples with proper formatting
  4. Tool Names: Examples personalized with actual tool names
  5. Mutual Exclusivity: command vs container choice explained with both examples
  6. Complete Configuration: Examples show realistic, complete configurations
  7. Code Readability: Long error messages split across multiple lines for better readability

Testing

All tests continue to pass:

=== RUN   TestMCPErrorMessageQuality
--- PASS: TestMCPErrorMessageQuality (0.00s)
=== RUN   TestParserMCPErrorMessageQuality  
--- PASS: TestParserMCPErrorMessageQuality (0.00s)
=== RUN   TestMCPErrorMessageStructure
--- PASS: TestMCPErrorMessageStructure (0.00s)

Verification

  • ✅ All unit tests pass (10.8s total)
  • ✅ Build succeeds without errors
  • ✅ Linting passes
  • ✅ Main branch merged successfully
  • ✅ Error messages tested and verified
  • ✅ Follows error message style guide
  • ✅ Code is more readable with proper line breaks
Original prompt

This section details on the original issue you should resolve

<issue_title>[task] Improve MCP configuration error messages with YAML examples</issue_title>
<issue_description>## Objective
Enhance MCP (Model Context Protocol) configuration validation errors to provide clear YAML examples and explain valid configuration options. MCP errors are particularly important as they involve complex nested YAML structures.

Context

Part of discussion #4046 - Workflow Error Message Quality improvement initiative. MCP configuration errors are especially confusing for users because they involve complex multi-line YAML structures. Clear examples will significantly reduce setup friction.

Approach

Follow the excellent MCP error examples documented in .github/instructions/error-messages.instructions.md.

Reference Pattern

// ✅ Example to follow
return fmt.Errorf("tool '%s' mcp configuration must specify either 'command' or 'container'. Example:\ntools:\n  %s:\n    command: \"npx `@my/tool`\"", toolName, toolName)

Improvements Needed

  1. Missing required field errors - Show complete valid example
  2. Type validation errors - Show received type and expected type using %T
  3. Invalid property errors - List valid properties
  4. Multi-line YAML examples - Properly format with \n
  5. Mutual exclusivity errors - Explain command vs container choice clearly

Files to Modify

  • Update: pkg/workflow/mcp-config.go - Tool configuration validation
  • Update: pkg/parser/mcp.go - MCP schema parsing errors

Acceptance Criteria

  • Missing required field errors show complete valid example
  • Type validation errors show received type (%T) and expected type
  • Invalid property errors list all valid properties
  • Multi-line YAML examples are properly formatted with \n
  • Errors explain mutual exclusivity (command vs container)
  • Tool name is used in examples when available for personalization
  • Each error follows three-part template (what's wrong + expected + example)

Example Improvements

// Current (vague)
return fmt.Errorf("invalid MCP configuration")

// Target (actionable)
return fmt.Errorf("invalid MCP configuration for tool '%s': missing required 'command' or 'container' field. Example:\nmcp-servers:\n  %s:\n    command: \"npx `@my/tool`\"\n    args: [\"--port\", \"3000\"]", toolName, toolName)

References

AI generated by Plan Command for discussion #4046</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Enhanced error messages in pkg/workflow/mcp-config.go and pkg/parser/mcp.go to follow the three-part template (what's wrong + expected + example) as specified in the error message style guide.

Changes:
- Unknown property errors now list all valid properties with examples
- Missing required field errors explain options and show complete YAML examples
- Type validation errors show received type using %T and expected types
- Mutual exclusivity errors (command vs container) explain both options with examples
- HTTP MCP errors clearly explain required url field with examples
- Unsupported type errors list valid types with examples
- All examples use proper multi-line YAML formatting with \n

Added comprehensive test suite in mcp_error_messages_test.go that verifies:
- All error messages contain what's wrong, expected format, and examples
- Error messages include tool names for personalization
- YAML examples have proper structure and formatting
- Type mismatches show both received and expected types

All existing tests continue to pass.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance MCP configuration validation error messages with YAML examples Improve MCP configuration error messages with YAML examples and type information Nov 15, 2025
Copilot AI requested a review from pelikhan November 15, 2025 17:42
Copilot finished work on behalf of pelikhan November 15, 2025 17:42
@pelikhan pelikhan marked this pull request as ready for review November 15, 2025 17:46
Copilot AI review requested due to automatic review settings November 15, 2025 17:47
Copilot finished reviewing on behalf of pelikhan November 15, 2025 17:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances MCP (Model Context Protocol) configuration validation error messages to provide actionable guidance with complete YAML examples, type information, and comprehensive explanations. The improvements address user confusion when configuring complex MCP server setups by following a three-part template: what's wrong → what's expected → working example.

Key Changes:

  • Error messages now include complete lists of valid properties/types when validation fails
  • Type mismatches show both received and expected types using %T format specifier
  • Multi-line YAML examples with proper formatting demonstrate correct configuration
  • Examples are personalized with actual tool names from the context
  • Mutual exclusivity (command vs container) is explained with examples for both options

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
pkg/workflow/mcp_error_messages_test.go New comprehensive test suite (412 lines) validating error message quality, structure, and three-part template compliance for MCP configuration errors
pkg/workflow/mcp-config.go Enhanced 4 error messages with valid property lists, type information, and multi-line YAML examples for unknown properties, missing type determination, HTTP URL requirements, and unsupported types
pkg/parser/mcp.go Improved 11 error messages with type information (%T), YAML examples, and detailed explanations for format validation, type checking, stdio/http requirements, and field validation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
default:
return nil, fmt.Errorf("unsupported MCP type '%s' for tool '%s'", result.Type, toolName)
return nil, fmt.Errorf("unsupported MCP type '%s' for tool '%s'. Valid types are: stdio, http. Example:\nmcp-servers:\n %s:\n type: stdio\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]", result.Type, toolName, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits. Consider breaking it into multiple lines for better code readability.

Suggested formatting:

return nil, fmt.Errorf("unsupported MCP type '%s' for tool '%s'. Valid types are: stdio, http. "+
    "Example:\nmcp-servers:\n  %s:\n    type: stdio\n    command: \"npx @my/tool\"\n"+
    "    args: [\"--port\", \"3000\"]", result.Type, toolName, toolName)
Suggested change
return nil, fmt.Errorf("unsupported MCP type '%s' for tool '%s'. Valid types are: stdio, http. Example:\nmcp-servers:\n %s:\n type: stdio\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]", result.Type, toolName, toolName)
return nil, fmt.Errorf(
"unsupported MCP type '%s' for tool '%s'. Valid types are: stdio, http. "+
"Example:\n"+
"mcp-servers:\n"+
" %s:\n"+
" type: stdio\n"+
" command: \"npx @my/tool\"\n"+
" args: [\"--port\", \"3000\"]",
result.Type, toolName, toolName)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit d57732e. Error message now split across multiple lines with proper concatenation for better readability.

mcpLog.Printf("Inferred MCP type as stdio (has container field)")
} else {
return nil, fmt.Errorf("unable to determine MCP type for tool '%s': missing type, url, command, or container", toolName)
return nil, fmt.Errorf("unable to determine MCP type for tool '%s': missing type, url, command, or container. Must specify one of: 'type' (stdio/http), 'url' (for HTTP MCP), 'command' (for command-based), or 'container' (for Docker-based). Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]", toolName, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits. Consider breaking it into multiple lines for better code readability.

Suggested formatting:

return nil, fmt.Errorf("unable to determine MCP type for tool '%s': missing type, url, command, or container. "+
    "Must specify one of: 'type' (stdio/http), 'url' (for HTTP MCP), 'command' (for command-based), or 'container' (for Docker-based). "+
    "Example:\nmcp-servers:\n  %s:\n    command: \"npx @my/tool\"\n    args: [\"--port\", \"3000\"]", toolName, toolName)
Suggested change
return nil, fmt.Errorf("unable to determine MCP type for tool '%s': missing type, url, command, or container. Must specify one of: 'type' (stdio/http), 'url' (for HTTP MCP), 'command' (for command-based), or 'container' (for Docker-based). Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]", toolName, toolName)
return nil, fmt.Errorf(
"unable to determine MCP type for tool '%s': missing type, url, command, or container. "+
"Must specify one of: 'type' (stdio/http), 'url' (for HTTP MCP), 'command' (for command-based), or 'container' (for Docker-based). "+
"Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]",
toolName, toolName,
)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit d57732e. Error message reformatted with proper line breaks.

for prop := range knownProperties {
validProps = append(validProps, prop)
}
sort.Strings(validProps)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import: This code uses sort.Strings() but the sort package import is not added to the file. Add "sort" to the imports at the top of the file.

import (
    "sort"
    "strings"
    // ... other imports
)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sort package import was already present in the file after merging main. No changes needed.

validProps = append(validProps, prop)
}
sort.Strings(validProps)
return nil, fmt.Errorf("unknown property '%s' in MCP configuration for tool '%s'. Valid properties are: %s. Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]",
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect string escaping: The backticks in \"npx @my/tool\" are unnecessary and will appear literally in the error message. The @ symbol doesn't need to be escaped in a regular string.

Remove the backticks:

return nil, fmt.Errorf("unknown property '%s' in MCP configuration for tool '%s'. Valid properties are: %s. Example:\nmcp-servers:\n  %s:\n    command: \"npx @my/tool\"\n    args: [\"--port\", \"3000\"]", 
    key, toolName, strings.Join(validProps, ", "), toolName)
Suggested change
return nil, fmt.Errorf("unknown property '%s' in MCP configuration for tool '%s'. Valid properties are: %s. Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]",
return nil, fmt.Errorf("unknown property '%s' in MCP configuration for tool '%s'. Valid properties are: %s. Example:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]",

Copilot uses AI. Check for mistakes.
}
} else {
return config, fmt.Errorf("stdio type requires 'command' or 'container' field")
return config, fmt.Errorf("stdio MCP tool '%s' must specify either 'command' or 'container' field. Cannot specify both. Example with command:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]\n\nExample with container:\nmcp-servers:\n %s:\n container: \"myorg/my-tool:latest\"\n env:\n API_KEY: \"${{ secrets.API_KEY }}\"", toolName, toolName, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits (appears to be ~350+ characters). While the content is valuable, consider breaking it into multiple lines for better readability in the code.

Suggested formatting:

return config, fmt.Errorf("stdio MCP tool '%s' must specify either 'command' or 'container' field. Cannot specify both. "+
    "Example with command:\nmcp-servers:\n  %s:\n    command: \"npx @my/tool\"\n    args: [\"--port\", \"3000\"]\n\n"+
    "Example with container:\nmcp-servers:\n  %s:\n    container: \"myorg/my-tool:latest\"\n    env:\n      API_KEY: \"${{ secrets.API_KEY }}\"", 
    toolName, toolName, toolName)
Suggested change
return config, fmt.Errorf("stdio MCP tool '%s' must specify either 'command' or 'container' field. Cannot specify both. Example with command:\nmcp-servers:\n %s:\n command: \"npx @my/tool\"\n args: [\"--port\", \"3000\"]\n\nExample with container:\nmcp-servers:\n %s:\n container: \"myorg/my-tool:latest\"\n env:\n API_KEY: \"${{ secrets.API_KEY }}\"", toolName, toolName, toolName)
return config, fmt.Errorf(
"stdio MCP tool '%s' must specify either 'command' or 'container' field. Cannot specify both. "+
"Example with command:\n"+
"mcp-servers:\n"+
" %s:\n"+
" command: \"npx @my/tool\"\n"+
" args: [\"--port\", \"3000\"]\n\n"+
"Example with container:\n"+
"mcp-servers:\n"+
" %s:\n"+
" container: \"myorg/my-tool:latest\"\n"+
" env:\n"+
" API_KEY: \"${{ secrets.API_KEY }}\"",
toolName, toolName, toolName,
)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit d57732e. Error message reformatted with proper line breaks for better readability.

config.URL = urlStr
} else {
return config, fmt.Errorf("url must be a string")
return config, fmt.Errorf("url field must be a string, got %T. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", url, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits. Consider breaking it into multiple lines for better code readability.

Suggested formatting:

return config, fmt.Errorf("url field must be a string, got %T. Example:\n"+
    "mcp-servers:\n  %s:\n    type: http\n    url: \"https://api.example.com/mcp\"\n"+
    "    headers:\n      Authorization: \"Bearer ${{ secrets.API_KEY }}\"", url, toolName)
Suggested change
return config, fmt.Errorf("url field must be a string, got %T. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", url, toolName)
return config, fmt.Errorf(
"url field must be a string, got %T. Example:\n"+
"mcp-servers:\n"+
" %s:\n"+
" type: http\n"+
" url: \"https://api.example.com/mcp\"\n"+
" headers:\n"+
" Authorization: \"Bearer ${{ secrets.API_KEY }}\"",
url, toolName)

Copilot uses AI. Check for mistakes.
}
} else {
return config, fmt.Errorf("http type requires 'url' field")
return config, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits. Consider breaking it into multiple lines for better code readability.

Suggested formatting:

return config, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. "+
    "Example:\nmcp-servers:\n  %s:\n    type: http\n    url: \"https://api.example.com/mcp\"\n"+
    "    headers:\n      Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
Suggested change
return config, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
return config, fmt.Errorf(
"http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. "+
"Example:\n"+
"mcp-servers:\n"+
" %s:\n"+
" type: http\n"+
" url: \"https://api.example.com/mcp\"\n"+
" headers:\n"+
" Authorization: \"Bearer ${{ secrets.API_KEY }}\"",
toolName, toolName,
)

Copilot uses AI. Check for mistakes.
result.URL = url
} else {
return nil, fmt.Errorf("http MCP tool '%s' missing required 'url' field", toolName)
return nil, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Long error message line: This error message exceeds typical line length limits. Consider breaking it into multiple lines for better code readability.

Suggested formatting:

return nil, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. "+
    "Example:\nmcp-servers:\n  %s:\n    type: http\n    url: \"https://api.example.com/mcp\"\n"+
    "    headers:\n      Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
Suggested change
return nil, fmt.Errorf("http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. Example:\nmcp-servers:\n %s:\n type: http\n url: \"https://api.example.com/mcp\"\n headers:\n Authorization: \"Bearer ${{ secrets.API_KEY }}\"", toolName, toolName)
return nil, fmt.Errorf(
"http MCP tool '%s' missing required 'url' field. HTTP MCP servers must specify a URL endpoint. "+
"Example:\n"+
"mcp-servers:\n"+
" %s:\n"+
" type: http\n"+
" url: \"https://api.example.com/mcp\"\n"+
" headers:\n"+
" Authorization: \"Bearer ${{ secrets.API_KEY }}\"",
toolName, toolName,
)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit d57732e. Error message reformatted across multiple lines.

@pelikhan
Copy link
Contributor

@copilot merge main and lint

Copilot AI and others added 2 commits November 15, 2025 17:54
- Merged main branch
- Reformatted long error message lines for better readability
- Split multi-line error messages across multiple lines with proper indentation
- All error messages maintain the three-part template structure
- Tests continue to pass
- Linting passes

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 15, 2025

@copilot merge main and lint

Merged main and addressed linting feedback in commit d57732e. All error messages have been reformatted with proper line breaks for better code readability while maintaining the three-part template structure. All tests pass and linting is clean.

Copilot finished work on behalf of pelikhan November 15, 2025 18:03
Copilot AI requested a review from pelikhan November 15, 2025 18:03
@pelikhan pelikhan merged commit a7ac418 into main Nov 15, 2025
51 of 56 checks passed
@pelikhan pelikhan deleted the copilot/improve-mcp-error-messages branch November 15, 2025 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[task] Improve MCP configuration error messages with YAML examples

2 participants