Skip to content

Commit fe31428

Browse files
Add context toolset and adjust readme (#499)
* add context toolset and adjust readme * move resources to a toolset * add resource registration as a toolset concern * add a note about broadening of toolsets * Apply suggestion from @SamMorrowDrums
1 parent cbcf29f commit fe31428

File tree

5 files changed

+67
-34
lines changed

5 files changed

+67
-34
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,22 @@ If you don't have Docker, you can use `go build` to build the binary in the
141141

142142
The GitHub MCP Server supports enabling or disabling specific groups of functionalities via the `--toolsets` flag. This allows you to control which GitHub API capabilities are available to your AI tools. Enabling only the toolsets that you need can help the LLM with tool choice and reduce the context size.
143143

144+
_Toolsets are not limited to Tools. Relevent MCP Resources and Prompts are also included where applicable._
145+
144146
### Available Toolsets
145147

146148
The following sets of tools are available (all are on by default):
147149

148150
| Toolset | Description |
149151
| ----------------------- | ------------------------------------------------------------- |
150-
| `repos` | Repository-related tools (file operations, branches, commits) |
152+
| `context` | **Strongly recommended**: Tools that provide context about the current user and GitHub context you are operating in |
153+
| `code_security` | Code scanning alerts and security features |
151154
| `issues` | Issue-related tools (create, read, update, comment) |
152-
| `users` | Anything relating to GitHub Users |
155+
| `notifications` | GitHub Notifications related tools |
153156
| `pull_requests` | Pull request operations (create, merge, review) |
154-
| `code_security` | Code scanning alerts and security features |
157+
| `repos` | Repository-related tools (file operations, branches, commits) |
158+
| `secret_protection` | Secret protection related tools, such as GitHub Secret Scanning |
159+
| `users` | Anything relating to GitHub Users |
155160
| `experiments` | Experimental features (not considered stable) |
156161

157162
#### Specifying Toolsets

internal/ghmcp/server.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,8 @@ func NewMCPServer(cfg MCPServerConfig) (*server.MCPServer, error) {
120120
return nil, fmt.Errorf("failed to enable toolsets: %w", err)
121121
}
122122

123-
context := github.InitContextToolset(getClient, cfg.Translator)
124-
github.RegisterResources(ghServer, getClient, cfg.Translator)
125-
126-
// Register the tools with the server
127-
tsg.RegisterTools(ghServer)
128-
context.RegisterTools(ghServer)
123+
// Register all mcp functionality with the server
124+
tsg.RegisterAll(ghServer)
129125

130126
if cfg.DynamicToolsets {
131127
dynamic := github.InitDynamicToolset(ghServer, tsg, cfg.Translator)

pkg/github/resources.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

pkg/github/tools.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
3838
toolsets.NewServerTool(CreateBranch(getClient, t)),
3939
toolsets.NewServerTool(PushFiles(getClient, t)),
4040
toolsets.NewServerTool(DeleteFile(getClient, t)),
41+
).
42+
AddResourceTemplates(
43+
toolsets.NewServerResourceTemplate(GetRepositoryResourceContent(getClient, t)),
44+
toolsets.NewServerResourceTemplate(GetRepositoryResourceBranchContent(getClient, t)),
45+
toolsets.NewServerResourceTemplate(GetRepositoryResourceCommitContent(getClient, t)),
46+
toolsets.NewServerResourceTemplate(GetRepositoryResourceTagContent(getClient, t)),
47+
toolsets.NewServerResourceTemplate(GetRepositoryResourcePrContent(getClient, t)),
4148
)
4249
issues := toolsets.NewToolset("issues", "GitHub Issues related tools").
4350
AddReadTools(
@@ -106,7 +113,13 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
106113
// Keep experiments alive so the system doesn't error out when it's always enabled
107114
experiments := toolsets.NewToolset("experiments", "Experimental features that are not considered stable yet")
108115

116+
contextTools := toolsets.NewToolset("context", "Tools that provide context about the current user and GitHub context you are operating in").
117+
AddReadTools(
118+
toolsets.NewServerTool(GetMe(getClient, t)),
119+
)
120+
109121
// Add toolsets to the group
122+
tsg.AddToolset(contextTools)
110123
tsg.AddToolset(repos)
111124
tsg.AddToolset(issues)
112125
tsg.AddToolset(users)
@@ -119,16 +132,6 @@ func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetG
119132
return tsg
120133
}
121134

122-
func InitContextToolset(getClient GetClientFn, t translations.TranslationHelperFunc) *toolsets.Toolset {
123-
// Create a new context toolset
124-
contextTools := toolsets.NewToolset("context", "Tools that provide context about the current user and GitHub context you are operating in").
125-
AddReadTools(
126-
toolsets.NewServerTool(GetMe(getClient, t)),
127-
)
128-
contextTools.Enabled = true
129-
return contextTools
130-
}
131-
132135
// InitDynamicToolset creates a dynamic toolset that can be used to enable other toolsets, and so requires the server and toolset group as arguments
133136
func InitDynamicToolset(s *server.MCPServer, tsg *toolsets.ToolsetGroup, t translations.TranslationHelperFunc) *toolsets.Toolset {
134137
// Create a new dynamic toolset

pkg/toolsets/toolsets.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,30 @@ func NewServerTool(tool mcp.Tool, handler server.ToolHandlerFunc) server.ServerT
3333
return server.ServerTool{Tool: tool, Handler: handler}
3434
}
3535

36+
func NewServerResourceTemplate(resourceTemplate mcp.ResourceTemplate, handler server.ResourceTemplateHandlerFunc) ServerResourceTemplate {
37+
return ServerResourceTemplate{
38+
resourceTemplate: resourceTemplate,
39+
handler: handler,
40+
}
41+
}
42+
43+
// ServerResourceTemplate represents a resource template that can be registered with the MCP server.
44+
type ServerResourceTemplate struct {
45+
resourceTemplate mcp.ResourceTemplate
46+
handler server.ResourceTemplateHandlerFunc
47+
}
48+
49+
// Toolset represents a collection of MCP functionality that can be enabled or disabled as a group.
3650
type Toolset struct {
3751
Name string
3852
Description string
3953
Enabled bool
4054
readOnly bool
4155
writeTools []server.ServerTool
4256
readTools []server.ServerTool
57+
// resources are not tools, but the community seems to be moving towards namespaces as a broader concept
58+
// and in order to have multiple servers running concurrently, we want to avoid overlapping resources too.
59+
resourceTemplates []ServerResourceTemplate
4360
}
4461

4562
func (t *Toolset) GetActiveTools() []server.ServerTool {
@@ -73,6 +90,31 @@ func (t *Toolset) RegisterTools(s *server.MCPServer) {
7390
}
7491
}
7592

93+
func (t *Toolset) AddResourceTemplates(templates ...ServerResourceTemplate) *Toolset {
94+
t.resourceTemplates = append(t.resourceTemplates, templates...)
95+
return t
96+
}
97+
98+
func (t *Toolset) GetActiveResourceTemplates() []ServerResourceTemplate {
99+
if !t.Enabled {
100+
return nil
101+
}
102+
return t.resourceTemplates
103+
}
104+
105+
func (t *Toolset) GetAvailableResourceTemplates() []ServerResourceTemplate {
106+
return t.resourceTemplates
107+
}
108+
109+
func (t *Toolset) RegisterResourcesTemplates(s *server.MCPServer) {
110+
if !t.Enabled {
111+
return
112+
}
113+
for _, resource := range t.resourceTemplates {
114+
s.AddResourceTemplate(resource.resourceTemplate, resource.handler)
115+
}
116+
}
117+
76118
func (t *Toolset) SetReadOnly() {
77119
// Set the toolset to read-only
78120
t.readOnly = true
@@ -179,9 +221,10 @@ func (tg *ToolsetGroup) EnableToolset(name string) error {
179221
return nil
180222
}
181223

182-
func (tg *ToolsetGroup) RegisterTools(s *server.MCPServer) {
224+
func (tg *ToolsetGroup) RegisterAll(s *server.MCPServer) {
183225
for _, toolset := range tg.Toolsets {
184226
toolset.RegisterTools(s)
227+
toolset.RegisterResourcesTemplates(s)
185228
}
186229
}
187230

0 commit comments

Comments
 (0)