Skip to content

Commit d82bf78

Browse files
committed
update client
1 parent 3562dbe commit d82bf78

File tree

4 files changed

+161
-46
lines changed

4 files changed

+161
-46
lines changed

README-streamable-http.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func main() {
174174
})
175175

176176
// Create a context with timeout
177-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
177+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
178178
defer cancel()
179179

180180
// Initialize the connection
@@ -195,11 +195,30 @@ func main() {
195195
initResponseJSON, _ := json.MarshalIndent(initResponse, "", " ")
196196
fmt.Printf("Initialization response: %s\n", initResponseJSON)
197197

198+
// List available tools
199+
fmt.Println("\nListing available tools...")
200+
listToolsRequest := transport.JSONRPCRequest{
201+
JSONRPC: "2.0",
202+
ID: 2,
203+
Method: "tools/list",
204+
}
205+
206+
listToolsResponse, err := trans.SendRequest(ctx, listToolsRequest)
207+
if err != nil {
208+
fmt.Printf("Failed to list tools: %v\n", err)
209+
os.Exit(1)
210+
}
211+
212+
// Print the tools list response
213+
toolsResponseJSON, _ := json.MarshalIndent(listToolsResponse, "", " ")
214+
fmt.Printf("Tools list response: %s\n", toolsResponseJSON)
215+
198216
// Call the echo tool
199217
fmt.Println("\nCalling echo tool...")
218+
fmt.Println("Using session ID from initialization...")
200219
echoRequest := transport.JSONRPCRequest{
201220
JSONRPC: "2.0",
202-
ID: 2,
221+
ID: 3,
203222
Method: "tools/call",
204223
Params: map[string]interface{}{
205224
"name": "echo",
@@ -221,6 +240,7 @@ func main() {
221240

222241
// Wait for notifications (the echo tool sends a notification after 1 second)
223242
fmt.Println("\nWaiting for notifications...")
243+
fmt.Println("(The server should send a notification about 1 second after the tool call)")
224244

225245
// Set up a signal channel to handle Ctrl+C
226246
sigChan := make(chan os.Signal, 1)

examples/streamable_http_client/main.go

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@ import (
55
"encoding/json"
66
"fmt"
77
"os"
8-
"os/signal"
9-
"syscall"
108
"time"
119

1210
"github.com/mark3labs/mcp-go/client/transport"
1311
"github.com/mark3labs/mcp-go/mcp"
1412
)
1513

1614
func main() {
17-
// Create a new Streamable HTTP transport
18-
trans, err := transport.NewStreamableHTTP("http://localhost:8080/mcp")
15+
// Create a new Streamable HTTP transport with a longer timeout
16+
trans, err := transport.NewStreamableHTTP("http://localhost:8080/mcp",
17+
transport.WithHTTPTimeout(30*time.Second))
1918
if err != nil {
2019
fmt.Printf("Failed to create transport: %v\n", err)
2120
os.Exit(1)
@@ -30,7 +29,7 @@ func main() {
3029
})
3130

3231
// Create a context with timeout
33-
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
32+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
3433
defer cancel()
3534

3635
// Initialize the connection
@@ -50,43 +49,8 @@ func main() {
5049
// Print the initialization response
5150
initResponseJSON, _ := json.MarshalIndent(initResponse, "", " ")
5251
fmt.Printf("Initialization response: %s\n", initResponseJSON)
52+
fmt.Printf("Session ID: %s\n", trans.GetSessionId())
5353

54-
// Call the echo tool
55-
fmt.Println("\nCalling echo tool...")
56-
echoRequest := transport.JSONRPCRequest{
57-
JSONRPC: "2.0",
58-
ID: 2,
59-
Method: "tools/call",
60-
Params: map[string]interface{}{
61-
"name": "echo",
62-
"arguments": map[string]interface{}{
63-
"message": "Hello from Streamable HTTP client!",
64-
},
65-
},
66-
}
67-
68-
echoResponse, err := trans.SendRequest(ctx, echoRequest)
69-
if err != nil {
70-
fmt.Printf("Failed to call echo tool: %v\n", err)
71-
os.Exit(1)
72-
}
73-
74-
// Print the echo response
75-
echoResponseJSON, _ := json.MarshalIndent(echoResponse, "", " ")
76-
fmt.Printf("Echo response: %s\n", echoResponseJSON)
77-
78-
// Wait for notifications (the echo tool sends a notification after 1 second)
79-
fmt.Println("\nWaiting for notifications...")
80-
81-
// Set up a signal channel to handle Ctrl+C
82-
sigChan := make(chan os.Signal, 1)
83-
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
84-
85-
// Wait for either a signal or a timeout
86-
select {
87-
case <-sigChan:
88-
fmt.Println("Received interrupt signal, exiting...")
89-
case <-time.After(5 * time.Second):
90-
fmt.Println("Timeout reached, exiting...")
91-
}
54+
// Wait for a moment
55+
fmt.Println("\nInitialization successful. Exiting...")
9256
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"os"
8+
"os/signal"
9+
"syscall"
10+
"time"
11+
12+
"github.com/mark3labs/mcp-go/client/transport"
13+
"github.com/mark3labs/mcp-go/mcp"
14+
)
15+
16+
func main() {
17+
// Create a new Streamable HTTP transport with a longer timeout
18+
trans, err := transport.NewStreamableHTTP("http://localhost:8080/mcp",
19+
transport.WithHTTPTimeout(30*time.Second))
20+
if err != nil {
21+
fmt.Printf("Failed to create transport: %v\n", err)
22+
os.Exit(1)
23+
}
24+
defer trans.Close()
25+
26+
// Set up notification handler
27+
trans.SetNotificationHandler(func(notification mcp.JSONRPCNotification) {
28+
fmt.Printf("\nReceived notification: %s\n", notification.Method)
29+
params, _ := json.MarshalIndent(notification.Params, "", " ")
30+
fmt.Printf("Params: %s\n", params)
31+
})
32+
33+
// Create a context with timeout
34+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
35+
defer cancel()
36+
37+
// Initialize the connection
38+
fmt.Println("Initializing connection...")
39+
initRequest := transport.JSONRPCRequest{
40+
JSONRPC: "2.0",
41+
ID: 1,
42+
Method: "initialize",
43+
}
44+
45+
initResponse, err := trans.SendRequest(ctx, initRequest)
46+
if err != nil {
47+
fmt.Printf("Failed to initialize: %v\n", err)
48+
os.Exit(1)
49+
}
50+
51+
// Print the initialization response
52+
initResponseJSON, _ := json.MarshalIndent(initResponse, "", " ")
53+
fmt.Printf("Initialization response: %s\n", initResponseJSON)
54+
fmt.Printf("Session ID: %s\n", trans.GetSessionId())
55+
56+
// List available tools
57+
fmt.Println("\nListing available tools...")
58+
listToolsRequest := transport.JSONRPCRequest{
59+
JSONRPC: "2.0",
60+
ID: 2,
61+
Method: "tools/list",
62+
}
63+
64+
listToolsResponse, err := trans.SendRequest(ctx, listToolsRequest)
65+
if err != nil {
66+
fmt.Printf("Failed to list tools: %v\n", err)
67+
os.Exit(1)
68+
}
69+
70+
// Print the tools list response
71+
toolsResponseJSON, _ := json.MarshalIndent(listToolsResponse, "", " ")
72+
fmt.Printf("Tools list response: %s\n", toolsResponseJSON)
73+
74+
// Extract tool information
75+
var toolsResult struct {
76+
Result struct {
77+
Tools []struct {
78+
Name string `json:"name"`
79+
Description string `json:"description"`
80+
} `json:"tools"`
81+
} `json:"result"`
82+
}
83+
if err := json.Unmarshal(listToolsResponse.Result, &toolsResult); err != nil {
84+
fmt.Printf("Failed to parse tools list: %v\n", err)
85+
} else {
86+
fmt.Println("\nAvailable tools:")
87+
for _, tool := range toolsResult.Result.Tools {
88+
fmt.Printf("- %s: %s\n", tool.Name, tool.Description)
89+
}
90+
}
91+
92+
// Call the echo tool
93+
fmt.Println("\nCalling echo tool...")
94+
echoRequest := transport.JSONRPCRequest{
95+
JSONRPC: "2.0",
96+
ID: 3,
97+
Method: "tools/call",
98+
Params: map[string]interface{}{
99+
"name": "echo",
100+
"arguments": map[string]interface{}{
101+
"message": "Hello from Streamable HTTP client!",
102+
},
103+
},
104+
}
105+
106+
echoResponse, err := trans.SendRequest(ctx, echoRequest)
107+
if err != nil {
108+
fmt.Printf("Failed to call echo tool: %v\n", err)
109+
os.Exit(1)
110+
}
111+
112+
// Print the echo response
113+
echoResponseJSON, _ := json.MarshalIndent(echoResponse, "", " ")
114+
fmt.Printf("Echo response: %s\n", echoResponseJSON)
115+
116+
// Wait for notifications (the echo tool sends a notification after 1 second)
117+
fmt.Println("\nWaiting for notifications...")
118+
fmt.Println("(The server should send a notification about 1 second after the tool call)")
119+
120+
// Set up a signal channel to handle Ctrl+C
121+
sigChan := make(chan os.Signal, 1)
122+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
123+
124+
// Wait for either a signal or a timeout
125+
select {
126+
case <-sigChan:
127+
fmt.Println("Received interrupt signal, exiting...")
128+
case <-time.After(5 * time.Second):
129+
fmt.Println("Timeout reached, exiting...")
130+
}
131+
}

examples/streamable_http_server/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func main() {
7171

7272
// Create a new Streamable HTTP server
7373
streamableServer := server.NewStreamableHTTPServer(mcpServer,
74-
server.WithEnableJSONResponse(false), // Use SSE streaming by default
74+
server.WithEnableJSONResponse(true), // Use direct JSON responses for simplicity
7575
)
7676

7777
// Start the server in a goroutine

0 commit comments

Comments
 (0)