Skip to content

Commit ed37e6f

Browse files
committed
Move inventory creation to HTTP handler and add factory pattern.
1 parent 7feaee3 commit ed37e6f

File tree

4 files changed

+64
-30
lines changed

4 files changed

+64
-30
lines changed

internal/ghmcp/server.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,22 @@ func NewStdioMCPServer(cfg github.MCPServerConfig) (*mcp.Server, error) {
9898
github.FeatureFlags{LockdownMode: cfg.LockdownMode},
9999
cfg.ContentWindowSize,
100100
)
101+
// Build and register the tool/resource/prompt inventory
102+
inventoryBuilder := github.NewInventory(cfg.Translator).
103+
WithDeprecatedAliases(github.DeprecatedToolAliases).
104+
WithReadOnly(cfg.ReadOnly).
105+
WithToolsets(cfg.EnabledToolsets).
106+
WithTools(github.CleanTools(cfg.EnabledTools))
107+
// WithFeatureChecker(createFeatureChecker(cfg.EnabledFeatures))
108+
109+
// Apply token scope filtering if scopes are known (for PAT filtering)
110+
if cfg.TokenScopes != nil {
111+
inventoryBuilder = inventoryBuilder.WithFilter(github.CreateToolScopeFilter(cfg.TokenScopes))
112+
}
113+
114+
inventory := inventoryBuilder.Build()
101115

102-
ghServer, err := github.NewMCPServer(&cfg, deps)
116+
ghServer, err := github.NewMCPServer(&cfg, deps, inventory)
103117
if err != nil {
104118
return nil, fmt.Errorf("failed to create GitHub MCP server: %w", err)
105119
}

pkg/github/server.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type MCPServerConfig struct {
6666
TokenScopes []string
6767
}
6868

69-
func NewMCPServer(cfg *MCPServerConfig, deps ToolDependencies) (*mcp.Server, error) {
69+
func NewMCPServer(cfg *MCPServerConfig, deps ToolDependencies, inventory *inventory.Inventory) (*mcp.Server, error) {
7070
enabledToolsets := resolveEnabledToolsets(cfg)
7171

7272
// For instruction generation, we need actual toolset names (not nil).
@@ -99,21 +99,6 @@ func NewMCPServer(cfg *MCPServerConfig, deps ToolDependencies) (*mcp.Server, err
9999
ghServer.AddReceivingMiddleware(addGitHubAPIErrorToContext)
100100
ghServer.AddReceivingMiddleware(InjectDepsMiddleware(deps))
101101

102-
// Build and register the tool/resource/prompt inventory
103-
inventoryBuilder := NewInventory(cfg.Translator).
104-
WithDeprecatedAliases(DeprecatedToolAliases).
105-
WithReadOnly(cfg.ReadOnly).
106-
WithToolsets(enabledToolsets).
107-
WithTools(CleanTools(cfg.EnabledTools)).
108-
WithFeatureChecker(createFeatureChecker(cfg.EnabledFeatures))
109-
110-
// Apply token scope filtering if scopes are known (for PAT filtering)
111-
if cfg.TokenScopes != nil {
112-
inventoryBuilder = inventoryBuilder.WithFilter(CreateToolScopeFilter(cfg.TokenScopes))
113-
}
114-
115-
inventory := inventoryBuilder.Build()
116-
117102
if unrecognized := inventory.UnrecognizedToolsets(); len(unrecognized) > 0 {
118103
fmt.Fprintf(os.Stderr, "Warning: unrecognized toolsets ignored: %s\n", strings.Join(unrecognized, ", "))
119104
}

pkg/http/handler.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,41 @@ package http
33
import (
44
"log/slog"
55
"net/http"
6+
"strings"
67

78
"github.com/github/github-mcp-server/pkg/github"
89
"github.com/github/github-mcp-server/pkg/http/middleware"
10+
"github.com/github/github-mcp-server/pkg/inventory"
911
"github.com/github/github-mcp-server/pkg/lockdown"
1012
"github.com/github/github-mcp-server/pkg/translations"
1113
"github.com/github/github-mcp-server/pkg/utils"
1214
"github.com/modelcontextprotocol/go-sdk/mcp"
1315
)
1416

17+
type InventoryFactoryFunc func(r *http.Request) *inventory.Inventory
18+
1519
type HttpMcpHandler struct {
16-
config *HTTPServerConfig
17-
apiHosts utils.ApiHost
18-
logger *slog.Logger
19-
t translations.TranslationHelperFunc
20-
repoAccessOpts []lockdown.RepoAccessOption
20+
config *HTTPServerConfig
21+
apiHosts utils.ApiHost
22+
logger *slog.Logger
23+
t translations.TranslationHelperFunc
24+
repoAccessOpts []lockdown.RepoAccessOption
25+
inventoryFactoryFunc InventoryFactoryFunc
2126
}
2227

2328
func NewHttpMcpHandler(cfg *HTTPServerConfig,
2429
t translations.TranslationHelperFunc,
2530
apiHosts *utils.ApiHost,
2631
repoAccessOptions []lockdown.RepoAccessOption,
27-
logger *slog.Logger) *HttpMcpHandler {
32+
logger *slog.Logger,
33+
inventoryFactory InventoryFactoryFunc) *HttpMcpHandler {
2834
return &HttpMcpHandler{
29-
config: cfg,
30-
apiHosts: *apiHosts,
31-
logger: logger,
32-
t: t,
33-
repoAccessOpts: repoAccessOptions,
35+
config: cfg,
36+
apiHosts: *apiHosts,
37+
logger: logger,
38+
t: t,
39+
repoAccessOpts: repoAccessOptions,
40+
inventoryFactoryFunc: inventoryFactory,
3441
}
3542
}
3643

@@ -48,6 +55,8 @@ func (s *HttpMcpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
4855
s.config.ContentWindowSize,
4956
)
5057

58+
inventory := s.inventoryFactoryFunc(r)
59+
5160
ghServer, err := github.NewMCPServer(&github.MCPServerConfig{
5261
Version: s.config.Version,
5362
Host: s.config.Host,
@@ -60,7 +69,7 @@ func (s *HttpMcpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6069
ContentWindowSize: s.config.ContentWindowSize,
6170
Logger: s.logger,
6271
RepoAccessTTL: s.config.RepoAccessCacheTTL,
63-
}, deps)
72+
}, deps, inventory)
6473
if err != nil {
6574
w.WriteHeader(http.StatusInternalServerError)
6675
}
@@ -73,3 +82,29 @@ func (s *HttpMcpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
7382

7483
middleware.ExtractUserToken()(mcpHandler).ServeHTTP(w, r)
7584
}
85+
86+
func DefaultInventoryFactory(cfg *HTTPServerConfig, t translations.TranslationHelperFunc) InventoryFactoryFunc {
87+
return func(r *http.Request) *inventory.Inventory {
88+
b := github.NewInventory(t).WithDeprecatedAliases(github.DeprecatedToolAliases)
89+
b = InventoryFiltersForRequestHeaders(r, b)
90+
return b.Build()
91+
}
92+
}
93+
94+
func InventoryFiltersForRequestHeaders(r *http.Request, builder *inventory.Builder) *inventory.Builder {
95+
if r.Header.Get("X-MCP-Readonly") != "" {
96+
builder = builder.WithReadOnly(true)
97+
}
98+
99+
if toolsetsStr := r.Header.Get("X-MCP-Toolsets"); toolsetsStr != "" {
100+
toolsets := strings.Split(toolsetsStr, ",")
101+
builder = builder.WithToolsets(toolsets)
102+
}
103+
104+
if toolsStr := r.Header.Get("X-MCP-Tools"); toolsStr != "" {
105+
tools := strings.Split(toolsStr, ",")
106+
builder = builder.WithTools(github.CleanTools(tools))
107+
}
108+
109+
return builder
110+
}

pkg/http/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func RunHTTPServer(cfg HTTPServerConfig) error {
9898
repoAccessOpts = append(repoAccessOpts, lockdown.WithTTL(*cfg.RepoAccessCacheTTL))
9999
}
100100

101-
handler := NewHttpMcpHandler(&cfg, t, &apiHost, repoAccessOpts, logger)
101+
handler := NewHttpMcpHandler(&cfg, t, &apiHost, repoAccessOpts, logger, DefaultInventoryFactory(&cfg, t))
102102

103103
r := chi.NewRouter()
104104
r.Mount("/", handler)

0 commit comments

Comments
 (0)