Add --exclude-tools (and X-MCP-Exclude-Tools) flag to enable shutting off tools as part of server configuration#2036
Add --exclude-tools (and X-MCP-Exclude-Tools) flag to enable shutting off tools as part of server configuration#2036tommaso-moro wants to merge 3 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds support for disallowed tools - a new way to disable specific tools regardless of any other configuration settings. This feature allows administrators to blocklist specific tools for security, compliance, or operational reasons. The implementation adds a --disallowed-tools flag for the local stdio server and documents (but does not implement) the corresponding X-MCP-Disallowed-Tools header for the remote server.
Changes:
- Added
WithDisallowedTools()builder method andCreateDisallowedToolsFilter()to the inventory package for filtering out specific tools by name - Added CLI flag
--disallowed-toolsand environment variableGITHUB_DISALLOWED_TOOLSsupport for the local stdio server - Added comprehensive test coverage including edge cases and interaction with read-only mode and additional tools
- Updated documentation in
docs/server-configuration.mdto describe the feature and provide examples
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/inventory/builder.go | Added WithDisallowedTools() method and CreateDisallowedToolsFilter() function to enable tool blocklisting via builder filters |
| pkg/inventory/registry_test.go | Added comprehensive test coverage for disallowed tools functionality including edge cases and interaction tests |
| pkg/github/server.go | Added DisallowedTools field to MCPServerConfig struct |
| internal/ghmcp/server.go | Added DisallowedTools field to StdioServerConfig and wired it through to MCPServerConfig |
| cmd/github-mcp-server/main.go | Added --disallowed-tools CLI flag, environment variable binding, and parsing logic |
| docs/server-configuration.md | Added documentation section and examples for disallowed tools feature, including both local and remote server usage |
|
hey @tommaso-moro, what would be user experience if we have the same tool explicitly enabled and disallowed ? |
|
@IrynaKulakova disallow always takes priority, so the tool would not be enabled if it's in the "disallowed-tools" list, regardless of other configurations:) |
|
Update |
Closes https://github.com/github/copilot-mcp-core/issues/1292
Update:
--disallow-toolsandX-MCP-Disallow-Toolshave been renamed to--exclude-toolsandX-MCP-Exclude-ToolsSummary
Adds support for excluding tools: a new way to disable specific tools regardless of any other configuration. This is the inverse of
--tools, which is used to enable specific tools. Tools listed inexclude-toolsare always removed, even if their toolset is enabled or they are explicitly added via--tools/X-MCP-Tools.Local server:
--exclude-tools=create_issue,push_filesflagGITHUB_EXCLUDE_TOOLSenv varRemote server (after bumping this dependency):
X-MCP-Exclude-Toolsheader to the remote server, and will merge it once this PR has been merged and shipped with the next release : https://github.com/github/github-mcp-server-remote/pull/705Demo
Stdio mode:
https://github.com/user-attachments/assets/3e8e866f-3fc8-4c03-8258-ed2293cc07c2
Using http mode:

Motivation
This enables configs like:
{ "--toolsets": "pull_requests", "--exclude-tools": "create_pull_request,merge_pull_request" }And in general it allows for better security + easier server configuration.
What changed
New CLI flag and env var
--exclude-toolsflag (comma-separated list of tool names to disable)GITHUB_EXCLUDE_TOOLSenv var (equivalent)New inventory builder APIs
Builder.WithDisallowedTools([]string): builder method that adds a filter to exclude the named tools. Input is cleaned (trimmed, deduplicated). No-op if the list is empty or nil.inventory.CreateDisallowedToolsFilter([]string): exported standalone filter constructor. Returns aToolFilterthat excludes tools by name. Exported so the remote server can use it directly if preferred.Both are thin wrappers around the existing
WithFiltermechanism: disallowed tools are implemented as a builder filter (step 4 in filter evaluation), which runs before the toolset/additional-tools check (step 5). This means a tool present in both--toolsand--disallowed-toolswill be disallowed.HTTP entrypoint support
In addition to the
--disallowed-toolsCLI flag for stdio mode, this PR adds full support for theX-MCP-Disallowed-ToolsHTTP header in the HTTP entrypoint (github-mcp-server http). This ensures the feature works across both transport modes and is available to the remote server (github-mcp-server-remote) which imports this repo'spkg/httppackage.pkg/http/headers/headers.goMCPDisallowedToolsHeader = "X-MCP-Disallowed-Tools"constantpkg/context/request.goWithDisallowedTools()/GetDisallowedTools()context helperspkg/http/middleware/request_config.goX-MCP-Disallowed-Toolsheader into request contextpkg/http/handler.goInventoryFiltersForRequestappliesWithDisallowedTools()from contextpkg/http/handler_test.goI added tests too and updated the docs.
MCP impact
Prompts tested (tool changes only)
Security / limits
Tool renaming
deprecated_tool_aliases.goNote: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.
Lint & tests
./script/lint./script/testDocs