Skip to content

Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools#1115

Merged
pelikhan merged 13 commits intomainfrom
copilot/fix-2b52337f-e29b-49f5-90fa-e39324a0fe01
Oct 1, 2025
Merged

Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools#1115
pelikhan merged 13 commits intomainfrom
copilot/fix-2b52337f-e29b-49f5-90fa-e39324a0fe01

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Sep 30, 2025

Fix Copilot Engine GitHub Tool Allow-List Generation

The Copilot agentic engine was not generating --allow-tool arguments for GitHub MCP tools correctly. This caused GitHub API operations to fail during workflow execution.

Problem Analysis

  • GitHub is NOT built-in to Copilot CLI in non-interactive (CLI) mode - it requires MCP configuration
  • The GitHub MCP server should only be allowed via --allow-tool github when using wildcard "*"
  • Individual GitHub tools need to be allowed via --allow-tool github(tool_name)
  • The code was incorrectly treating GitHub as built-in and skipping it entirely in the builtInTools map
  • Default GitHub tools are added by applyDefaultTools and need to be converted to --allow-tool arguments

Solution

Modified computeCopilotToolArguments in pkg/workflow/copilot_engine.go to handle GitHub as an MCP server tool with conditional server-level permission:

  1. Removed GitHub from builtInTools list: GitHub is not built-in in CLI mode (only in interactive mode)
  2. Added special handling for GitHub: Treat it as an MCP server tool with conditional behavior
  3. Efficient single-pass processing: Process the allowed array once to detect wildcard and add tool permissions
  4. Conditional server-level permission:
    • Only emit --allow-tool github when allowed contains "*" wildcard
    • Always emit --allow-tool github(tool_name) for each specific tool (excluding wildcard)
  5. Maintain sorted output: Tool arguments are alphabetically sorted for consistency
  6. Proper shell escaping: Arguments with special characters (like parentheses) are automatically wrapped in single quotes via shellEscapeArg function

Before

copilot --add-dir /tmp/ --log-level all --prompt "$INSTRUCTION"

After (with specific tools)

copilot --add-dir /tmp/ --log-level all \
  --allow-tool 'github(get_issue)' \
  --allow-tool 'github(add_issue_comment)' \
  --allow-tool 'github(list_issues)' \
  --prompt "$INSTRUCTION"

After (with wildcard)

copilot --add-dir /tmp/ --log-level all \
  --allow-tool github \
  --prompt "$INSTRUCTION"

After (GitHub not configured)

copilot --add-dir /tmp/ --log-level all \
  --prompt "$INSTRUCTION"

Testing

  • Updated 8 test cases to remove --allow-tool github when not using wildcard
  • Added 2 new test cases for wildcard behavior (wildcard-only and wildcard with specific tools)
  • Added explicit test for shell escaping of GitHub tool arguments
  • All existing tests continue to pass
  • Manually verified the generated Copilot commands include correct tool arguments with proper single-quote wrapping
  • Verified no arguments are added when GitHub is not configured

Changes

  • pkg/workflow/copilot_engine.go: Simplified wildcard handling with single-pass processing, only emit server-level permission with wildcard
  • pkg/workflow/copilot_engine_test.go: Updated comprehensive test cases including wildcard scenarios
  • pkg/workflow/shell.go: Existing shell escaping logic handles parentheses correctly
Original prompt

Make sure the copilot agentic engine generates the --allow-tool list for the github mcp. Although it is a builtin, the tool have to be allowed to.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 2 commits September 30, 2025 17:08
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Make sure the copilot agentic engine generates the --allow-tool list for the github mcp. Although it is a builtin, the tool have to be allowed to. Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools Sep 30, 2025
Copilot AI requested a review from pelikhan September 30, 2025 17:17
@pelikhan pelikhan marked this pull request as ready for review September 30, 2025 17:20
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Oct 1, 2025

@copilot use "--deny-tool github" when GitHub is disabled

- Modified computeCopilotToolArguments to add --deny-tool github for empty allowed arrays, nil, false values
- Updated sorting logic to preserve flag types (--allow-tool vs --deny-tool)
- Modified applyDefaultTools to respect explicitly empty allowed arrays
- Added test case for github: false
- Updated tests to expect --deny-tool github for disabled cases

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

Copilot AI commented Oct 1, 2025

@copilot use "--deny-tool github" when GitHub is disabled

Added --deny-tool github support in commit e322c1a.

When GitHub is disabled (empty allowed array, nil, or false), the Copilot CLI command now includes --deny-tool github. For example:

copilot --deny-tool github --prompt "$INSTRUCTION"

The compiler also now respects explicitly empty allowed arrays (github: { allowed: [] }), which allows users to disable GitHub tools without having defaults added automatically.

Copilot AI changed the title Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools Fix Copilot engine to generate --allow-tool and --deny-tool arguments for GitHub MCP tools Oct 1, 2025
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Oct 1, 2025

@copilot remove --deny-tool support since github is only enabled on demand.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 1, 2025

@copilot remove --deny-tool support since github is only enabled on demand.

Removed --deny-tool support in commit 99c1a9e.

GitHub is now only enabled on demand when explicitly configured with tools. When GitHub is not configured or has an empty allowed array, no arguments are added to the Copilot CLI command. This is the correct behavior since GitHub is a built-in tool that doesn't need to be explicitly denied.

Copilot AI changed the title Fix Copilot engine to generate --allow-tool and --deny-tool arguments for GitHub MCP tools Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools Oct 1, 2025
Copy link
Copy Markdown
Collaborator

@pelikhan pelikhan left a comment

Choose a reason for hiding this comment

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

@copilot remove the --deny-tool support

Copy link
Copy Markdown
Collaborator

@pelikhan pelikhan left a comment

Choose a reason for hiding this comment

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

@copilot the entries like

github(add_issue_comment)" 

must be single quoted:

'github(add_issue_comment)'

Reverted all --deny-tool logic since GitHub is only enabled on demand:
- Simplified GitHub handling in copilotengine.go to only add --allow-tool for configured tools
- Reverted sorting logic to simpler version that assumes all flags are --allow-tool
- Reverted compiler changes to always add default GitHub tools
- Updated test expectations to not expect --deny-tool

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

Copilot AI commented Oct 1, 2025

@copilot remove the --deny-tool support

Removed all --deny-tool support in commit 65fde01.

The code now only adds --allow-tool github(tool_name) when GitHub tools are explicitly configured. When GitHub is not configured or has an empty allowed array, no arguments are added since GitHub is only enabled on demand.

Added TestCopilotEngineGitHubToolsShellEscaping to explicitly verify that GitHub tool arguments like 'github(add_issue_comment)' are properly wrapped in single quotes by the shellEscapeArg function.

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

Copilot AI commented Oct 1, 2025

@copilot the entries like

github(add_issue_comment)" ...

The GitHub tool arguments are already being single-quoted correctly. The shellEscapeArg function in pkg/workflow/shell.go automatically wraps arguments containing parentheses in single quotes.

Added test TestCopilotEngineGitHubToolsShellEscaping in commit 39676d0 to explicitly verify this behavior. The test confirms that arguments like 'github(add_issue_comment)' and 'github(get_issue)' are properly single-quoted in the generated commands.

Example from a compiled workflow:

copilot --allow-tool 'github(get_issue)' --allow-tool 'github(add_issue_comment)'

Comment thread pkg/workflow/copilot_engine.go Outdated
// Handle GitHub MCP tools - GitHub is built-in to Copilot CLI but still needs tool allowlist
if githubConfig, hasGithub := tools["github"]; hasGithub {
if githubConfigMap, ok := githubConfig.(map[string]any); ok {
// GitHub is built-in, so we don't add --allow-tool github itself
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot GitHub is not builtin in cli mode (only interactive mode) so you need to treat like any other tool and emit the proper arguments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in commit ee6281c to treat GitHub as an MCP server tool in CLI mode.

Now emits both:

  • --allow-tool github (the MCP server itself)
  • --allow-tool 'github(tool_name)' for each allowed tool

Example generated command:

copilot --allow-tool github --allow-tool 'github(get_issue)' --allow-tool 'github(add_issue_comment)'

GitHub is not built-in in CLI mode (only in interactive mode), so it needs to be treated like any other MCP server tool. Updated to:
- Remove GitHub from builtInTools list
- Add special handling for GitHub in MCP server loop
- Emit both --allow-tool github and --allow-tool github(tool_name) for each allowed tool
- Updated tests to expect --allow-tool github in addition to individual tool permissions

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools Fix Copilot engine to generate --allow-tool arguments for GitHub MCP server and tools Oct 1, 2025
Copilot AI requested a review from pelikhan October 1, 2025 07:38
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Oct 1, 2025

@copilot only add --allow-tool GitHub when allowed is "*"

Modified GitHub handling to only emit --allow-tool github (server-level permission) when the allowed array contains the "*" wildcard. When specific tools are listed, only emit --allow-tool github(tool_name) for each tool.

This allows more granular control - users can specify just the tools they need without enabling the entire GitHub MCP server.

Updated tests to:
- Remove --allow-tool github from tests with specific tools
- Add new test cases for wildcard behavior
- Add test for wildcard combined with specific tools

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

Copilot AI commented Oct 1, 2025

@copilot only add --allow-tool GitHub when allowed is "*"

Updated in commit 565ca88 to only add --allow-tool github when the allowed array contains "*".

When specific tools are listed, only the individual tool permissions are emitted:

copilot --allow-tool 'github(get_issue)' --allow-tool 'github(add_issue_comment)'

When wildcard is used:

copilot --allow-tool github

Copilot AI changed the title Fix Copilot engine to generate --allow-tool arguments for GitHub MCP server and tools Fix Copilot engine to generate --allow-tool arguments for GitHub MCP tools Oct 1, 2025
@pelikhan
Copy link
Copy Markdown
Collaborator

pelikhan commented Oct 1, 2025

@copilot review the wildcard treatment and make sure you are not tearing it twice. Simplify, add test cases

Refactored GitHub tool handling to process the allowed array only once instead of twice:
- Single loop processes both wildcard detection and individual tool permissions
- Wildcard "*" adds server-level permission (--allow-tool github)
- Other tools add individual permissions (--allow-tool github(tool_name))
- More efficient and easier to understand

All existing tests pass without changes.

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

Copilot AI commented Oct 1, 2025

@copilot review the wildcard treatment and make sure you are not tearing it twice. Simplify, add test cases

Simplified in commit 488ddd3 to process the allowed list in a single pass instead of iterating twice.

The refactored code:

  • Processes wildcard detection and individual tool permissions in one loop
  • More efficient and easier to understand
  • All existing tests pass without changes

@pelikhan pelikhan merged commit a01a702 into main Oct 1, 2025
7 of 11 checks passed
@pelikhan pelikhan deleted the copilot/fix-2b52337f-e29b-49f5-90fa-e39324a0fe01 branch October 1, 2025 14:41
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.

2 participants