Skip to content

feat: partition tools by product/feature #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 14, 2025
Merged

Conversation

SamMorrowDrums
Copy link
Collaborator

@SamMorrowDrums SamMorrowDrums commented Apr 8, 2025

Partitioned Features

This PR proposes a method for partitioning features by product area, and provides ENV and CLI flag options to configure it on server startup.

Features Configuration

The GitHub MCP Server supports enabling or disabling specific groups of functionalities via the --features flag. This allows you to control which GitHub API capabilities are available to your AI tools.

Available Features

The following feature groups are available:

Feature Description Default Status
repos Repository-related tools (file operations, branches, commits) Enabled
issues Issue-related tools (create, read, update, comment) Enabled
search Search functionality (code, repositories, users) Enabled
pull_requests Pull request operations (create, merge, review) Enabled
code_security Code scanning alerts and security features Disabled
experiments Experimental features (not considered stable) Disabled
everything Special flag to enable all features Disabled

Specifying Features

You can enable specific features in two ways:

  1. Using Command Line Argument:

    github-mcp-server --features repos,issues,pull_requests,code_security
  2. Using Environment Variable:

    GITHUB_FEATURES="repos,issues,pull_requests,code_security" ./github-mcp-server

The environment variable GITHUB_FEATURES takes precedence over the command line argument if both are provided.

Default Enabled Features

By default, the following features are enabled:

  • repos
  • issues
  • pull_requests
  • search

Using With Docker

When using Docker, you can pass the features as environment variables:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=<your-token> \
  -e GITHUB_FEATURES="repos,issues,pull_requests,code_security,experiments" \
  ghcr.io/github/github-mcp-server

The "everything" Feature

The special feature everything can be provided to enable all available features regardless of their individual settings:

./github-mcp-server --features everything

Or using the environment variable:

GITHUB_FEATURES="everything" ./github-mcp-server

@Copilot Copilot AI review requested due to automatic review settings April 8, 2025 23:45
Copy link
Contributor

@Copilot 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 partitions the GitHub MCP Server tools by product area using feature flags, and adds the necessary configuration options and tests.

  • Introduces a new "features" module to manage feature sets and enable/disable specific tools.
  • Updates the server initialization to conditionally add tools based on feature flags.
  • Adds tests and updates documentation to reflect the new configurable features.

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/github/server_test.go Added tests (e.g., Test_ListAvailableFeatures) for verifying the feature listing tool.
pkg/github/server.go Modified server creation to conditionally add tools based on enabled feature flags.
pkg/features/features_test.go Added unit tests to validate FeatureSet behavior.
pkg/features/features.go Introduced FeatureSet implementation for feature management.
cmd/github-mcp-server/main.go Updated CLI and environment variable parsing to initialize features.
README.md Expanded documentation on the new features configuration and usage.
Comments suppressed due to low confidence (2)

cmd/github-mcp-server/main.go:91

  • [nitpick] Consider renaming the variable 'envFeats' to 'envFeatures' to improve clarity.
if envFeats := os.Getenv("GITHUB_FEATURES"); envFeats != "" {

pkg/features/features.go:63

  • [nitpick] Consider wrapping the feature name in quotes within the error message (e.g. "feature '%s' does not exist") for improved clarity.
return fmt.Errorf("feature %s does not exist", name)

func(_ context.Context, _ mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// We need to convert the FeatureSet back to a map for JSON serialization
featureMap := make(map[string]bool)
for name := range featureSet.Features {
Copy link
Preview

Copilot AI Apr 8, 2025

Choose a reason for hiding this comment

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

If a deterministic order of features is required for clients consuming the JSON output, consider sorting the feature keys before JSON marshaling.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

}
}

func (fs *FeatureSet) AddFeature(name string, description string, enabled bool) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: if you ever need to use https://pkg.go.dev/io/fs in here one or the other will need to be renamed

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Great point!

@toby
Copy link
Member

toby commented Apr 9, 2025

I might consider calling them "toolsets" instead of features, just to be a bit more explicit.

@SamMorrowDrums
Copy link
Collaborator Author

@toby toolsets does make sense, I hesitate a little because resources and prompts are also part of it, so I was sort of avoiding the word tool, but perhaps we just run with it?

Definitely not committed to any naming.

juruen
juruen previously approved these changes Apr 10, 2025
Copy link
Collaborator

@juruen juruen left a comment

Choose a reason for hiding this comment

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

Looks good to me!

Just one super minor question: what would you think about using all instead of everything?

As it's very minor, feel free to ignore it 😄

toby
toby previously approved these changes Apr 10, 2025
@toby
Copy link
Member

toby commented Apr 10, 2025

This is so great!!

tonytrg
tonytrg previously approved these changes Apr 10, 2025
@tonytrg
Copy link
Contributor

tonytrg commented Apr 10, 2025

Aside from the linter, do you plan on merging this soon?

@SamMorrowDrums
Copy link
Collaborator Author

Yeah, I just have to finish a couple of bits. Mostly the auto tool updates. Just keep pushing the latest.

@SamMorrowDrums SamMorrowDrums dismissed stale reviews from tonytrg and toby via d2588f0 April 10, 2025 23:51
@SamMorrowDrums SamMorrowDrums force-pushed the partition-tools branch 2 times, most recently from 0ee52f5 to 9a56c25 Compare April 11, 2025 00:15
juruen
juruen previously approved these changes Apr 11, 2025
Copy link
Collaborator

@juruen juruen left a comment

Choose a reason for hiding this comment

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

Looking great! 🚀

@SamMorrowDrums SamMorrowDrums force-pushed the partition-tools branch 5 times, most recently from 8d56fe2 to 6ecee2f Compare April 11, 2025 14:10
@SamMorrowDrums SamMorrowDrums requested a review from juruen April 11, 2025 15:22
@toby
Copy link
Member

toby commented Apr 11, 2025

What do you think about these options?

  1. By default we list all tools (all), except: list_available_toolsets, enable_toolset and get_toolset_tools since you won't really need them with all enabled.
  2. Use a --dynamic-toolsets flag to enable list_available_toolsets, enable_toolset and get_toolset_tools, all other tools (except get_me) are hidden until enabled
  3. Use the --toolsets flag to specify active toolsets. If used in conjunction with --dynamic-toolsets they will be hidden until enabled, toolsets not specified, cannot be enabled. If the --dynamic-toolsets flag is not set, all of the tools listed in the toolsets you've enabled are listed by default.

@SamMorrowDrums
Copy link
Collaborator Author

I think those suggestions get us closer to a usable interface for sure, will riff on them on Monday I hope, see if we end up with something mergeable. Feels close.

README.md Outdated
- `issues`
- `pull_requests`
- `search`
- `context-_ools`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo

readOnly bool
writeTools []server.ServerTool
readTools []server.ServerTool
resourceTemplates []ResourceTemplate
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feedback

Was a bit confusing to me that toolsets also manage resource templates. I don't see a relationship between them. Might be indicative that the abstraction is trying to do too much.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll leave it separate then, initially the idea was that all features pertaining to a product area (not just tools) would be adjusted - and the naming reflected that - but I merged it into toolsets.

For now I'll leave it separate, and it can be revisited.

@SamMorrowDrums SamMorrowDrums force-pushed the partition-tools branch 2 times, most recently from 45f55fc to 8aba085 Compare April 14, 2025 21:04
@ismith
Copy link

ismith commented Apr 14, 2025

"none" also might be useful? As in, "I do not currently want any of these tools enabled, but nor do I want to remove my config entirely from settings" (and since .vscode/mcp.json is, well, json, commenting out the entire block seems like a non-starter).

@SamMorrowDrums
Copy link
Collaborator Author

Interesting idea @ismith

commenting out the entire block seems like a non-starter
Actually VSCode config supports jsonc, so you can use comments, and also you can de-select the tools for an entire server in the UI, if you click on the symbol.

CleanShot 2025-04-15 at 00 33 28

Some other software might not support that, but I'm tempted to say we once this merges we could track the none idea in an issue if you like, and see if there are others requesting the same?

@SamMorrowDrums SamMorrowDrums merged commit ff3036d into main Apr 14, 2025
16 checks passed
@SamMorrowDrums SamMorrowDrums deleted the partition-tools branch April 14, 2025 23:11
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.

None yet

7 participants