Skip to content

Commit 12a31a8

Browse files
committed
cover #107
1 parent 2b28205 commit 12a31a8

File tree

2 files changed

+146
-31
lines changed

2 files changed

+146
-31
lines changed

client/client.go

Lines changed: 121 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -160,42 +160,77 @@ func (c *Client) Ping(ctx context.Context) error {
160160
return err
161161
}
162162

163-
func (c *Client) ListResources(
163+
// ListResourcesByPage manually list resources by page.
164+
func (c *Client) ListResourcesByPage(
164165
ctx context.Context,
165166
request mcp.ListResourcesRequest,
166167
) (*mcp.ListResourcesResult, error) {
167-
response, err := c.sendRequest(ctx, "resources/list", request.Params)
168+
result, err := listByPage[mcp.ListResourcesResult](ctx, c, request.PaginatedRequest, "resources/list")
168169
if err != nil {
169170
return nil, err
170171
}
172+
return result, nil
173+
}
171174

172-
var result mcp.ListResourcesResult
173-
if err := json.Unmarshal(*response, &result); err != nil {
174-
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
175+
func (c *Client) ListResources(
176+
ctx context.Context,
177+
request mcp.ListResourcesRequest,
178+
) (*mcp.ListResourcesResult, error) {
179+
result, err := c.ListResourcesByPage(ctx, request)
180+
if err != nil {
181+
return nil, err
182+
}
183+
for result.NextCursor != "" {
184+
select {
185+
case <-ctx.Done():
186+
return nil, ctx.Err()
187+
default:
188+
request.Params.Cursor = result.NextCursor
189+
newPageRes, err := c.ListResourcesByPage(ctx, request)
190+
if err != nil {
191+
return nil, err
192+
}
193+
result.Resources = append(result.Resources, newPageRes.Resources...)
194+
result.NextCursor = newPageRes.NextCursor
195+
}
175196
}
197+
return result, nil
198+
}
176199

177-
return &result, nil
200+
func (c *Client) ListResourceTemplatesByPage(
201+
ctx context.Context,
202+
request mcp.ListResourceTemplatesRequest,
203+
) (*mcp.ListResourceTemplatesResult, error) {
204+
result, err := listByPage[mcp.ListResourceTemplatesResult](ctx, c, request.PaginatedRequest, "resources/templates/list")
205+
if err != nil {
206+
return nil, err
207+
}
208+
return result, nil
178209
}
179210

180211
func (c *Client) ListResourceTemplates(
181212
ctx context.Context,
182213
request mcp.ListResourceTemplatesRequest,
183214
) (*mcp.ListResourceTemplatesResult, error) {
184-
response, err := c.sendRequest(
185-
ctx,
186-
"resources/templates/list",
187-
request.Params,
188-
)
215+
result, err := c.ListResourceTemplatesByPage(ctx, request)
189216
if err != nil {
190217
return nil, err
191218
}
192-
193-
var result mcp.ListResourceTemplatesResult
194-
if err := json.Unmarshal(*response, &result); err != nil {
195-
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
219+
for result.NextCursor != "" {
220+
select {
221+
case <-ctx.Done():
222+
return nil, ctx.Err()
223+
default:
224+
request.Params.Cursor = result.NextCursor
225+
newPageRes, err := c.ListResourceTemplatesByPage(ctx, request)
226+
if err != nil {
227+
return nil, err
228+
}
229+
result.ResourceTemplates = append(result.ResourceTemplates, newPageRes.ResourceTemplates...)
230+
result.NextCursor = newPageRes.NextCursor
231+
}
196232
}
197-
198-
return &result, nil
233+
return result, nil
199234
}
200235

201236
func (c *Client) ReadResource(
@@ -226,21 +261,40 @@ func (c *Client) Unsubscribe(
226261
return err
227262
}
228263

229-
func (c *Client) ListPrompts(
264+
func (c *Client) ListPromptsByPage(
230265
ctx context.Context,
231266
request mcp.ListPromptsRequest,
232267
) (*mcp.ListPromptsResult, error) {
233-
response, err := c.sendRequest(ctx, "prompts/list", request.Params)
268+
result, err := listByPage[mcp.ListPromptsResult](ctx, c, request.PaginatedRequest, "prompts/list")
234269
if err != nil {
235270
return nil, err
236271
}
272+
return result, nil
273+
}
237274

238-
var result mcp.ListPromptsResult
239-
if err := json.Unmarshal(*response, &result); err != nil {
240-
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
275+
func (c *Client) ListPrompts(
276+
ctx context.Context,
277+
request mcp.ListPromptsRequest,
278+
) (*mcp.ListPromptsResult, error) {
279+
result, err := c.ListPromptsByPage(ctx, request)
280+
if err != nil {
281+
return nil, err
241282
}
242-
243-
return &result, nil
283+
for result.NextCursor != "" {
284+
select {
285+
case <-ctx.Done():
286+
return nil, ctx.Err()
287+
default:
288+
request.Params.Cursor = result.NextCursor
289+
newPageRes, err := c.ListPromptsByPage(ctx, request)
290+
if err != nil {
291+
return nil, err
292+
}
293+
result.Prompts = append(result.Prompts, newPageRes.Prompts...)
294+
result.NextCursor = newPageRes.NextCursor
295+
}
296+
}
297+
return result, nil
244298
}
245299

246300
func (c *Client) GetPrompt(
@@ -255,21 +309,40 @@ func (c *Client) GetPrompt(
255309
return mcp.ParseGetPromptResult(response)
256310
}
257311

258-
func (c *Client) ListTools(
312+
func (c *Client) ListToolsByPage(
259313
ctx context.Context,
260314
request mcp.ListToolsRequest,
261315
) (*mcp.ListToolsResult, error) {
262-
response, err := c.sendRequest(ctx, "tools/list", request.Params)
316+
result, err := listByPage[mcp.ListToolsResult](ctx, c, request.PaginatedRequest, "tools/list")
263317
if err != nil {
264318
return nil, err
265319
}
320+
return result, nil
321+
}
266322

267-
var result mcp.ListToolsResult
268-
if err := json.Unmarshal(*response, &result); err != nil {
269-
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
323+
func (c *Client) ListTools(
324+
ctx context.Context,
325+
request mcp.ListToolsRequest,
326+
) (*mcp.ListToolsResult, error) {
327+
result, err := c.ListToolsByPage(ctx, request)
328+
if err != nil {
329+
return nil, err
270330
}
271-
272-
return &result, nil
331+
for result.NextCursor != "" {
332+
select {
333+
case <-ctx.Done():
334+
return nil, ctx.Err()
335+
default:
336+
request.Params.Cursor = result.NextCursor
337+
newPageRes, err := c.ListToolsByPage(ctx, request)
338+
if err != nil {
339+
return nil, err
340+
}
341+
result.Tools = append(result.Tools, newPageRes.Tools...)
342+
result.NextCursor = newPageRes.NextCursor
343+
}
344+
}
345+
return result, nil
273346
}
274347

275348
func (c *Client) CallTool(
@@ -309,6 +382,23 @@ func (c *Client) Complete(
309382
return &result, nil
310383
}
311384

385+
func listByPage[T any](
386+
ctx context.Context,
387+
client *Client,
388+
request mcp.PaginatedRequest,
389+
method string,
390+
) (*T, error) {
391+
response, err := client.sendRequest(ctx, method, request.Params)
392+
if err != nil {
393+
return nil, err
394+
}
395+
var result T
396+
if err := json.Unmarshal(*response, &result); err != nil {
397+
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
398+
}
399+
return &result, nil
400+
}
401+
312402
// Helper methods
313403

314404
// GetTransport gives access to the underlying transport layer.

client/interface.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,25 @@ type MCPClient interface {
1818
// Ping checks if the server is alive
1919
Ping(ctx context.Context) error
2020

21+
// ListResourcesByPage manually list resources by page.
22+
ListResourcesByPage(
23+
ctx context.Context,
24+
request mcp.ListResourcesRequest,
25+
) (*mcp.ListResourcesResult, error)
26+
2127
// ListResources requests a list of available resources from the server
2228
ListResources(
2329
ctx context.Context,
2430
request mcp.ListResourcesRequest,
2531
) (*mcp.ListResourcesResult, error)
2632

33+
// ListResourceTemplatesByPage manually list resource templates by page.
34+
ListResourceTemplatesByPage(
35+
ctx context.Context,
36+
request mcp.ListResourceTemplatesRequest,
37+
) (*mcp.ListResourceTemplatesResult,
38+
error)
39+
2740
// ListResourceTemplates requests a list of available resource templates from the server
2841
ListResourceTemplates(
2942
ctx context.Context,
@@ -43,6 +56,12 @@ type MCPClient interface {
4356
// Unsubscribe cancels notifications for a specific resource
4457
Unsubscribe(ctx context.Context, request mcp.UnsubscribeRequest) error
4558

59+
// ListPromptsByPage manually list prompts by page.
60+
ListPromptsByPage(
61+
ctx context.Context,
62+
request mcp.ListPromptsRequest,
63+
) (*mcp.ListPromptsResult, error)
64+
4665
// ListPrompts requests a list of available prompts from the server
4766
ListPrompts(
4867
ctx context.Context,
@@ -55,6 +74,12 @@ type MCPClient interface {
5574
request mcp.GetPromptRequest,
5675
) (*mcp.GetPromptResult, error)
5776

77+
// ListToolsByPage manually list tools by page.
78+
ListToolsByPage(
79+
ctx context.Context,
80+
request mcp.ListToolsRequest,
81+
) (*mcp.ListToolsResult, error)
82+
5883
// ListTools requests a list of available tools from the server
5984
ListTools(
6085
ctx context.Context,

0 commit comments

Comments
 (0)