@@ -7,12 +7,12 @@ import (
77 "log/slog"
88 "net/http"
99 "net/http/httptest"
10+ "net/url"
1011 "testing"
1112
1213 "github.com/github/github-mcp-server/internal/oauth"
1314 "github.com/github/github-mcp-server/pkg/github"
1415 "github.com/github/github-mcp-server/pkg/http/headers"
15- "github.com/github/github-mcp-server/pkg/utils"
1616 "github.com/google/jsonschema-go/jsonschema"
1717 "github.com/modelcontextprotocol/go-sdk/mcp"
1818 "github.com/stretchr/testify/assert"
@@ -23,6 +23,108 @@ func discardLogger() *slog.Logger {
2323 return slog .New (slog .NewTextHandler (io .Discard , nil ))
2424}
2525
26+ func TestCreateGitHubClientsScopesRESTAndRawTokens (t * testing.T ) {
27+ t .Parallel ()
28+
29+ var foreignAuth string
30+ foreign := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
31+ foreignAuth = r .Header .Get (headers .AuthorizationHeader )
32+ w .WriteHeader (http .StatusOK )
33+ }))
34+ defer foreign .Close ()
35+
36+ var sourceAuth string
37+ source := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
38+ sourceAuth = r .Header .Get (headers .AuthorizationHeader )
39+ http .Redirect (w , r , foreign .URL , http .StatusFound )
40+ }))
41+ defer source .Close ()
42+
43+ tests := []struct {
44+ name string
45+ cfg github.MCPServerConfig
46+ }{
47+ {
48+ name : "static token" ,
49+ cfg : github.MCPServerConfig {
50+ Version : "test" ,
51+ Token : "static-token" ,
52+ },
53+ },
54+ {
55+ name : "token provider" ,
56+ cfg : github.MCPServerConfig {
57+ Version : "test" ,
58+ TokenProvider : func () string { return "provider-token" },
59+ },
60+ },
61+ }
62+
63+ for _ , tt := range tests {
64+ t .Run (tt .name , func (t * testing.T ) {
65+ apiHost := newStaticAPIHostResolver (t , source .URL )
66+ clients , err := createGitHubClients (tt .cfg , apiHost )
67+ require .NoError (t , err )
68+
69+ sourceAuth = ""
70+ foreignAuth = ""
71+ resp , err := clients .rest .Client ().Get (source .URL + "/rest" )
72+ require .NoError (t , err )
73+ resp .Body .Close ()
74+ assert .NotEmpty (t , sourceAuth , "REST request must authenticate to the configured host" )
75+ assert .Empty (t , foreignAuth , "REST redirect must not authenticate to a foreign host" )
76+
77+ sourceAuth = ""
78+ foreignAuth = ""
79+ resp , err = clients .raw .GetRawContent (context .Background (), "owner" , "repo" , "file" , nil )
80+ require .NoError (t , err )
81+ resp .Body .Close ()
82+ assert .NotEmpty (t , sourceAuth , "raw request must authenticate to the configured host" )
83+ assert .Empty (t , foreignAuth , "raw redirect must not authenticate to a foreign host" )
84+ })
85+ }
86+ }
87+
88+ type staticAPIHostResolver struct {
89+ restURL * url.URL
90+ graphQLURL * url.URL
91+ uploadURL * url.URL
92+ rawURL * url.URL
93+ }
94+
95+ func newStaticAPIHostResolver (t * testing.T , endpoint string ) staticAPIHostResolver {
96+ t .Helper ()
97+
98+ u , err := url .Parse (endpoint )
99+ require .NoError (t , err )
100+ return staticAPIHostResolver {
101+ restURL : u ,
102+ graphQLURL : u ,
103+ uploadURL : u ,
104+ rawURL : u ,
105+ }
106+ }
107+
108+ func (r staticAPIHostResolver ) BaseRESTURL (context.Context ) (* url.URL , error ) {
109+ return r .restURL , nil
110+ }
111+
112+ func (r staticAPIHostResolver ) GraphqlURL (context.Context ) (* url.URL , error ) {
113+ return r .graphQLURL , nil
114+ }
115+
116+ func (r staticAPIHostResolver ) UploadURL (context.Context ) (* url.URL , error ) {
117+ return r .uploadURL , nil
118+ }
119+
120+ func (r staticAPIHostResolver ) RawURL (context.Context ) (* url.URL , error ) {
121+ return r .rawURL , nil
122+ }
123+
124+ func (r staticAPIHostResolver ) AuthorizationServerURL (context.Context ) (* url.URL , error ) {
125+ return r .restURL , nil
126+ }
127+
26128// probeToolName is the name of the throwaway tool the harness registers; its
27129// handler runs a probe closure against a sessionPrompter so the adapter can be
28130// exercised against a real, fully-negotiated server session from the client side.
@@ -583,8 +685,7 @@ func TestCreateGitHubClientsTokenProvider(t *testing.T) {
583685 defer server .Close ()
584686
585687 current := ""
586- apiHost , err := utils .NewAPIHost (server .URL )
587- require .NoError (t , err )
688+ apiHost := newStaticAPIHostResolver (t , server .URL )
588689
589690 clients , err := createGitHubClients (github.MCPServerConfig {
590691 Version : "test" ,
0 commit comments