| 79 | } |
| 80 | |
| 81 | func NewHTTPMcpHandler( |
| 82 | ctx context.Context, |
| 83 | cfg *ServerConfig, |
| 84 | deps github.ToolDependencies, |
| 85 | t translations.TranslationHelperFunc, |
| 86 | logger *slog.Logger, |
| 87 | apiHost utils.APIHostResolver, |
| 88 | options ...HandlerOption) *Handler { |
| 89 | opts := &HandlerOptions{} |
| 90 | for _, o := range options { |
| 91 | o(opts) |
| 92 | } |
| 93 | |
| 94 | githubMcpServerFactory := opts.GitHubMcpServerFactory |
| 95 | if githubMcpServerFactory == nil { |
| 96 | githubMcpServerFactory = DefaultGitHubMCPServerFactory |
| 97 | } |
| 98 | |
| 99 | scopeFetcher := opts.ScopeFetcher |
| 100 | if scopeFetcher == nil { |
| 101 | scopeFetcher = scopes.NewFetcher(apiHost, scopes.FetcherOptions{}) |
| 102 | } |
| 103 | |
| 104 | inventoryFactory := opts.InventoryFactory |
| 105 | if inventoryFactory == nil { |
| 106 | inventoryFactory = DefaultInventoryFactory(cfg, t, opts.FeatureChecker, scopeFetcher) |
| 107 | } |
| 108 | |
| 109 | // Create a shared schema cache to avoid repeated JSON schema reflection |
| 110 | // when a new MCP Server is created per request in stateless mode. |
| 111 | schemaCache := mcp.NewSchemaCache() |
| 112 | |
| 113 | return &Handler{ |
| 114 | ctx: ctx, |
| 115 | config: cfg, |
| 116 | deps: deps, |
| 117 | logger: logger, |
| 118 | apiHosts: apiHost, |
| 119 | t: t, |
| 120 | githubMcpServerFactory: githubMcpServerFactory, |
| 121 | inventoryFactoryFunc: inventoryFactory, |
| 122 | oauthCfg: opts.OAuthConfig, |
| 123 | scopeFetcher: scopeFetcher, |
| 124 | schemaCache: schemaCache, |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | func (h *Handler) RegisterMiddleware(r chi.Router) { |
| 129 | r.Use( |