From 302c35b0bb26df9161a9b4e84fb6a3b31d8981a2 Mon Sep 17 00:00:00 2001 From: Iryna Kulakova Date: Tue, 21 Apr 2026 14:00:28 +0200 Subject: [PATCH 1/7] Fix Content-Type rejection for application/json; charset=utf-8 Add NormalizeContentType middleware that strips optional parameters (e.g. charset=utf-8) from application/json Content-Type headers before the request reaches the Go SDK's StreamableHTTP handler, which performs strict string matching. Per RFC 8259, the charset parameter is redundant for JSON but must be accepted per HTTP semantics. Fixes #2333 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- pkg/http/handler.go | 1 + pkg/http/handler_test.go | 96 ++++++++++++++++++++++++ pkg/http/middleware/content_type.go | 29 +++++++ pkg/http/middleware/content_type_test.go | 72 ++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 pkg/http/middleware/content_type.go create mode 100644 pkg/http/middleware/content_type_test.go diff --git a/pkg/http/handler.go b/pkg/http/handler.go index d55d7c53d7..3314ece080 100644 --- a/pkg/http/handler.go +++ b/pkg/http/handler.go @@ -127,6 +127,7 @@ func NewHTTPMcpHandler( func (h *Handler) RegisterMiddleware(r chi.Router) { r.Use( + middleware.NormalizeContentType, middleware.ExtractUserToken(h.oauthCfg), middleware.WithRequestConfig, middleware.WithMCPParse(), diff --git a/pkg/http/handler_test.go b/pkg/http/handler_test.go index 5c8543c852..56495d26b1 100644 --- a/pkg/http/handler_test.go +++ b/pkg/http/handler_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "slices" "sort" + "strings" "testing" ghcontext "github.com/github/github-mcp-server/pkg/context" @@ -631,6 +632,101 @@ func TestStaticConfigEnforcement(t *testing.T) { } } +// TestContentTypeHandling verifies that the MCP StreamableHTTP handler +// accepts Content-Type values with additional parameters like charset=utf-8. +// This is a regression test for https://github.com/github/github-mcp-server/issues/2333 +// where the Go SDK performs strict string matching against "application/json" +// and rejects requests with "application/json; charset=utf-8". +func TestContentTypeHandling(t *testing.T) { + tests := []struct { + name string + contentType string + expectUnsupportedMedia bool + }{ + { + name: "exact application/json is accepted", + contentType: "application/json", + expectUnsupportedMedia: false, + }, + { + name: "application/json with charset=utf-8 should be accepted", + contentType: "application/json; charset=utf-8", + expectUnsupportedMedia: false, + }, + { + name: "application/json with charset=UTF-8 should be accepted", + contentType: "application/json; charset=UTF-8", + expectUnsupportedMedia: false, + }, + { + name: "completely wrong content type is rejected", + contentType: "text/plain", + expectUnsupportedMedia: true, + }, + { + name: "empty content type is rejected", + contentType: "", + expectUnsupportedMedia: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a minimal MCP server factory + mcpServerFactory := func(_ *http.Request, _ github.ToolDependencies, _ *inventory.Inventory, _ *github.MCPServerConfig) (*mcp.Server, error) { + return mcp.NewServer(&mcp.Implementation{Name: "test", Version: "0.0.1"}, nil), nil + } + + // Create a simple inventory factory + inventoryFactory := func(_ *http.Request) (*inventory.Inventory, error) { + return inventory.NewBuilder(). + SetTools(testTools()). + WithToolsets([]string{"all"}). + Build() + } + + apiHost, err := utils.NewAPIHost("https://api.github.com") + require.NoError(t, err) + + handler := NewHTTPMcpHandler( + context.Background(), + &ServerConfig{Version: "test"}, + nil, + translations.NullTranslationHelper, + slog.Default(), + apiHost, + WithInventoryFactory(inventoryFactory), + WithGitHubMCPServerFactory(mcpServerFactory), + WithScopeFetcher(allScopesFetcher{}), + ) + + r := chi.NewRouter() + handler.RegisterMiddleware(r) + handler.RegisterRoutes(r) + + // Send an MCP initialize request as a POST with the given Content-Type + body := `{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}` + req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body)) + req.Header.Set(headers.AuthorizationHeader, "Bearer ghp_testtoken") + req.Header.Set("Accept", "application/json, text/event-stream") + if tt.contentType != "" { + req.Header.Set(headers.ContentTypeHeader, tt.contentType) + } + + rr := httptest.NewRecorder() + r.ServeHTTP(rr, req) + + if tt.expectUnsupportedMedia { + assert.Equal(t, http.StatusUnsupportedMediaType, rr.Code, + "expected 415 Unsupported Media Type for Content-Type: %q", tt.contentType) + } else { + assert.NotEqual(t, http.StatusUnsupportedMediaType, rr.Code, + "should not get 415 for Content-Type: %q, got status %d", tt.contentType, rr.Code) + } + }) + } +} + // buildStaticInventoryFromTools is a test helper that mirrors buildStaticInventory // but uses the provided mock tools instead of calling github.AllTools. func buildStaticInventoryFromTools(cfg *ServerConfig, tools []inventory.ServerTool, featureChecker inventory.FeatureFlagChecker) ([]inventory.ServerTool, []inventory.ServerResourceTemplate, []inventory.ServerPrompt) { diff --git a/pkg/http/middleware/content_type.go b/pkg/http/middleware/content_type.go new file mode 100644 index 0000000000..b5e7359974 --- /dev/null +++ b/pkg/http/middleware/content_type.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "mime" + "net/http" +) + +// NormalizeContentType is a middleware that normalizes the Content-Type header +// by stripping optional parameters (e.g. charset=utf-8) when the media type +// is "application/json". This works around strict Content-Type matching in +// the Go MCP SDK's StreamableHTTP handler which rejects valid JSON media +// types that include parameters. +// +// Per RFC 8259, JSON text exchanged between systems that are not part of a +// closed ecosystem MUST be encoded using UTF-8, so the charset parameter is +// redundant but MUST be accepted per HTTP semantics. +// +// See: https://github.com/github/github-mcp-server/issues/2333 +func NormalizeContentType(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if ct := r.Header.Get("Content-Type"); ct != "" { + mediaType, _, err := mime.ParseMediaType(ct) + if err == nil && mediaType == "application/json" { + r.Header.Set("Content-Type", "application/json") + } + } + next.ServeHTTP(w, r) + }) +} diff --git a/pkg/http/middleware/content_type_test.go b/pkg/http/middleware/content_type_test.go new file mode 100644 index 0000000000..838b7499b6 --- /dev/null +++ b/pkg/http/middleware/content_type_test.go @@ -0,0 +1,72 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNormalizeContentType(t *testing.T) { + tests := []struct { + name string + inputCT string + expectedCT string + }{ + { + name: "exact application/json unchanged", + inputCT: "application/json", + expectedCT: "application/json", + }, + { + name: "strips charset=utf-8", + inputCT: "application/json; charset=utf-8", + expectedCT: "application/json", + }, + { + name: "strips charset=UTF-8", + inputCT: "application/json; charset=UTF-8", + expectedCT: "application/json", + }, + { + name: "strips multiple parameters", + inputCT: "application/json; charset=utf-8; boundary=something", + expectedCT: "application/json", + }, + { + name: "non-json content type left unchanged", + inputCT: "text/plain; charset=utf-8", + expectedCT: "text/plain; charset=utf-8", + }, + { + name: "text/event-stream left unchanged", + inputCT: "text/event-stream", + expectedCT: "text/event-stream", + }, + { + name: "empty content type left unchanged", + inputCT: "", + expectedCT: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var capturedCT string + inner := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { + capturedCT = r.Header.Get("Content-Type") + }) + + handler := NormalizeContentType(inner) + req := httptest.NewRequest(http.MethodPost, "/", nil) + if tt.inputCT != "" { + req.Header.Set("Content-Type", tt.inputCT) + } + + handler.ServeHTTP(httptest.NewRecorder(), req) + + assert.Equal(t, tt.expectedCT, capturedCT) + }) + } +} From eb231365bb9ece99bdb5c4075feafbb6927d7cf7 Mon Sep 17 00:00:00 2001 From: Iryna Kulakova Date: Tue, 21 Apr 2026 14:13:50 +0200 Subject: [PATCH 2/7] Bump go-sdk to 27f29c1 (Content-Type media type parsing fix) Upgrades github.com/modelcontextprotocol/go-sdk from v1.5.0 to v1.5.1-0.20260403154220-27f29c1cef3b which includes proper media type parsing for Content-Type headers, fixing the strict string matching that rejected application/json; charset=utf-8. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 4440a03eaa..89cafc377d 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/josephburnett/jd/v2 v2.5.0 github.com/lithammer/fuzzysearch v1.1.8 github.com/microcosm-cc/bluemonday v1.0.27 - github.com/modelcontextprotocol/go-sdk v1.5.0 + github.com/modelcontextprotocol/go-sdk v1.5.1-0.20260403154220-27f29c1cef3b github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7 github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 diff --git a/go.sum b/go.sum index 2d66c84ed7..62b83740ee 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwX github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/modelcontextprotocol/go-sdk v1.5.0 h1:CHU0FIX9kpueNkxuYtfYQn1Z0slhFzBZuq+x6IiblIU= github.com/modelcontextprotocol/go-sdk v1.5.0/go.mod h1:gggDIhoemhWs3BGkGwd1umzEXCEMMvAnhTrnbXJKKKA= +github.com/modelcontextprotocol/go-sdk v1.5.1-0.20260403154220-27f29c1cef3b h1:mB8zdpP8SX1TEqnEZpV2hHD30EQXivsZl4AP9hgm7F8= +github.com/modelcontextprotocol/go-sdk v1.5.1-0.20260403154220-27f29c1cef3b/go.mod h1:gggDIhoemhWs3BGkGwd1umzEXCEMMvAnhTrnbXJKKKA= github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 h1:31Y+Yu373ymebRdJN1cWLLooHH8xAr0MhKTEJGV/87g= github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021/go.mod h1:WERUkUryfUWlrHnFSO/BEUZ+7Ns8aZy7iVOGewxKzcc= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= From d3985f7ad65c7e203286c8177c744130cc2adc42 Mon Sep 17 00:00:00 2001 From: Iryna Kulakova Date: Tue, 21 Apr 2026 14:14:54 +0200 Subject: [PATCH 3/7] Remove NormalizeContentType middleware workaround The go-sdk bump (27f29c1) includes the proper fix upstream, making the middleware unnecessary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- pkg/http/handler.go | 1 - pkg/http/middleware/content_type.go | 29 ---------- pkg/http/middleware/content_type_test.go | 72 ------------------------ 3 files changed, 102 deletions(-) delete mode 100644 pkg/http/middleware/content_type.go delete mode 100644 pkg/http/middleware/content_type_test.go diff --git a/pkg/http/handler.go b/pkg/http/handler.go index 3314ece080..d55d7c53d7 100644 --- a/pkg/http/handler.go +++ b/pkg/http/handler.go @@ -127,7 +127,6 @@ func NewHTTPMcpHandler( func (h *Handler) RegisterMiddleware(r chi.Router) { r.Use( - middleware.NormalizeContentType, middleware.ExtractUserToken(h.oauthCfg), middleware.WithRequestConfig, middleware.WithMCPParse(), diff --git a/pkg/http/middleware/content_type.go b/pkg/http/middleware/content_type.go deleted file mode 100644 index b5e7359974..0000000000 --- a/pkg/http/middleware/content_type.go +++ /dev/null @@ -1,29 +0,0 @@ -package middleware - -import ( - "mime" - "net/http" -) - -// NormalizeContentType is a middleware that normalizes the Content-Type header -// by stripping optional parameters (e.g. charset=utf-8) when the media type -// is "application/json". This works around strict Content-Type matching in -// the Go MCP SDK's StreamableHTTP handler which rejects valid JSON media -// types that include parameters. -// -// Per RFC 8259, JSON text exchanged between systems that are not part of a -// closed ecosystem MUST be encoded using UTF-8, so the charset parameter is -// redundant but MUST be accepted per HTTP semantics. -// -// See: https://github.com/github/github-mcp-server/issues/2333 -func NormalizeContentType(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if ct := r.Header.Get("Content-Type"); ct != "" { - mediaType, _, err := mime.ParseMediaType(ct) - if err == nil && mediaType == "application/json" { - r.Header.Set("Content-Type", "application/json") - } - } - next.ServeHTTP(w, r) - }) -} diff --git a/pkg/http/middleware/content_type_test.go b/pkg/http/middleware/content_type_test.go deleted file mode 100644 index 838b7499b6..0000000000 --- a/pkg/http/middleware/content_type_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package middleware - -import ( - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNormalizeContentType(t *testing.T) { - tests := []struct { - name string - inputCT string - expectedCT string - }{ - { - name: "exact application/json unchanged", - inputCT: "application/json", - expectedCT: "application/json", - }, - { - name: "strips charset=utf-8", - inputCT: "application/json; charset=utf-8", - expectedCT: "application/json", - }, - { - name: "strips charset=UTF-8", - inputCT: "application/json; charset=UTF-8", - expectedCT: "application/json", - }, - { - name: "strips multiple parameters", - inputCT: "application/json; charset=utf-8; boundary=something", - expectedCT: "application/json", - }, - { - name: "non-json content type left unchanged", - inputCT: "text/plain; charset=utf-8", - expectedCT: "text/plain; charset=utf-8", - }, - { - name: "text/event-stream left unchanged", - inputCT: "text/event-stream", - expectedCT: "text/event-stream", - }, - { - name: "empty content type left unchanged", - inputCT: "", - expectedCT: "", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var capturedCT string - inner := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { - capturedCT = r.Header.Get("Content-Type") - }) - - handler := NormalizeContentType(inner) - req := httptest.NewRequest(http.MethodPost, "/", nil) - if tt.inputCT != "" { - req.Header.Set("Content-Type", tt.inputCT) - } - - handler.ServeHTTP(httptest.NewRecorder(), req) - - assert.Equal(t, tt.expectedCT, capturedCT) - }) - } -} From 6ec21b0914da18380dc8faef6523ab625bdf2f5c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Apr 2026 12:16:23 +0000 Subject: [PATCH 4/7] chore: regenerate license files Auto-generated by license-check workflow --- third-party-licenses.darwin.md | 4 ++-- third-party-licenses.linux.md | 4 ++-- third-party-licenses.windows.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/third-party-licenses.darwin.md b/third-party-licenses.darwin.md index e8d9822218..2e5ca59ec2 100644 --- a/third-party-licenses.darwin.md +++ b/third-party-licenses.darwin.md @@ -24,8 +24,8 @@ The following packages are included for the amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) diff --git a/third-party-licenses.linux.md b/third-party-licenses.linux.md index c4474fced3..d818469896 100644 --- a/third-party-licenses.linux.md +++ b/third-party-licenses.linux.md @@ -24,8 +24,8 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) diff --git a/third-party-licenses.windows.md b/third-party-licenses.windows.md index 3f36d5127c..6efed3338c 100644 --- a/third-party-licenses.windows.md +++ b/third-party-licenses.windows.md @@ -25,8 +25,8 @@ The following packages are included for the 386, amd64, arm64 architectures. - [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE)) - [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE)) - [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) - - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.5.0/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) + - [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/27f29c1cef3b/LICENSE)) - [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt)) - [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE)) - [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE)) From 452637d963384d7b6ab806aba61e8c9c944fb43d Mon Sep 17 00:00:00 2001 From: Adam Holt Date: Tue, 21 Apr 2026 14:19:42 +0200 Subject: [PATCH 5/7] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/http/handler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/http/handler_test.go b/pkg/http/handler_test.go index 56495d26b1..aeda12f424 100644 --- a/pkg/http/handler_test.go +++ b/pkg/http/handler_test.go @@ -708,7 +708,7 @@ func TestContentTypeHandling(t *testing.T) { body := `{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}` req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body)) req.Header.Set(headers.AuthorizationHeader, "Bearer ghp_testtoken") - req.Header.Set("Accept", "application/json, text/event-stream") + req.Header.Set(headers.AcceptHeader, strings.Join([]string{headers.ContentTypeJSON, headers.ContentTypeEventStream}, ", ")) if tt.contentType != "" { req.Header.Set(headers.ContentTypeHeader, tt.contentType) } From 709b07db628c664513dbb2869d9320c0cacd94be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 12:41:00 +0000 Subject: [PATCH 6/7] chore: run go mod tidy Agent-Logs-Url: https://github.com/github/github-mcp-server/sessions/49811f97-33b0-476c-8811-419dee2a5318 Co-authored-by: omgitsads <4619+omgitsads@users.noreply.github.com> --- go.sum | 2 -- pkg/http/handler_test.go | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/go.sum b/go.sum index 62b83740ee..615b4e9c0c 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,6 @@ github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8 github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/modelcontextprotocol/go-sdk v1.5.0 h1:CHU0FIX9kpueNkxuYtfYQn1Z0slhFzBZuq+x6IiblIU= -github.com/modelcontextprotocol/go-sdk v1.5.0/go.mod h1:gggDIhoemhWs3BGkGwd1umzEXCEMMvAnhTrnbXJKKKA= github.com/modelcontextprotocol/go-sdk v1.5.1-0.20260403154220-27f29c1cef3b h1:mB8zdpP8SX1TEqnEZpV2hHD30EQXivsZl4AP9hgm7F8= github.com/modelcontextprotocol/go-sdk v1.5.1-0.20260403154220-27f29c1cef3b/go.mod h1:gggDIhoemhWs3BGkGwd1umzEXCEMMvAnhTrnbXJKKKA= github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 h1:31Y+Yu373ymebRdJN1cWLLooHH8xAr0MhKTEJGV/87g= diff --git a/pkg/http/handler_test.go b/pkg/http/handler_test.go index aeda12f424..6b94e5e132 100644 --- a/pkg/http/handler_test.go +++ b/pkg/http/handler_test.go @@ -639,33 +639,33 @@ func TestStaticConfigEnforcement(t *testing.T) { // and rejects requests with "application/json; charset=utf-8". func TestContentTypeHandling(t *testing.T) { tests := []struct { - name string - contentType string + name string + contentType string expectUnsupportedMedia bool }{ { - name: "exact application/json is accepted", - contentType: "application/json", + name: "exact application/json is accepted", + contentType: "application/json", expectUnsupportedMedia: false, }, { - name: "application/json with charset=utf-8 should be accepted", - contentType: "application/json; charset=utf-8", + name: "application/json with charset=utf-8 should be accepted", + contentType: "application/json; charset=utf-8", expectUnsupportedMedia: false, }, { - name: "application/json with charset=UTF-8 should be accepted", - contentType: "application/json; charset=UTF-8", + name: "application/json with charset=UTF-8 should be accepted", + contentType: "application/json; charset=UTF-8", expectUnsupportedMedia: false, }, { - name: "completely wrong content type is rejected", - contentType: "text/plain", + name: "completely wrong content type is rejected", + contentType: "text/plain", expectUnsupportedMedia: true, }, { - name: "empty content type is rejected", - contentType: "", + name: "empty content type is rejected", + contentType: "", expectUnsupportedMedia: true, }, } From ed05d6a56accf0e37d932268f8d8c2c2e30c41ab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 12:41:26 +0000 Subject: [PATCH 7/7] chore: revert unintended handler test formatting Agent-Logs-Url: https://github.com/github/github-mcp-server/sessions/49811f97-33b0-476c-8811-419dee2a5318 Co-authored-by: omgitsads <4619+omgitsads@users.noreply.github.com> --- pkg/http/handler_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/http/handler_test.go b/pkg/http/handler_test.go index 6b94e5e132..aeda12f424 100644 --- a/pkg/http/handler_test.go +++ b/pkg/http/handler_test.go @@ -639,33 +639,33 @@ func TestStaticConfigEnforcement(t *testing.T) { // and rejects requests with "application/json; charset=utf-8". func TestContentTypeHandling(t *testing.T) { tests := []struct { - name string - contentType string + name string + contentType string expectUnsupportedMedia bool }{ { - name: "exact application/json is accepted", - contentType: "application/json", + name: "exact application/json is accepted", + contentType: "application/json", expectUnsupportedMedia: false, }, { - name: "application/json with charset=utf-8 should be accepted", - contentType: "application/json; charset=utf-8", + name: "application/json with charset=utf-8 should be accepted", + contentType: "application/json; charset=utf-8", expectUnsupportedMedia: false, }, { - name: "application/json with charset=UTF-8 should be accepted", - contentType: "application/json; charset=UTF-8", + name: "application/json with charset=UTF-8 should be accepted", + contentType: "application/json; charset=UTF-8", expectUnsupportedMedia: false, }, { - name: "completely wrong content type is rejected", - contentType: "text/plain", + name: "completely wrong content type is rejected", + contentType: "text/plain", expectUnsupportedMedia: true, }, { - name: "empty content type is rejected", - contentType: "", + name: "empty content type is rejected", + contentType: "", expectUnsupportedMedia: true, }, }