Skip to content

Commit fc8ccaf

Browse files
committed
bring mcp server inline with warp and api template pattern
1 parent d071cc6 commit fc8ccaf

3 files changed

Lines changed: 106 additions & 20 deletions

File tree

mcp/logging_middleware.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package main
22

33
import (
44
"context"
5-
"log"
65
"time"
76

87
"github.com/modelcontextprotocol/go-sdk/mcp"
8+
"github.com/urnetwork/glog"
99
)
1010

1111
func createLoggingMiddleware() mcp.Middleware {
@@ -19,7 +19,7 @@ func createLoggingMiddleware() mcp.Middleware {
1919
sessionID := req.GetSession().ID()
2020

2121
// Log request details.
22-
log.Printf("[REQUEST] Session: %s | Method: %s",
22+
glog.Infof("[REQUEST] Session: %s | Method: %s",
2323
sessionID,
2424
method)
2525

@@ -30,13 +30,13 @@ func createLoggingMiddleware() mcp.Middleware {
3030
duration := time.Since(start)
3131

3232
if err != nil {
33-
log.Printf("[RESPONSE] Session: %s | Method: %s | Status: ERROR | Duration: %v | Error: %v",
33+
glog.Infof("[RESPONSE] Session: %s | Method: %s | Status: ERROR | Duration: %v | Error: %v",
3434
sessionID,
3535
method,
3636
duration,
3737
err)
3838
} else {
39-
log.Printf("[RESPONSE] Session: %s | Method: %s | Status: OK | Duration: %v",
39+
glog.Infof("[RESPONSE] Session: %s | Method: %s | Status: OK | Duration: %v",
4040
sessionID,
4141
method,
4242
duration)

mcp/main.go

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

33
import (
4+
"context"
45
"flag"
5-
"fmt"
6-
"log"
6+
"runtime"
7+
"syscall"
8+
"time"
9+
10+
"github.com/urnetwork/glog"
11+
"github.com/urnetwork/server"
712
)
813

14+
const DrainTimeout = 60 * time.Second
15+
916
var (
1017
host = flag.String("host", "0.0.0.0", "host to listen on")
11-
port = flag.Int("port", 8000, "port number to listen on")
18+
port = flag.Int("port", 80, "port number to listen on")
19+
p = flag.Int("p", 80, "port number to listen on (short form)")
1220
)
1321

1422
func main() {
1523
flag.Parse()
1624

17-
addr := fmt.Sprintf("%s:%d", *host, *port)
18-
log.Printf("Starting MCP server on %s", addr)
25+
quitEvent := server.NewEventWithContext(context.Background())
26+
defer quitEvent.Set()
27+
28+
closeFn := quitEvent.SetOnSignals(syscall.SIGQUIT, syscall.SIGTERM)
29+
defer closeFn()
30+
31+
ctx, cancel := context.WithCancel(context.Background())
32+
defer cancel()
33+
34+
// drain on sigterm
35+
go server.HandleError(func() {
36+
defer cancel()
37+
select {
38+
case <-ctx.Done():
39+
return
40+
case <-quitEvent.Ctx.Done():
41+
select {
42+
case <-ctx.Done():
43+
return
44+
case <-time.After(DrainTimeout):
45+
}
46+
}
47+
})
48+
49+
// Debugging - log goroutine count
50+
go server.HandleError(func() {
51+
for {
52+
select {
53+
case <-ctx.Done():
54+
return
55+
case <-time.After(30 * time.Second):
56+
}
57+
58+
glog.Infof("[mcp]goroutines=%d/%d\n", runtime.NumGoroutine(), runtime.GOMAXPROCS(0))
59+
}
60+
})
61+
62+
server.Warmup()
63+
64+
glog.Infof(
65+
"[mcp]serving %s %s on %s:%d\n",
66+
server.RequireEnv(),
67+
server.RequireVersion(),
68+
*host,
69+
*port,
70+
)
1971

20-
if err := runServer(addr); err != nil {
21-
log.Fatalf("Server failed: %v", err)
72+
if err := runServer(ctx, *port); err != nil {
73+
glog.Fatalf("[mcp]Server failed: %v", err)
2274
}
75+
glog.Infof("[mcp]close\n")
2376
}

mcp/server.go

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

33
import (
4-
"log"
4+
"context"
5+
"net"
56
"net/http"
7+
"strconv"
8+
"time"
69

710
"github.com/modelcontextprotocol/go-sdk/mcp"
11+
"github.com/urnetwork/glog"
12+
"github.com/urnetwork/server"
13+
"github.com/urnetwork/server/router"
814
)
915

10-
func runServer(addr string) error {
11-
server := mcp.NewServer(&mcp.Implementation{
16+
func runServer(ctx context.Context, port int) error {
17+
mcpServer := mcp.NewServer(&mcp.Implementation{
1218
Name: "urnetwork-mcp",
1319
Version: "0.0.1-beta.1",
1420
}, nil)
1521

1622
// add logging
17-
server.AddReceivingMiddleware(createLoggingMiddleware())
23+
mcpServer.AddReceivingMiddleware(createLoggingMiddleware())
1824

1925
// register tools
20-
registerTools(server)
26+
registerTools(mcpServer)
2127

22-
handler := mcp.NewStreamableHTTPHandler(func(req *http.Request) *mcp.Server {
23-
return server
28+
mcpHandler := mcp.NewStreamableHTTPHandler(func(req *http.Request) *mcp.Server {
29+
return mcpServer
2430
}, nil)
2531

26-
log.Printf("MCP server listening on %s", addr)
32+
// Wrap MCP handler to match http.HandlerFunc signature
33+
mcpHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
34+
mcpHandler.ServeHTTP(w, r)
35+
}
2736

28-
return http.ListenAndServe(addr, handler)
37+
// Define routes using the router package
38+
routes := []*router.Route{
39+
router.NewRoute("GET", "/status", router.WarpStatus),
40+
router.NewRoute("*", ".*", mcpHandlerFunc),
41+
}
42+
43+
listenIpv4, _, listenPort := server.RequireListenIpPort(port)
44+
45+
reusePort := false
46+
47+
httpServerOptions := server.HttpServerOptions{
48+
ReadTimeout: 15 * time.Second,
49+
WriteTimeout: 30 * time.Second,
50+
IdleTimeout: 5 * time.Minute,
51+
}
52+
53+
glog.Infof("MCP server listening on %s:%d", listenIpv4, listenPort)
54+
55+
return server.HttpListenAndServeWithReusePort(
56+
ctx,
57+
net.JoinHostPort(listenIpv4, strconv.Itoa(listenPort)),
58+
router.NewRouter(ctx, routes),
59+
reusePort,
60+
httpServerOptions,
61+
)
2962
}

0 commit comments

Comments
 (0)