Skip to content

Commit 270bbf7

Browse files
authored
pretty print json (#114)
1 parent 86b0dcd commit 270bbf7

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

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)

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