Skip to content

Commit e622f59

Browse files
committed
feat: enable streamable http server for osv
add an env var that allows to switch mcp server mode, from sse to streamable http mode
1 parent a361ef1 commit e622f59

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

cmd/server/main.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func main() {
3939
// Parse command-line flags
4040
addr := flag.String("addr", ":"+port, "Address to listen on")
4141
flag.Parse()
42+
mode := os.Getenv("MCP_TRANSPORT_MODE") // "stream" or "sse"
4243

4344
// Create OSV client
4445
osvClient := osv.NewClient()
@@ -55,7 +56,14 @@ func main() {
5556
// Start server in a goroutine
5657
errChan := make(chan error, 1)
5758
go func() {
58-
errChan <- mcpServer.ServeSSE(*addr)
59+
switch mode {
60+
case "stream":
61+
log.Printf("Starting OSV MCP server (Streamable HTTP) on %s", *addr)
62+
errChan <- mcpServer.ServeHTTPStream(*addr)
63+
default:
64+
log.Printf("Starting OSV MCP server (SSE) on %s", *addr)
65+
errChan <- mcpServer.ServeSSE(*addr)
66+
}
5967
}()
6068

6169
// Wait for signal or error

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ module github.com/StacklokLabs/osv-mcp
33
go 1.24.2
44

55
require (
6-
github.com/mark3labs/mcp-go v0.28.0
6+
github.com/mark3labs/mcp-go v0.32.0
77
github.com/stretchr/testify v1.10.0
88
)
99

1010
require (
1111
github.com/davecgh/go-spew v1.1.1 // indirect
1212
github.com/google/uuid v1.6.0 // indirect
1313
github.com/pmezard/go-difflib v1.0.0 // indirect
14-
github.com/spf13/cast v1.7.1 // indirect
14+
github.com/spf13/cast v1.9.2 // indirect
1515
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
1616
gopkg.in/yaml.v3 v3.0.1 // indirect
1717
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1212
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
1313
github.com/mark3labs/mcp-go v0.28.0 h1:7yl4y5D1KYU2f/9Uxp7xfLIggfunHoESCRbrjcytcLM=
1414
github.com/mark3labs/mcp-go v0.28.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
15+
github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8=
16+
github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
1517
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1618
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1719
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
1820
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
1921
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
2022
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
23+
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
24+
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
2125
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
2226
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
2327
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=

pkg/mcp/server.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"fmt"
88
"log"
9+
"time"
910

1011
"github.com/mark3labs/mcp-go/mcp"
1112
"github.com/mark3labs/mcp-go/server"
@@ -158,6 +159,19 @@ func (s *Server) ServeSSE(addr string) error {
158159
return sseServer.Start(addr)
159160
}
160161

162+
// ServeHTTPStream starts the MCP server using Streamable HTTP transport
163+
func (s *Server) ServeHTTPStream(addr string) error {
164+
log.Printf("Starting OSV MCP server (Streamable HTTP) on %s", addr)
165+
166+
httpSrv := server.NewStreamableHTTPServer(s.mcpServer,
167+
server.WithEndpointPath("/mcp"),
168+
server.WithStateLess(true), // stateless mode
169+
server.WithHeartbeatInterval(30*time.Second),
170+
)
171+
172+
return httpSrv.Start(addr)
173+
}
174+
161175
// handleQueryVulnerability handles the query_vulnerability tool
162176
func (s *Server) handleQueryVulnerability(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
163177
commit := mcp.ParseString(request, "commit", "")
@@ -213,9 +227,14 @@ func (s *Server) handleQueryVulnerability(ctx context.Context, request mcp.CallT
213227

214228
// handleQueryVulnerabilitiesBatch handles the query_vulnerabilities_batch tool
215229
func (s *Server) handleQueryVulnerabilitiesBatch(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
216-
queriesRaw, ok := request.Params.Arguments["queries"].([]interface{})
230+
args, ok := request.Params.Arguments.(map[string]interface{})
231+
if !ok {
232+
return mcp.NewToolResultError("Invalid arguments format"), nil
233+
}
234+
235+
queriesRaw, ok := args["queries"].([]interface{})
217236
if !ok {
218-
return mcp.NewToolResultError("Invalid queries parameter"), nil
237+
return mcp.NewToolResultError("Invalid 'queries' parameter: must be array"), nil
219238
}
220239

221240
// Convert queries to QueryRequest objects

0 commit comments

Comments
 (0)