Skip to content

Commit d9e9bae

Browse files
committed
forgotten files
1 parent e91a875 commit d9e9bae

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

pkg/http/headers/parse.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package headers
2+
3+
import "strings"
4+
5+
// ParseCommaSeparated splits a header value by comma, trims whitespace,
6+
// and filters out empty values
7+
func ParseCommaSeparated(value string) []string {
8+
if value == "" {
9+
return []string{}
10+
}
11+
12+
parts := strings.Split(value, ",")
13+
result := make([]string, 0, len(parts))
14+
for _, p := range parts {
15+
trimmed := strings.TrimSpace(p)
16+
if trimmed != "" {
17+
result = append(result, trimmed)
18+
}
19+
}
20+
return result
21+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package middleware
2+
3+
import (
4+
"net/http"
5+
"slices"
6+
"strings"
7+
8+
ghcontext "github.com/github/github-mcp-server/pkg/context"
9+
"github.com/github/github-mcp-server/pkg/http/headers"
10+
)
11+
12+
// WithRequestConfig is a middleware that extracts MCP-related headers and sets them in the request context
13+
func WithRequestConfig(next http.Handler) http.Handler {
14+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15+
ctx := r.Context()
16+
17+
// Only set from headers if not already set in ctx
18+
if !ghcontext.IsReadonly(ctx) {
19+
if relaxedParseBool(r.Header.Get(headers.MCPReadOnlyHeader)) {
20+
ctx = ghcontext.WithReadonly(ctx, true)
21+
}
22+
}
23+
24+
if len(ghcontext.GetToolsets(ctx)) == 0 {
25+
if toolsets := headers.ParseCommaSeparated(r.Header.Get(headers.MCPToolsetsHeader)); len(toolsets) > 0 {
26+
ctx = ghcontext.WithToolsets(ctx, toolsets)
27+
}
28+
}
29+
30+
next.ServeHTTP(w, r.WithContext(ctx))
31+
})
32+
}
33+
34+
// relaxedParseBool parses a string into a boolean value, treating various
35+
// common false values or empty strings as false, and everything else as true.
36+
// It is case-insensitive and trims whitespace.
37+
func relaxedParseBool(s string) bool {
38+
s = strings.TrimSpace(strings.ToLower(s))
39+
falseValues := []string{"", "false", "0", "no", "off", "n", "f"}
40+
return !slices.Contains(falseValues, s)
41+
}

0 commit comments

Comments
 (0)