Skip to content

Commit cf55a18

Browse files
authored
Merge branch 'main' into add-issue-comments-tool
2 parents 6c2a159 + 6b02799 commit cf55a18

File tree

6 files changed

+73
-18
lines changed

6 files changed

+73
-18
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: "⭐ Submit a feature request"
3+
about: Surface a feature or problem that you think should be solved
4+
title: ''
5+
labels: enhancement
6+
assignees: ''
7+
8+
---
9+
10+
### Describe the feature or problem you’d like to solve
11+
12+
A clear and concise description of what the feature or problem is.
13+
14+
### Proposed solution
15+
16+
How will it benefit GitHub MCP Server and its users?
17+
18+
### Additional context
19+
20+
Add any other context like screenshots or mockups are helpful, if applicable.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
88

9-
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE.txt).
9+
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE).
1010

1111
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
1212

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ automation and interaction capabilities for developers and tools.
1414

1515
## Prerequisites
1616

17-
[Create a GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new).
18-
The MCP server can use many of the GitHub APIs, so enable the permissions that you feel comfortable granting your AI tools.
17+
1. To run the server in a container, you will need to have [Docker](https://www.docker.com/) installed.
18+
2. [Create a GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new).
19+
The MCP server can use many of the GitHub APIs, so enable the permissions that you feel comfortable granting your AI tools (to learn more about access tokens, please check out the [documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)).
1920

20-
To learn more about access tokens, please check out the [documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).
2121

22-
To run the server in a container, you will need to have [Docker](https://www.docker.com/) installed.
2322

2423
## Installation
2524

cmd/github-mcp-server/main.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package main
22

33
import (
4+
"bytes"
45
"context"
6+
"encoding/json"
57
"fmt"
68
"io"
79
stdlog "log"
@@ -39,12 +41,20 @@ var (
3941
logFile := viper.GetString("log-file")
4042
readOnly := viper.GetBool("read-only")
4143
exportTranslations := viper.GetBool("export-translations")
44+
prettyPrintJSON := viper.GetBool("pretty-print-json")
4245
logger, err := initLogger(logFile)
4346
if err != nil {
4447
stdlog.Fatal("Failed to initialize logger:", err)
4548
}
4649
logCommands := viper.GetBool("enable-command-logging")
47-
if err := runStdioServer(readOnly, logger, logCommands, exportTranslations); err != nil {
50+
cfg := runConfig{
51+
readOnly: readOnly,
52+
logger: logger,
53+
logCommands: logCommands,
54+
exportTranslations: exportTranslations,
55+
prettyPrintJSON: prettyPrintJSON,
56+
}
57+
if err := runStdioServer(cfg); err != nil {
4858
stdlog.Fatal("failed to run stdio server:", err)
4959
}
5060
},
@@ -60,13 +70,15 @@ func init() {
6070
rootCmd.PersistentFlags().Bool("enable-command-logging", false, "When enabled, the server will log all command requests and responses to the log file")
6171
rootCmd.PersistentFlags().Bool("export-translations", false, "Save translations to a JSON file")
6272
rootCmd.PersistentFlags().String("gh-host", "", "Specify the GitHub hostname (for GitHub Enterprise etc.)")
73+
rootCmd.PersistentFlags().Bool("pretty-print-json", false, "Pretty print JSON output")
6374

6475
// Bind flag to viper
6576
_ = viper.BindPFlag("read-only", rootCmd.PersistentFlags().Lookup("read-only"))
6677
_ = viper.BindPFlag("log-file", rootCmd.PersistentFlags().Lookup("log-file"))
6778
_ = viper.BindPFlag("enable-command-logging", rootCmd.PersistentFlags().Lookup("enable-command-logging"))
6879
_ = viper.BindPFlag("export-translations", rootCmd.PersistentFlags().Lookup("export-translations"))
6980
_ = viper.BindPFlag("gh-host", rootCmd.PersistentFlags().Lookup("gh-host"))
81+
_ = viper.BindPFlag("pretty-print-json", rootCmd.PersistentFlags().Lookup("pretty-print-json"))
7082

7183
// Add subcommands
7284
rootCmd.AddCommand(stdioCmd)
@@ -95,15 +107,36 @@ func initLogger(outPath string) (*log.Logger, error) {
95107
return logger, nil
96108
}
97109

98-
func runStdioServer(readOnly bool, logger *log.Logger, logCommands bool, exportTranslations bool) error {
110+
type runConfig struct {
111+
readOnly bool
112+
logger *log.Logger
113+
logCommands bool
114+
exportTranslations bool
115+
prettyPrintJSON bool
116+
}
117+
118+
// JSONPrettyPrintWriter is a Writer that pretty prints input to indented JSON
119+
type JSONPrettyPrintWriter struct {
120+
writer io.Writer
121+
}
122+
123+
func (j JSONPrettyPrintWriter) Write(p []byte) (n int, err error) {
124+
var prettyJSON bytes.Buffer
125+
if err := json.Indent(&prettyJSON, p, "", "\t"); err != nil {
126+
return 0, err
127+
}
128+
return j.writer.Write(prettyJSON.Bytes())
129+
}
130+
131+
func runStdioServer(cfg runConfig) error {
99132
// Create app context
100133
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
101134
defer stop()
102135

103136
// Create GH client
104137
token := os.Getenv("GITHUB_PERSONAL_ACCESS_TOKEN")
105138
if token == "" {
106-
logger.Fatal("GITHUB_PERSONAL_ACCESS_TOKEN not set")
139+
cfg.logger.Fatal("GITHUB_PERSONAL_ACCESS_TOKEN not set")
107140
}
108141
ghClient := gogithub.NewClient(nil).WithAuthToken(token)
109142
ghClient.UserAgent = fmt.Sprintf("github-mcp-server/%s", version)
@@ -125,13 +158,13 @@ func runStdioServer(readOnly bool, logger *log.Logger, logCommands bool, exportT
125158
t, dumpTranslations := translations.TranslationHelper()
126159

127160
// Create
128-
ghServer := github.NewServer(ghClient, readOnly, t)
161+
ghServer := github.NewServer(ghClient, cfg.readOnly, t)
129162
stdioServer := server.NewStdioServer(ghServer)
130163

131-
stdLogger := stdlog.New(logger.Writer(), "stdioserver", 0)
164+
stdLogger := stdlog.New(cfg.logger.Writer(), "stdioserver", 0)
132165
stdioServer.SetErrorLogger(stdLogger)
133166

134-
if exportTranslations {
167+
if cfg.exportTranslations {
135168
// Once server is initialized, all translations are loaded
136169
dumpTranslations()
137170
}
@@ -141,11 +174,14 @@ func runStdioServer(readOnly bool, logger *log.Logger, logCommands bool, exportT
141174
go func() {
142175
in, out := io.Reader(os.Stdin), io.Writer(os.Stdout)
143176

144-
if logCommands {
145-
loggedIO := iolog.NewIOLogger(in, out, logger)
177+
if cfg.logCommands {
178+
loggedIO := iolog.NewIOLogger(in, out, cfg.logger)
146179
in, out = loggedIO, loggedIO
147180
}
148181

182+
if cfg.prettyPrintJSON {
183+
out = JSONPrettyPrintWriter{writer: out}
184+
}
149185
errC <- stdioServer.Listen(ctx, in, out)
150186
}()
151187

@@ -155,7 +191,7 @@ func runStdioServer(readOnly bool, logger *log.Logger, logCommands bool, exportT
155191
// Wait for shutdown signal
156192
select {
157193
case <-ctx.Done():
158-
logger.Infof("shutting down server...")
194+
cfg.logger.Infof("shutting down server...")
159195
case err := <-errC:
160196
if err != nil {
161197
return fmt.Errorf("error running server: %w", err)

pkg/github/search.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func searchRepositories(client *github.Client, t translations.TranslationHelperF
3636
if err != nil {
3737
return mcp.NewToolResultError(err.Error()), nil
3838
}
39-
perPage, err := optionalIntParamWithDefault(request, "per_page", 30)
39+
perPage, err := optionalIntParamWithDefault(request, "perPage", 30)
4040
if err != nil {
4141
return mcp.NewToolResultError(err.Error()), nil
4242
}

pkg/github/search_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ func Test_SearchRepositories(t *testing.T) {
7272
),
7373
),
7474
requestArgs: map[string]interface{}{
75-
"query": "golang test",
76-
"page": float64(2),
77-
"per_page": float64(10),
75+
"query": "golang test",
76+
"page": float64(2),
77+
"perPage": float64(10),
7878
},
7979
expectError: false,
8080
expectedResult: mockSearchResult,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy