Skip to content

Commit 454dd09

Browse files
committed
feat: add support for MCP HTTP streaming
Signed-off-by: Donnie Adams <[email protected]>
1 parent 559876f commit 454dd09

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

pkg/mcp/loader.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import (
1515
"github.com/gptscript-ai/gptscript/pkg/mvl"
1616
"github.com/gptscript-ai/gptscript/pkg/types"
1717
"github.com/gptscript-ai/gptscript/pkg/version"
18-
"github.com/mark3labs/mcp-go/client"
18+
mcpclient "github.com/mark3labs/mcp-go/client"
19+
"github.com/mark3labs/mcp-go/client/transport"
1920
"github.com/mark3labs/mcp-go/mcp"
2021
)
2122

@@ -36,7 +37,7 @@ type Local struct {
3637
type Session struct {
3738
ID string
3839
InitResult *mcp.InitializeResult
39-
Client client.MCPClient
40+
Client mcpclient.MCPClient
4041
Config ServerConfig
4142
}
4243

@@ -117,7 +118,7 @@ func (l *Local) LoadTools(ctx context.Context, server ServerConfig, toolName str
117118
// Reset so we don't start a new MCP server, no reason to if one is already running and the allowed tools change.
118119
server.AllowedTools = nil
119120

120-
session, err := l.loadSession(server)
121+
session, err := l.loadSession(server, true)
121122
if err != nil {
122123
return nil, err
123124
}
@@ -279,7 +280,7 @@ func (l *Local) sessionToTools(ctx context.Context, session *Session, toolName s
279280
return toolDefs, nil
280281
}
281282

282-
func (l *Local) loadSession(server ServerConfig) (*Session, error) {
283+
func (l *Local) loadSession(server ServerConfig, tryHTTPStreaming bool) (*Session, error) {
283284
id := hash.Digest(server)
284285
l.lock.Lock()
285286
existing, ok := l.sessions[id]
@@ -294,11 +295,11 @@ func (l *Local) loadSession(server ServerConfig) (*Session, error) {
294295
}
295296

296297
var (
297-
c *client.Client
298+
c *mcpclient.Client
298299
err error
299300
)
300301
if server.Command != "" {
301-
c, err = client.NewStdioMCPClient(server.Command, server.Env, server.Args...)
302+
c, err = mcpclient.NewStdioMCPClient(server.Command, server.Env, server.Args...)
302303
if err != nil {
303304
return nil, fmt.Errorf("failed to create MCP stdio client: %w", err)
304305
}
@@ -314,7 +315,11 @@ func (l *Local) loadSession(server ServerConfig) (*Session, error) {
314315
headers[k] = v
315316
}
316317

317-
c, err = client.NewSSEMCPClient(url, client.WithHeaders(headers))
318+
if tryHTTPStreaming {
319+
c, err = mcpclient.NewStreamableHttpClient(url, transport.WithHTTPHeaders(headers))
320+
} else {
321+
c, err = mcpclient.NewSSEMCPClient(url, mcpclient.WithHeaders(headers))
322+
}
318323
if err != nil {
319324
return nil, fmt.Errorf("failed to create MCP HTTP client: %w", err)
320325
}
@@ -333,6 +338,13 @@ func (l *Local) loadSession(server ServerConfig) (*Session, error) {
333338

334339
initResult, err := c.Initialize(ctx, initRequest)
335340
if err != nil {
341+
if server.Command == "" && tryHTTPStreaming {
342+
// The MCP spec indicates that trying to initialize the client for HTTP streaming and checking for an error
343+
// is the recommended way to determine if the server supports HTTP streaming, falling back to SEE.
344+
// Ideally, we can check for a 400-level error, but our client implementation doesn't expose that information.
345+
// Retrying on any error is harmless.
346+
return l.loadSession(server, false)
347+
}
336348
return nil, fmt.Errorf("failed to initialize MCP client: %w", err)
337349
}
338350

0 commit comments

Comments
 (0)