Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitafc7a93

Browse files
committed
Extract ghmcp internal package
This commit cleanly separates config parsing, stdio server execution andmcp server construction. Aside from significant clarity improvements, itallows for direct construction of the mcp server in e2e tests to allowfor breakpoint debugging.
1 parente56c096 commitafc7a93

File tree

2 files changed

+238
-166
lines changed

2 files changed

+238
-166
lines changed

‎cmd/github-mcp-server/main.go

Lines changed: 22 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
package main
22

33
import (
4-
"context"
4+
"errors"
55
"fmt"
6-
"io"
7-
stdlog"log"
86
"os"
9-
"os/signal"
10-
"syscall"
117

8+
"github.com/github/github-mcp-server/internal/ghmcp"
129
"github.com/github/github-mcp-server/pkg/github"
13-
iolog"github.com/github/github-mcp-server/pkg/log"
14-
"github.com/github/github-mcp-server/pkg/translations"
15-
gogithub"github.com/google/go-github/v69/github"
16-
"github.com/mark3labs/mcp-go/mcp"
17-
"github.com/mark3labs/mcp-go/server"
18-
log"github.com/sirupsen/logrus"
1910
"github.com/spf13/cobra"
2011
"github.com/spf13/viper"
2112
)
2213

14+
// These variables are set by the build process using ldflags.
2315
varversion="version"
2416
varcommit="commit"
2517
vardate="date"
@@ -36,36 +28,34 @@ var (
3628
Use:"stdio",
3729
Short:"Start stdio server",
3830
Long:`Start a server that communicates via standard input/output streams using JSON-RPC messages.`,
39-
Run:func(_*cobra.Command,_ []string) {
40-
logFile:=viper.GetString("log-file")
41-
readOnly:=viper.GetBool("read-only")
42-
exportTranslations:=viper.GetBool("export-translations")
43-
logger,err:=initLogger(logFile)
44-
iferr!=nil {
45-
stdlog.Fatal("Failed to initialize logger:",err)
31+
RunE:func(_*cobra.Command,_ []string)error {
32+
token:=viper.GetString("personal_access_token")
33+
iftoken=="" {
34+
returnerrors.New("GITHUB_PERSONAL_ACCESS_TOKEN not set")
4635
}
4736

4837
// If you're wondering why we're not using viper.GetStringSlice("toolsets"),
4938
// it's because viper doesn't handle comma-separated values correctly for env
5039
// vars when using GetStringSlice.
5140
// https://github.com/spf13/viper/issues/380
5241
varenabledToolsets []string
53-
err=viper.UnmarshalKey("toolsets",&enabledToolsets)
54-
iferr!=nil {
55-
stdlog.Fatal("Failed to unmarshal toolsets:",err)
42+
iferr:=viper.UnmarshalKey("toolsets",&enabledToolsets);err!=nil {
43+
returnfmt.Errorf("failed to unmarshal toolsets: %w",err)
5644
}
5745

58-
logCommands:=viper.GetBool("enable-command-logging")
59-
cfg:=runConfig{
60-
readOnly:readOnly,
61-
logger:logger,
62-
logCommands:logCommands,
63-
exportTranslations:exportTranslations,
64-
enabledToolsets:enabledToolsets,
65-
}
66-
iferr:=runStdioServer(cfg);err!=nil {
67-
stdlog.Fatal("failed to run stdio server:",err)
46+
stdioServerConfig:=ghmcp.StdioServerConfig{
47+
Version:version,
48+
Host:viper.GetString("host"),
49+
Token:token,
50+
EnabledToolsets:enabledToolsets,
51+
DynamicToolsets:viper.GetBool("dynamic_toolsets"),
52+
ReadOnly:viper.GetBool("read-only"),
53+
ExportTranslations:viper.GetBool("export-translations"),
54+
EnableCommandLogging:viper.GetBool("enable-command-logging"),
55+
LogFilePath:viper.GetString("log-file"),
6856
}
57+
58+
returnghmcp.RunStdioServer(stdioServerConfig)
6959
},
7060
}
7161
)
@@ -103,143 +93,9 @@ func initConfig() {
10393
viper.AutomaticEnv()
10494
}
10595

106-
funcinitLogger(outPathstring) (*log.Logger,error) {
107-
ifoutPath=="" {
108-
returnlog.New(),nil
109-
}
110-
111-
file,err:=os.OpenFile(outPath,os.O_CREATE|os.O_WRONLY|os.O_APPEND,0666)
112-
iferr!=nil {
113-
returnnil,fmt.Errorf("failed to open log file: %w",err)
114-
}
115-
116-
logger:=log.New()
117-
logger.SetLevel(log.DebugLevel)
118-
logger.SetOutput(file)
119-
120-
returnlogger,nil
121-
}
122-
123-
typerunConfigstruct {
124-
readOnlybool
125-
logger*log.Logger
126-
logCommandsbool
127-
exportTranslationsbool
128-
enabledToolsets []string
129-
}
130-
131-
funcrunStdioServer(cfgrunConfig)error {
132-
// Create app context
133-
ctx,stop:=signal.NotifyContext(context.Background(),os.Interrupt,syscall.SIGTERM)
134-
deferstop()
135-
136-
// Create GH client
137-
token:=viper.GetString("personal_access_token")
138-
iftoken=="" {
139-
cfg.logger.Fatal("GITHUB_PERSONAL_ACCESS_TOKEN not set")
140-
}
141-
ghClient:=gogithub.NewClient(nil).WithAuthToken(token)
142-
ghClient.UserAgent=fmt.Sprintf("github-mcp-server/%s",version)
143-
144-
host:=viper.GetString("host")
145-
146-
ifhost!="" {
147-
varerrerror
148-
ghClient,err=ghClient.WithEnterpriseURLs(host,host)
149-
iferr!=nil {
150-
returnfmt.Errorf("failed to create GitHub client with host: %w",err)
151-
}
152-
}
153-
154-
t,dumpTranslations:=translations.TranslationHelper()
155-
156-
beforeInit:=func(_ context.Context,_any,message*mcp.InitializeRequest) {
157-
ghClient.UserAgent=fmt.Sprintf("github-mcp-server/%s (%s/%s)",version,message.Params.ClientInfo.Name,message.Params.ClientInfo.Version)
158-
}
159-
160-
getClient:=func(_ context.Context) (*gogithub.Client,error) {
161-
returnghClient,nil// closing over client
162-
}
163-
164-
hooks:=&server.Hooks{
165-
OnBeforeInitialize: []server.OnBeforeInitializeFunc{beforeInit},
166-
}
167-
// Create server
168-
ghServer:=github.NewServer(version,server.WithHooks(hooks))
169-
170-
enabled:=cfg.enabledToolsets
171-
dynamic:=viper.GetBool("dynamic_toolsets")
172-
ifdynamic {
173-
// filter "all" from the enabled toolsets
174-
enabled=make([]string,0,len(cfg.enabledToolsets))
175-
for_,toolset:=rangecfg.enabledToolsets {
176-
iftoolset!="all" {
177-
enabled=append(enabled,toolset)
178-
}
179-
}
180-
}
181-
182-
// Create default toolsets
183-
toolsets,err:=github.InitToolsets(enabled,cfg.readOnly,getClient,t)
184-
context:=github.InitContextToolset(getClient,t)
185-
186-
iferr!=nil {
187-
stdlog.Fatal("Failed to initialize toolsets:",err)
188-
}
189-
190-
// Register resources with the server
191-
github.RegisterResources(ghServer,getClient,t)
192-
// Register the tools with the server
193-
toolsets.RegisterTools(ghServer)
194-
context.RegisterTools(ghServer)
195-
196-
ifdynamic {
197-
dynamic:=github.InitDynamicToolset(ghServer,toolsets,t)
198-
dynamic.RegisterTools(ghServer)
199-
}
200-
201-
stdioServer:=server.NewStdioServer(ghServer)
202-
203-
stdLogger:=stdlog.New(cfg.logger.Writer(),"stdioserver",0)
204-
stdioServer.SetErrorLogger(stdLogger)
205-
206-
ifcfg.exportTranslations {
207-
// Once server is initialized, all translations are loaded
208-
dumpTranslations()
209-
}
210-
211-
// Start listening for messages
212-
errC:=make(chanerror,1)
213-
gofunc() {
214-
in,out:=io.Reader(os.Stdin),io.Writer(os.Stdout)
215-
216-
ifcfg.logCommands {
217-
loggedIO:=iolog.NewIOLogger(in,out,cfg.logger)
218-
in,out=loggedIO,loggedIO
219-
}
220-
221-
errC<-stdioServer.Listen(ctx,in,out)
222-
}()
223-
224-
// Output github-mcp-server string
225-
_,_=fmt.Fprintf(os.Stderr,"GitHub MCP Server running on stdio\n")
226-
227-
// Wait for shutdown signal
228-
select {
229-
case<-ctx.Done():
230-
cfg.logger.Infof("shutting down server...")
231-
caseerr:=<-errC:
232-
iferr!=nil {
233-
returnfmt.Errorf("error running server: %w",err)
234-
}
235-
}
236-
237-
returnnil
238-
}
239-
24096
funcmain() {
24197
iferr:=rootCmd.Execute();err!=nil {
242-
fmt.Println(err)
98+
fmt.Fprintf(os.Stderr,"%v\n",err)
24399
os.Exit(1)
244100
}
245101
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp