createGitHubClients creates all the GitHub API clients needed by the server.
(cfg github.MCPServerConfig, apiHost utils.APIHostResolver)
| 42 | |
| 43 | // createGitHubClients creates all the GitHub API clients needed by the server. |
| 44 | func createGitHubClients(cfg github.MCPServerConfig, apiHost utils.APIHostResolver) (*githubClients, error) { |
| 45 | restURL, err := apiHost.BaseRESTURL(context.Background()) |
| 46 | if err != nil { |
| 47 | return nil, fmt.Errorf("failed to get base REST URL: %w", err) |
| 48 | } |
| 49 | |
| 50 | uploadURL, err := apiHost.UploadURL(context.Background()) |
| 51 | if err != nil { |
| 52 | return nil, fmt.Errorf("failed to get upload URL: %w", err) |
| 53 | } |
| 54 | |
| 55 | graphQLURL, err := apiHost.GraphqlURL(context.Background()) |
| 56 | if err != nil { |
| 57 | return nil, fmt.Errorf("failed to get GraphQL URL: %w", err) |
| 58 | } |
| 59 | |
| 60 | rawURL, err := apiHost.RawURL(context.Background()) |
| 61 | if err != nil { |
| 62 | return nil, fmt.Errorf("failed to get Raw URL: %w", err) |
| 63 | } |
| 64 | |
| 65 | // Construct REST client. When a TokenProvider is configured (OAuth), we |
| 66 | // authenticate via BearerAuthTransport and skip go-github's WithAuthToken: |
| 67 | // the latter installs its own round tripper that would pin the static token |
| 68 | // and shadow the dynamic one. |
| 69 | restUATransport := &transport.UserAgentTransport{ |
| 70 | Transport: http.DefaultTransport, |
| 71 | Agent: fmt.Sprintf("github-mcp-server/%s", cfg.Version), |
| 72 | } |
| 73 | var restClient *gogithub.Client |
| 74 | if cfg.TokenProvider != nil { |
| 75 | restClient, err = gogithub.NewClient( |
| 76 | gogithub.WithHTTPClient(&http.Client{Transport: &transport.BearerAuthTransport{ |
| 77 | Transport: restUATransport, |
| 78 | TokenProvider: cfg.TokenProvider, |
| 79 | }}), |
| 80 | gogithub.WithEnterpriseURLs(restURL.String(), uploadURL.String()), |
| 81 | ) |
| 82 | } else { |
| 83 | restClient, err = gogithub.NewClient( |
| 84 | gogithub.WithHTTPClient(&http.Client{Transport: restUATransport}), |
| 85 | gogithub.WithAuthToken(cfg.Token), |
| 86 | gogithub.WithEnterpriseURLs(restURL.String(), uploadURL.String()), |
| 87 | ) |
| 88 | } |
| 89 | if err != nil { |
| 90 | return nil, fmt.Errorf("failed to create REST client: %w", err) |
| 91 | } |
| 92 | |
| 93 | // Construct GraphQL client |
| 94 | // We use NewEnterpriseClient unconditionally since we already parsed the API host |
| 95 | gqlHTTPClient := &http.Client{ |
| 96 | Transport: &transport.BearerAuthTransport{ |
| 97 | Transport: &transport.GraphQLFeaturesTransport{ |
| 98 | Transport: http.DefaultTransport, |
| 99 | }, |
| 100 | Token: cfg.Token, |
| 101 | TokenProvider: cfg.TokenProvider, |