Skip to content

feat: enable go run execution by moving main to root #630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/docs-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
go-version-file: 'go.mod'

- name: Build docs generator
run: go build -o github-mcp-server ./cmd/github-mcp-server
run: go build .

- name: Generate documentation
run: ./github-mcp-server generate-docs
Expand All @@ -35,7 +35,7 @@ jobs:
echo "The generated documentation differs from what's committed."
echo "Please run the following command to update the documentation:"
echo ""
echo " go run ./cmd/github-mcp-server generate-docs"
echo " go run . generate-docs"
echo ""
echo "Then commit the changes."
echo ""
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
run: script/test

- name: Build
run: go build -v ./cmd/github-mcp-server
run: go build -v .
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.idea
cmd/github-mcp-server/github-mcp-server
github-mcp-server*

# VSCode
.vscode/*
Expand Down
3 changes: 1 addition & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ builds:
- env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
- -s -w -X cmd.version={{.Version}} -X cmd.commit={{.Commit}} -X cmd.date={{.Date}}
goos:
- linux
- windows
- darwin
main: ./cmd/github-mcp-server

archives:
- formats: tar.gz
Expand Down
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"request": "launch",
"mode": "auto",
"cwd": "${workspaceFolder}",
"program": "cmd/github-mcp-server/main.go",
"program": "main.go",
"args": ["stdio"],
"console": "integratedTerminal",
},
Expand All @@ -20,7 +20,7 @@
"request": "launch",
"mode": "auto",
"cwd": "${workspaceFolder}",
"program": "cmd/github-mcp-server/main.go",
"program": "main.go",
"args": ["stdio", "--read-only"],
"console": "integratedTerminal",
}
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ RUN --mount=type=cache,target=/var/cache/apk \
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=bind,target=. \
CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=$(git rev-parse HEAD) -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o /bin/github-mcp-server cmd/github-mcp-server/main.go
CGO_ENABLED=0 go build -ldflags="-s -w -X cmd.version=${VERSION} -X cmd.commit=$(git rev-parse HEAD) -X cmd.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o /bin/github-mcp-server .

# Make a stage to run the app
FROM gcr.io/distroless/base-debian12
Expand Down
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,43 @@ More about using MCP server tools in VS Code's [agent mode documentation](https:

### Build from source

If you don't have Docker, you can use `go build` to build the binary in the
`cmd/github-mcp-server` directory, and use the `github-mcp-server stdio` command with the `GITHUB_PERSONAL_ACCESS_TOKEN` environment variable set to your token. To specify the output location of the build, use the `-o` flag. You should configure your server to use the built executable as its `command`. For example:
If you don't have Docker, you have several options:

#### Option 1: Run directly from source (Recommended)

You can run the server directly from source using `go run`:

```bash
GITHUB_PERSONAL_ACCESS_TOKEN=<your-token> go run github.com/github/github-mcp-server@latest stdio
```

Or configure your MCP host to use `go run`:

```JSON
{
"mcp": {
"servers": {
"github": {
"command": "go",
"args": ["run", "github.com/github/github-mcp-server@latest", "stdio"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
}
}
}
}
```

#### Option 2: Build and install

You can build the binary and use the built executable:

```bash
go build -o github-mcp-server github.com/github/github-mcp-server@latest
```

Then configure your server to use the built executable:

```JSON
{
Expand Down
4 changes: 2 additions & 2 deletions cmd/github-mcp-server/generate_docs.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"context"
Expand Down Expand Up @@ -29,7 +29,7 @@ var generateDocsCmd = &cobra.Command{
}

func init() {
rootCmd.AddCommand(generateDocsCmd)
RootCmd.AddCommand(generateDocsCmd)
}

// mockGetClient returns a mock GitHub client for documentation generation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package main
package cmd

import (
"errors"
"fmt"
"os"
"strings"

"github.com/github/github-mcp-server/internal/ghmcp"
Expand All @@ -19,7 +18,7 @@ var commit = "commit"
var date = "date"

var (
rootCmd = &cobra.Command{
RootCmd = &cobra.Command{
Use: "server",
Short: "GitHub MCP Server",
Long: `A GitHub MCP server that handles various tools and resources.`,
Expand Down Expand Up @@ -63,30 +62,30 @@ var (

func init() {
cobra.OnInitialize(initConfig)
rootCmd.SetGlobalNormalizationFunc(wordSepNormalizeFunc)
RootCmd.SetGlobalNormalizationFunc(wordSepNormalizeFunc)

rootCmd.SetVersionTemplate("{{.Short}}\n{{.Version}}\n")
RootCmd.SetVersionTemplate("{{.Short}}\n{{.Version}}\n")

// Add global flags that will be shared by all commands
rootCmd.PersistentFlags().StringSlice("toolsets", github.DefaultTools, "An optional comma separated list of groups of tools to allow, defaults to enabling all")
rootCmd.PersistentFlags().Bool("dynamic-toolsets", false, "Enable dynamic toolsets")
rootCmd.PersistentFlags().Bool("read-only", false, "Restrict the server to read-only operations")
rootCmd.PersistentFlags().String("log-file", "", "Path to log file")
rootCmd.PersistentFlags().Bool("enable-command-logging", false, "When enabled, the server will log all command requests and responses to the log file")
rootCmd.PersistentFlags().Bool("export-translations", false, "Save translations to a JSON file")
rootCmd.PersistentFlags().String("gh-host", "", "Specify the GitHub hostname (for GitHub Enterprise etc.)")
RootCmd.PersistentFlags().StringSlice("toolsets", github.DefaultTools, "An optional comma separated list of groups of tools to allow, defaults to enabling all")
RootCmd.PersistentFlags().Bool("dynamic-toolsets", false, "Enable dynamic toolsets")
RootCmd.PersistentFlags().Bool("read-only", false, "Restrict the server to read-only operations")
RootCmd.PersistentFlags().String("log-file", "", "Path to log file")
RootCmd.PersistentFlags().Bool("enable-command-logging", false, "When enabled, the server will log all command requests and responses to the log file")
RootCmd.PersistentFlags().Bool("export-translations", false, "Save translations to a JSON file")
RootCmd.PersistentFlags().String("gh-host", "", "Specify the GitHub hostname (for GitHub Enterprise etc.)")

// Bind flag to viper
_ = viper.BindPFlag("toolsets", rootCmd.PersistentFlags().Lookup("toolsets"))
_ = viper.BindPFlag("dynamic_toolsets", rootCmd.PersistentFlags().Lookup("dynamic-toolsets"))
_ = viper.BindPFlag("read-only", rootCmd.PersistentFlags().Lookup("read-only"))
_ = viper.BindPFlag("log-file", rootCmd.PersistentFlags().Lookup("log-file"))
_ = viper.BindPFlag("enable-command-logging", rootCmd.PersistentFlags().Lookup("enable-command-logging"))
_ = viper.BindPFlag("export-translations", rootCmd.PersistentFlags().Lookup("export-translations"))
_ = viper.BindPFlag("host", rootCmd.PersistentFlags().Lookup("gh-host"))
_ = viper.BindPFlag("toolsets", RootCmd.PersistentFlags().Lookup("toolsets"))
_ = viper.BindPFlag("dynamic_toolsets", RootCmd.PersistentFlags().Lookup("dynamic-toolsets"))
_ = viper.BindPFlag("read-only", RootCmd.PersistentFlags().Lookup("read-only"))
_ = viper.BindPFlag("log-file", RootCmd.PersistentFlags().Lookup("log-file"))
_ = viper.BindPFlag("enable-command-logging", RootCmd.PersistentFlags().Lookup("enable-command-logging"))
_ = viper.BindPFlag("export-translations", RootCmd.PersistentFlags().Lookup("export-translations"))
_ = viper.BindPFlag("host", RootCmd.PersistentFlags().Lookup("gh-host"))

// Add subcommands
rootCmd.AddCommand(stdioCmd)
RootCmd.AddCommand(stdioCmd)
}

func initConfig() {
Expand All @@ -96,13 +95,6 @@ func initConfig() {

}

func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}

func wordSepNormalizeFunc(_ *pflag.FlagSet, name string) pflag.NormalizedName {
from := []string{"_"}
to := "-"
Expand Down
2 changes: 1 addition & 1 deletion cmd/mcpcurl/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bytes"
Expand Down
29 changes: 14 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,54 +1,53 @@
module github.com/github/github-mcp-server

go 1.23.7
go 1.24.4

require (
github.com/google/go-github/v72 v72.0.0
github.com/josephburnett/jd v1.9.2
github.com/mark3labs/mcp-go v0.32.0
github.com/migueleliasweb/go-github-mock v1.3.0
github.com/migueleliasweb/go-github-mock v1.4.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
)

require (
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/swag v0.21.1 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/google/go-github/v73 v73.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-viper/mapstructure/v2 v2.3.0
github.com/google/go-github/v71 v71.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/sagikazarmark/locafero v0.9.0 // indirect
github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/cast v1.9.2 // indirect
github.com/spf13/pflag v1.0.6
github.com/subosito/gotenv v1.6.0 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/oauth2 v0.29.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.5.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading