@@ -12,6 +12,7 @@ import (
1212 "os/signal"
1313 "strings"
1414 "syscall"
15+ "time"
1516
1617 "github.com/github/github-mcp-server/pkg/errors"
1718 "github.com/github/github-mcp-server/pkg/github"
@@ -367,7 +368,18 @@ func newGHESHost(hostname string) (apiHost, error) {
367368 if err != nil {
368369 return apiHost {}, fmt .Errorf ("failed to parse GHES Upload URL: %w" , err )
369370 }
370- rawURL , err := url .Parse (fmt .Sprintf ("%s://%s/raw/" , u .Scheme , u .Hostname ()))
371+
372+ // Check if subdomain isolation is enabled
373+ hasSubdomainIsolation := checkSubdomainIsolation (u .Scheme , u .Hostname ())
374+
375+ var rawURL * url.URL
376+ if hasSubdomainIsolation {
377+ // With subdomain isolation: https://raw.hostname/
378+ rawURL , err = url .Parse (fmt .Sprintf ("%s://raw.%s/" , u .Scheme , u .Hostname ()))
379+ } else {
380+ // Without subdomain isolation: https://hostname/raw/
381+ rawURL , err = url .Parse (fmt .Sprintf ("%s://%s/raw/" , u .Scheme , u .Hostname ()))
382+ }
371383 if err != nil {
372384 return apiHost {}, fmt .Errorf ("failed to parse GHES Raw URL: %w" , err )
373385 }
@@ -380,6 +392,31 @@ func newGHESHost(hostname string) (apiHost, error) {
380392 }, nil
381393}
382394
395+ // checkSubdomainIsolation detects if GitHub Enterprise Server has subdomain isolation enabled
396+ // by attempting to ping the raw._ping endpoint on the subdomain.
397+ // Returns true if subdomain isolation is detected, false otherwise.
398+ func checkSubdomainIsolation (scheme , hostname string ) bool {
399+ // Try the subdomain isolation URL first: https://raw.hostname/_ping
400+ subdomainURL := fmt .Sprintf ("%s://raw.%s/_ping" , scheme , hostname )
401+
402+ client := & http.Client {
403+ Timeout : 5 * time .Second ,
404+ // Don't follow redirects - we just want to check if the endpoint exists
405+ CheckRedirect : func (req * http.Request , via []* http.Request ) error {
406+ return http .ErrUseLastResponse
407+ },
408+ }
409+
410+ resp , err := client .Get (subdomainURL )
411+ if err != nil {
412+ // If we can't reach the subdomain, assume no subdomain isolation
413+ return false
414+ }
415+ defer resp .Body .Close ()
416+
417+ return resp .StatusCode == http .StatusOK
418+ }
419+
383420// Note that this does not handle ports yet, so development environments are out.
384421func parseAPIHost (s string ) (apiHost , error ) {
385422 if s == "" {
0 commit comments