Skip to content

Commit 91fcecd

Browse files
committed
feat: add token source flag, gh cli auth
1 parent 614f226 commit 91fcecd

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

cmd/github-mcp-server/main.go

+54-16
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os/signal"
1010
"syscall"
1111

12+
"github.com/cli/go-gh/pkg/auth"
1213
"github.com/github/github-mcp-server/pkg/github"
1314
iolog "github.com/github/github-mcp-server/pkg/log"
1415
"github.com/github/github-mcp-server/pkg/translations"
@@ -24,9 +25,12 @@ var version = "version"
2425
var commit = "commit"
2526
var date = "date"
2627

28+
var root_command_name = "github-mcp-server"
29+
var default_token_source = "env"
30+
2731
var (
2832
rootCmd = &cobra.Command{
29-
Use: "server",
33+
Use: root_command_name,
3034
Short: "GitHub MCP Server",
3135
Long: `A GitHub MCP server that handles various tools and resources.`,
3236
Version: fmt.Sprintf("Version: %s\nCommit: %s\nBuild Date: %s", version, commit, date),
@@ -75,6 +79,7 @@ func init() {
7579
rootCmd.PersistentFlags().Bool("enable-command-logging", false, "When enabled, the server will log all command requests and responses to the log file")
7680
rootCmd.PersistentFlags().Bool("export-translations", false, "Save translations to a JSON file")
7781
rootCmd.PersistentFlags().String("gh-host", "", "Specify the GitHub hostname (for GitHub Enterprise etc.)")
82+
rootCmd.PersistentFlags().String("token-source", default_token_source, "Authentication token source (e.g. env, gh)")
7883

7984
// Bind flag to viper
8085
_ = viper.BindPFlag("toolsets", rootCmd.PersistentFlags().Lookup("toolsets"))
@@ -84,6 +89,7 @@ func init() {
8489
_ = viper.BindPFlag("enable-command-logging", rootCmd.PersistentFlags().Lookup("enable-command-logging"))
8590
_ = viper.BindPFlag("export-translations", rootCmd.PersistentFlags().Lookup("export-translations"))
8691
_ = viper.BindPFlag("host", rootCmd.PersistentFlags().Lookup("gh-host"))
92+
_ = viper.BindPFlag("token-source", rootCmd.PersistentFlags().Lookup("token-source"))
8793

8894
// Add subcommands
8995
rootCmd.AddCommand(stdioCmd)
@@ -126,21 +132,9 @@ func runStdioServer(cfg runConfig) error {
126132
defer stop()
127133

128134
// Create GH client
129-
token := viper.GetString("personal_access_token")
130-
if token == "" {
131-
cfg.logger.Fatal("GITHUB_PERSONAL_ACCESS_TOKEN not set")
132-
}
133-
ghClient := gogithub.NewClient(nil).WithAuthToken(token)
134-
ghClient.UserAgent = fmt.Sprintf("github-mcp-server/%s", version)
135-
136-
host := viper.GetString("host")
137-
138-
if host != "" {
139-
var err error
140-
ghClient, err = ghClient.WithEnterpriseURLs(host, host)
141-
if err != nil {
142-
return fmt.Errorf("failed to create GitHub client with host: %w", err)
143-
}
135+
ghClient, err := newGitHubClient()
136+
if err != nil {
137+
cfg.logger.Fatalf("failed to create GitHub client: %v", err)
144138
}
145139

146140
t, dumpTranslations := translations.TranslationHelper()
@@ -229,6 +223,50 @@ func runStdioServer(cfg runConfig) error {
229223
return nil
230224
}
231225

226+
func getToken(host string) (string, error) {
227+
token_source := viper.GetString("token-source")
228+
switch token_source {
229+
case "env":
230+
token := os.Getenv("GITHUB_PERSONAL_ACCESS_TOKEN")
231+
if token == "" {
232+
return "", fmt.Errorf("GITHUB_PERSONAL_ACCESS_TOKEN not set")
233+
}
234+
return token, nil
235+
case "gh":
236+
token, err := auth.TokenForHost(host)
237+
if err == "default" {
238+
return "", fmt.Errorf("no token found for host: %s", host)
239+
}
240+
return token, nil
241+
}
242+
return "", fmt.Errorf("unknown token source: %s", token_source)
243+
}
244+
245+
func getHost() string {
246+
host := os.Getenv("GH_HOST")
247+
if host == "" {
248+
host = viper.GetString("gh-host")
249+
}
250+
return host
251+
}
252+
253+
func newGitHubClient() (*gogithub.Client, error) {
254+
host := getHost()
255+
token, err := getToken(host)
256+
if err != nil {
257+
return nil, fmt.Errorf("failed to get token: %w", err)
258+
}
259+
ghClient := gogithub.NewClient(nil).WithAuthToken(token)
260+
if host != "" {
261+
ghClient, err = ghClient.WithEnterpriseURLs(host, host)
262+
if err != nil {
263+
return nil, fmt.Errorf("failed to create GitHub client with host: %w", err)
264+
}
265+
}
266+
ghClient.UserAgent = fmt.Sprintf("github-mcp-server/%s", version)
267+
return ghClient, nil
268+
}
269+
232270
func main() {
233271
if err := rootCmd.Execute(); err != nil {
234272
fmt.Println(err)

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ require (
1414
github.com/stretchr/testify v1.10.0
1515
)
1616

17+
require github.com/cli/safeexec v1.0.0 // indirect
18+
1719
require (
1820
github.com/Microsoft/go-winio v0.6.2 // indirect
21+
github.com/cli/go-gh v1.2.1
1922
github.com/containerd/log v0.1.0 // indirect
2023
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2124
github.com/distribution/reference v0.6.0 // indirect

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
44
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
55
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
66
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
7+
github.com/cli/go-gh v1.2.1 h1:xFrjejSsgPiwXFP6VYynKWwxLQcNJy3Twbu82ZDlR/o=
8+
github.com/cli/go-gh v1.2.1/go.mod h1:Jxk8X+TCO4Ui/GarwY9tByWm/8zp4jJktzVZNlTW5VM=
9+
github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI=
10+
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
711
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
812
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
913
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=

0 commit comments

Comments
 (0)