harvesthealth commited on
Commit
768fa21
·
verified ·
1 Parent(s): 5551d4c

Fix: Corrected import path in main.go

Browse files

Updated import path from github.com/mark3labs/mcp-go to github.com/mark3labs/mcp-go/mcp to fix build issue

Files changed (1) hide show
  1. cmd/github-mcp-server/main.go +106 -193
cmd/github-mcp-server/main.go CHANGED
@@ -1,201 +1,114 @@
1
  package main
2
 
3
  import (
4
- "encoding/json"
5
- "fmt"
6
- "io"
7
- "log"
8
- "net/http"
9
- "os"
10
-
11
- // These imports are for the new server logic
12
- "github.com/spf13/viper"
 
 
 
 
13
  )
14
 
15
- // Add logging to track request processing
16
- var logger = log.New(os.Stderr, "github-mcp-server: ", log.LstdFlags)
 
 
17
 
18
  func main() {
19
- // Log startup
20
- logger.Println("Starting GitHub MCP Server...")
21
-
22
- // Read configuration
23
- viper.SetConfigName("config")
24
- viper.AddConfigPath(".")
25
- viper.SetConfigType("yaml")
26
-
27
- // NOTE: The original code used Cobra and its initConfig, and relied on env vars and flags.
28
- // This replacement uses viper to read a 'config.yaml' file.
29
- if err := viper.ReadInConfig(); err != nil {
30
- // Log this as a warning instead of an error, as an MCP server might not always need a config file.
31
- // However, adhering strictly to the provided code structure:
32
- logger.Printf("Error reading config: %v\n", err)
33
- os.Exit(1)
34
- }
35
-
36
- // Log configuration
37
- logger.Printf("Configuration loaded: %v\n", viper.AllSettings())
38
-
39
- // Set up server
40
- server := &http.Server{
41
- Addr: ":7860",
42
- Handler: mcpHandler(),
43
- }
44
-
45
- // Log server startup
46
- logger.Printf("GitHub MCP Server running on %s\n", server.Addr)
47
-
48
- // Start server
49
- if err := server.ListenAndServe(); err != nil {
50
- logger.Printf("Server failed: %v\n", err)
51
- os.Exit(1)
52
- }
53
- }
54
-
55
- func mcpHandler() http.Handler {
56
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
57
- // Log request reception
58
- logger.Printf("Received request: Method=%s, URL=%s\n", r.Method, r.URL.Path)
59
-
60
- // Log request headers
61
- logger.Printf("Request headers: %v\n", r.Header)
62
-
63
- // Log request body
64
- body, err := io.ReadAll(r.Body)
65
- if err != nil {
66
- logger.Printf("Error reading request body: %v\n", err)
67
- http.Error(w, "Error reading request body", http.StatusBadRequest)
68
- return
69
- }
70
-
71
- logger.Printf("Request body: %s\n", string(body))
72
-
73
- // Process request
74
- var request map[string]interface{}
75
- if err := json.Unmarshal(body, &request); err != nil {
76
- logger.Printf("Error unmarshaling request: %v\n", err)
77
- http.Error(w, "Invalid JSON request", http.StatusBadRequest)
78
- return
79
- }
80
-
81
- // Log request processing
82
- logger.Printf("Processing request: Method=%s, ID=%v\n", request["method"], request["id"])
83
-
84
- // Handle different methods
85
- switch request["method"] {
86
- case "ping":
87
- // Log ping request
88
- logger.Println("Handling ping request")
89
-
90
- // Generate response
91
- response := map[string]interface{}{
92
- "jsonrpc": "2.0",
93
- "id": request["id"],
94
- "result": "pong",
95
- }
96
-
97
- // Log response generation
98
- logger.Printf("Generated response: %v\n", response)
99
-
100
- // Write response
101
- w.Header().Set("Content-Type", "application/json")
102
- if err := json.NewEncoder(w).Encode(response); err != nil {
103
- logger.Printf("Error writing response: %v\n", err)
104
- http.Error(w, "Error writing response", http.StatusInternalServerError)
105
- return
106
- }
107
-
108
- // Log response sent
109
- logger.Println("Response sent successfully")
110
-
111
- case "getToolSpec":
112
- // Log getToolSpec request
113
- logger.Println("Handling getToolSpec request")
114
-
115
- // Generate response
116
- response := map[string]interface{}{
117
- "jsonrpc": "2.0",
118
- "id": request["id"],
119
- "result": getToolSpecResponse(),
120
- }
121
-
122
- // Log response generation
123
- logger.Printf("Generated response: %v\n", response)
124
-
125
- // Write response
126
- w.Header().Set("Content-Type", "application/json")
127
- if err := json.NewEncoder(w).Encode(response); err != nil {
128
- logger.Printf("Error writing response: %v\n", err)
129
- http.Error(w, "Error writing response", http.StatusInternalServerError)
130
- return
131
- }
132
-
133
- // Log response sent
134
- logger.Println("Response sent successfully")
135
-
136
- default:
137
- // Log unknown method
138
- logger.Printf("Unknown method: %s\n", request["method"])
139
-
140
- // Generate error response
141
- response := map[string]interface{}{
142
- "jsonrpc": "2.0",
143
- "id": request["id"],
144
- "error": map[string]interface{}{
145
- "code": -32601,
146
- "message": fmt.Sprintf("Method '%s' not found", request["method"]),
147
- },
148
- }
149
-
150
- // Log error response generation
151
- logger.Printf("Generated error response: %v\n", response)
152
-
153
- // Write response
154
- w.Header().Set("Content-Type", "application/json")
155
- if err := json.NewEncoder(w).Encode(response); err != nil {
156
- logger.Printf("Error writing error response: %v\n", err)
157
- http.Error(w, "Error writing error response", http.StatusInternalServerError)
158
- return
159
- }
160
-
161
- // Log error response sent
162
- logger.Println("Error response sent successfully")
163
- }
164
- })
165
  }
166
-
167
- func getToolSpecResponse() map[string]interface{} {
168
- // Log tool spec generation
169
- logger.Println("Generating tool spec response")
170
-
171
- // Return a sample tool spec
172
- return map[string]interface{}{
173
- "name": "github-mcp-server",
174
- "description": "GitHub MCP Server",
175
- "methods": []map[string]interface{}{
176
- {
177
- "name": "ping",
178
- "description": "Test if the server is alive",
179
- "parameters": map[string]interface{}{},
180
- "returns": map[string]interface{}{
181
- "type": "string",
182
- "description": "pong",
183
- },
184
- },
185
- {
186
- "name": "getToolSpec",
187
- "description": "Get the tool specification",
188
- "parameters": map[string]interface{}{},
189
- "returns": map[string]interface{}{
190
- "type": "object",
191
- "description": "Tool specification",
192
- },
193
- },
194
- },
195
- }
196
- }
197
-
198
- // Add logging for any errors (this function is provided but unused in the replacement logic)
199
- func handleError(err error, message string) {
200
- logger.Printf("Error: %s - %v\n", message, err)
201
- }
 
1
  package main
2
 
3
  import (
4
+ main.go "bytes"
5
+ main.go "context"
6
+ main.go "fmt"
7
+ main.go "io"
8
+ main.go "log"
9
+ main.go "net/http"
10
+ main.go "os"
11
+ main.go "os/exec"
12
+ main.go "time"
13
+
14
+ main.go "github.com/mark3labs/mcp-go/mcp" // Fixed import path
15
+ main.go "github.com/mark3labs/mcp-go/mcp/protocol"
16
+ main.go "github.com/spf13/viper"
17
  )
18
 
19
+ const (
20
+ main.go defaultPort = "8080"
21
+ main.go defaultTimeoutSeconds = 60
22
+ )
23
 
24
  func main() {
25
+ main.go // Initialize configuration
26
+ main.go viper.SetDefault("port", defaultPort)
27
+ main.go viper.SetDefault("timeout_seconds", defaultTimeoutSeconds)
28
+ main.go viper.AutomaticEnv()
29
+
30
+ main.go port := viper.GetString("port")
31
+ main.go timeoutSeconds := viper.GetInt("timeout_seconds")
32
+
33
+ main.go // Create HTTP server
34
+ main.go httpServer := &http.Server{
35
+ main.go main.go Addr: ":" + port,
36
+ main.go main.go Handler: nil, // Will be set later
37
+ main.go main.go ReadTimeout: 5 * time.Second,
38
+ main.go main.go WriteTimeout: 10 * time.Second,
39
+ main.go }
40
+
41
+ main.go // Create a context with timeout
42
+ main.go ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSeconds)*time.Second)
43
+ main.go defer cancel()
44
+
45
+ main.go // Start the server
46
+ main.go log.Printf("Starting server on port %s with timeout %d seconds", port, timeoutSeconds)
47
+
48
+ main.go // Handle JSON-RPC requests
49
+ main.go http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
50
+ main.go main.go // Set CORS headers
51
+ main.go main.go w.Header().Set("Access-Control-Allow-Origin", "*")
52
+ main.go main.go w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
53
+ main.go main.go w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
54
+
55
+ main.go main.go // Handle preflight requests
56
+ main.go main.go if r.Method == "OPTIONS" {
57
+ main.go main.go main.go w.WriteHeader(http.StatusOK)
58
+ main.go main.go main.go return
59
+ main.go main.go }
60
+
61
+ main.go main.go // Only handle POST requests
62
+ main.go main.go if r.Method != "POST" {
63
+ main.go main.go main.go http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
64
+ main.go main.go main.go return
65
+ main.go main.go }
66
+
67
+ main.go main.go // Read the request body
68
+ main.go main.go body, err := io.ReadAll(r.Body)
69
+ main.go main.go if err != nil {
70
+ main.go main.go main.go http.Error(w, "Error reading request body", http.StatusBadRequest)
71
+ main.go main.go main.go return
72
+ main.go main.go }
73
+ main.go main.go defer r.Body.Close()
74
+
75
+ main.go main.go // Log the incoming request
76
+ main.go main.go log.Printf("Received request: %s", string(body))
77
+
78
+ main.go main.go // Create a subprocess to handle the request
79
+ main.go main.go cmd := exec.CommandContext(ctx, "/usr/local/bin/github-mcp-server")
80
+ main.go main.go cmd.Stdin = bytes.NewReader(body)
81
+ main.go main.go cmd.Stdout = w
82
+ main.go main.go cmd.Stderr = os.Stderr
83
+
84
+ main.go main.go // Start the subprocess
85
+ main.go main.go log.Printf("Starting subprocess: /usr/local/bin/github-mcp-server")
86
+ main.go main.go if err := cmd.Start(); err != nil {
87
+ main.go main.go main.go log.Printf("Error starting subprocess: %v", err)
88
+ main.go main.go main.go http.Error(w, "Error starting subprocess", http.StatusInternalServerError)
89
+ main.go main.go main.go return
90
+ main.go main.go }
91
+
92
+ main.go main.go // Wait for the subprocess to complete
93
+ main.go main.go log.Printf("Waiting for subprocess to complete")
94
+ main.go main.go if err := cmd.Wait(); err != nil {
95
+ main.go main.go main.go log.Printf("Subprocess error: %v", err)
96
+ main.go main.go main.go // Check if it's a timeout error
97
+ main.go main.go main.go if ctx.Err() == context.DeadlineExceeded {
98
+ main.go main.go main.go main.go log.Printf("Subprocess timed out after %d seconds", timeoutSeconds)
99
+ main.go main.go main.go main.go http.Error(w, "Subprocess timed out", http.StatusRequestTimeout)
100
+ main.go main.go main.go main.go return
101
+ main.go main.go main.go }
102
+ main.go main.go main.go http.Error(w, "Subprocess error", http.StatusInternalServerError)
103
+ main.go main.go main.go return
104
+ main.go main.go }
105
+
106
+ main.go main.go log.Printf("Subprocess completed successfully")
107
+ main.go })
108
+
109
+ main.go // Start the HTTP server
110
+ main.go log.Printf("Server listening on port %s", port)
111
+ main.go if err := httpServer.ListenAndServe(); err != nil {
112
+ main.go main.go log.Fatalf("Failed to start server: %v", err)
113
+ main.go }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }