Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/github-mcp-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ var (
Short: "Start HTTP server",
Long: `Start an HTTP server that listens for MCP requests over HTTP.`,
RunE: func(_ *cobra.Command, _ []string) error {
ttl := viper.GetDuration("repo-access-cache-ttl")
httpConfig := ghhttp.HTTPServerConfig{
Version: version,
Host: viper.GetString("host"),
Expand All @@ -104,6 +105,8 @@ var (
EnableCommandLogging: viper.GetBool("enable-command-logging"),
LogFilePath: viper.GetString("log-file"),
ContentWindowSize: viper.GetInt("content-window-size"),
LockdownMode: viper.GetBool("lockdown-mode"),
RepoAccessCacheTTL: &ttl,
}

return ghhttp.RunHTTPServer(httpConfig)
Expand Down
16 changes: 16 additions & 0 deletions pkg/context/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,19 @@ func GetTools(ctx context.Context) []string {
}
return nil
}

// lockdownCtxKey is a context key for lockdown mode
type lockdownCtxKey struct{}

// WithLockdownMode adds lockdown mode state to the context
func WithLockdownMode(ctx context.Context, enabled bool) context.Context {
return context.WithValue(ctx, lockdownCtxKey{}, enabled)
}

// IsLockdownMode retrieves the lockdown mode state from the context
func IsLockdownMode(ctx context.Context) bool {
if enabled, ok := ctx.Value(lockdownCtxKey{}).(bool); ok {
return enabled
}
return false
}
12 changes: 7 additions & 5 deletions pkg/github/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ type ToolDependencies interface {
GetT() translations.TranslationHelperFunc

// GetFlags returns feature flags
GetFlags() FeatureFlags
GetFlags(ctx context.Context) FeatureFlags

// GetContentWindowSize returns the content window size for log truncation
GetContentWindowSize() int
Expand Down Expand Up @@ -165,7 +165,7 @@ func (d BaseDeps) GetRepoAccessCache(_ context.Context) (*lockdown.RepoAccessCac
func (d BaseDeps) GetT() translations.TranslationHelperFunc { return d.T }

// GetFlags implements ToolDependencies.
func (d BaseDeps) GetFlags() FeatureFlags { return d.Flags }
func (d BaseDeps) GetFlags(_ context.Context) FeatureFlags { return d.Flags }

// GetContentWindowSize implements ToolDependencies.
func (d BaseDeps) GetContentWindowSize() int { return d.ContentWindowSize }
Expand Down Expand Up @@ -262,7 +262,6 @@ func NewRequestDeps(
lockdownMode bool,
repoAccessOpts []lockdown.RepoAccessOption,
t translations.TranslationHelperFunc,
flags FeatureFlags,
contentWindowSize int,
featureChecker inventory.FeatureFlagChecker,
) *RequestDeps {
Expand All @@ -272,7 +271,6 @@ func NewRequestDeps(
lockdownMode: lockdownMode,
RepoAccessOpts: repoAccessOpts,
T: t,
Flags: flags,
ContentWindowSize: contentWindowSize,
featureChecker: featureChecker,
}
Expand Down Expand Up @@ -379,7 +377,11 @@ func (d *RequestDeps) GetRepoAccessCache(ctx context.Context) (*lockdown.RepoAcc
func (d *RequestDeps) GetT() translations.TranslationHelperFunc { return d.T }

// GetFlags implements ToolDependencies.
func (d *RequestDeps) GetFlags() FeatureFlags { return d.Flags }
func (d *RequestDeps) GetFlags(ctx context.Context) FeatureFlags {
return FeatureFlags{
LockdownMode: d.lockdownMode && ghcontext.IsLockdownMode(ctx),
}
}

// GetContentWindowSize implements ToolDependencies.
func (d *RequestDeps) GetContentWindowSize() int { return d.ContentWindowSize }
Expand Down
2 changes: 1 addition & 1 deletion pkg/github/feature_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func HelloWorldTool(t translations.TranslationHelperFunc) inventory.ServerTool {
if deps.IsFeatureEnabled(ctx, RemoteMCPEnthusiasticGreeting) {
greeting += " Welcome to the future of MCP! 🎉"
}
if deps.GetFlags().InsiderMode {
if deps.GetFlags(ctx).InsiderMode {
greeting += " Experimental features are enabled! 🚀"
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/github/issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ func GetIssue(ctx context.Context, client *github.Client, deps ToolDependencies,
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
flags := deps.GetFlags()
flags := deps.GetFlags(ctx)

issue, resp, err := client.Issues.Get(ctx, owner, repo, issueNumber)
if err != nil {
Expand Down Expand Up @@ -389,7 +389,7 @@ func GetIssueComments(ctx context.Context, client *github.Client, deps ToolDepen
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
flags := deps.GetFlags()
flags := deps.GetFlags(ctx)

opts := &github.IssueListCommentsOptions{
ListOptions: github.ListOptions{
Expand Down Expand Up @@ -449,7 +449,7 @@ func GetSubIssues(ctx context.Context, client *github.Client, deps ToolDependenc
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
featureFlags := deps.GetFlags()
featureFlags := deps.GetFlags(ctx)

opts := &github.IssueListOptions{
ListOptions: github.ListOptions{
Expand Down
6 changes: 3 additions & 3 deletions pkg/github/pullrequests.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func GetPullRequest(ctx context.Context, client *github.Client, deps ToolDepende
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
ff := deps.GetFlags()
ff := deps.GetFlags(ctx)

pr, resp, err := client.PullRequests.Get(ctx, owner, repo, pullNumber)
if err != nil {
Expand Down Expand Up @@ -350,7 +350,7 @@ func GetPullRequestReviewComments(ctx context.Context, gqlClient *githubv4.Clien
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
ff := deps.GetFlags()
ff := deps.GetFlags(ctx)

// Convert pagination parameters to GraphQL format
gqlParams, err := pagination.ToGraphQLParams()
Expand Down Expand Up @@ -437,7 +437,7 @@ func GetPullRequestReviews(ctx context.Context, client *github.Client, deps Tool
if err != nil {
return nil, fmt.Errorf("failed to get repo access cache: %w", err)
}
ff := deps.GetFlags()
ff := deps.GetFlags(ctx)

reviews, resp, err := client.PullRequests.ListReviews(ctx, owner, repo, pullNumber, nil)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/github/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
return nil, nil
}

func (s stubDeps) GetRepoAccessCache(ctx context.Context) (*lockdown.RepoAccessCache, error) {

Check failure on line 55 in pkg/github/server_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
return s.repoAccessCache, nil
}
func (s stubDeps) GetT() translations.TranslationHelperFunc { return s.t }
func (s stubDeps) GetFlags() FeatureFlags { return s.flags }
func (s stubDeps) GetFlags(ctx context.Context) FeatureFlags { return s.flags }

Check failure on line 59 in pkg/github/server_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
func (s stubDeps) GetContentWindowSize() int { return s.contentWindowSize }
func (s stubDeps) IsFeatureEnabled(_ context.Context, _ string) bool { return false }

Expand Down
2 changes: 2 additions & 0 deletions pkg/http/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const (
MCPToolsetsHeader = "X-MCP-Toolsets"
// MCPToolsHeader is a comma-separated list of MCP tools that the request is for.
MCPToolsHeader = "X-MCP-Tools"
// MCPLockdownHeader indicates whether lockdown mode is enabled.
MCPLockdownHeader = "X-MCP-Lockdown"
// MCPFeaturesHeader is a comma-separated list of feature flags to enable.
MCPFeaturesHeader = "X-MCP-Features"
)
4 changes: 4 additions & 0 deletions pkg/http/middleware/request_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ func WithRequestConfig(next http.Handler) http.Handler {
ctx = ghcontext.WithTools(ctx, tools)
}

if relaxedParseBool(r.Header.Get(headers.MCPLockdownHeader)) {
ctx = ghcontext.WithLockdownMode(ctx, true)
}

next.ServeHTTP(w, r.WithContext(ctx))
})
}
Expand Down
3 changes: 0 additions & 3 deletions pkg/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"github.com/go-chi/chi/v5"
)

type HTTPServerConfig struct {

Check failure on line 21 in pkg/http/server.go

View workflow job for this annotation

GitHub Actions / lint

exported: type name will be used as http.HTTPServerConfig by other packages, and that stutters; consider calling this ServerConfig (revive)
// Version of the server
Version string

Expand Down Expand Up @@ -89,9 +89,6 @@
cfg.LockdownMode,
repoAccessOpts,
t,
github.FeatureFlags{
LockdownMode: cfg.LockdownMode,
},
cfg.ContentWindowSize,
nil,
)
Expand Down
Loading