wolfpack-mcp 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -1,4 +1,8 @@
1
1
  import { ApiClient } from './apiClient.js';
2
+ // Maximum number of items to fetch without confirmation
3
+ const MAX_ITEMS_THRESHOLD = 200;
4
+ // Page size for fetching all items
5
+ const PAGE_SIZE = 50;
2
6
  export class WolfpackClient {
3
7
  api;
4
8
  teamId = null;
@@ -31,6 +35,48 @@ export class WolfpackClient {
31
35
  async listTeams() {
32
36
  return this.api.get('/teams');
33
37
  }
38
+ // Helper to fetch all pages of a paginated endpoint
39
+ async fetchAllPages(endpoint, baseParams) {
40
+ // First request to get total count
41
+ const firstParams = new URLSearchParams(baseParams);
42
+ firstParams.set('limit', PAGE_SIZE.toString());
43
+ firstParams.set('offset', '0');
44
+ const firstQuery = firstParams.toString();
45
+ const firstPage = await this.api.get(`${endpoint}${firstQuery ? `?${firstQuery}` : ''}`);
46
+ // If total exceeds threshold, return first page with truncation warning
47
+ if (firstPage.total > MAX_ITEMS_THRESHOLD) {
48
+ return {
49
+ items: firstPage.items,
50
+ total: firstPage.total,
51
+ truncated: true,
52
+ };
53
+ }
54
+ // If all items fit in first page, return them
55
+ if (firstPage.items.length >= firstPage.total) {
56
+ return {
57
+ items: firstPage.items,
58
+ total: firstPage.total,
59
+ truncated: false,
60
+ };
61
+ }
62
+ // Fetch remaining pages
63
+ const allItems = [...firstPage.items];
64
+ let offset = PAGE_SIZE;
65
+ while (offset < firstPage.total) {
66
+ const params = new URLSearchParams(baseParams);
67
+ params.set('limit', PAGE_SIZE.toString());
68
+ params.set('offset', offset.toString());
69
+ const query = params.toString();
70
+ const page = await this.api.get(`${endpoint}${query ? `?${query}` : ''}`);
71
+ allItems.push(...page.items);
72
+ offset += PAGE_SIZE;
73
+ }
74
+ return {
75
+ items: allItems,
76
+ total: firstPage.total,
77
+ truncated: false,
78
+ };
79
+ }
34
80
  // Work Item methods
35
81
  async listWorkItems(options) {
36
82
  const params = new URLSearchParams();
@@ -38,12 +84,22 @@ export class WolfpackClient {
38
84
  params.append('teamId', options.teamId.toString());
39
85
  if (options?.status)
40
86
  params.append('status', options.status);
41
- if (options?.limit)
42
- params.append('limit', options.limit.toString());
43
- if (options?.offset)
44
- params.append('offset', options.offset.toString());
45
- const query = params.toString();
46
- return this.api.get(`/work-items${query ? `?${query}` : ''}`);
87
+ // If explicit limit/offset provided, use single request (for manual pagination)
88
+ if (options?.limit !== undefined || options?.offset !== undefined) {
89
+ if (options?.limit)
90
+ params.append('limit', options.limit.toString());
91
+ if (options?.offset)
92
+ params.append('offset', options.offset.toString());
93
+ const query = params.toString();
94
+ const response = await this.api.get(`/work-items${query ? `?${query}` : ''}`);
95
+ return {
96
+ items: response.items,
97
+ total: response.total,
98
+ truncated: response.total > response.items.length,
99
+ };
100
+ }
101
+ // Otherwise, fetch all pages automatically
102
+ return this.fetchAllPages('/work-items', params);
47
103
  }
48
104
  async getWorkItem(workItemId, teamId) {
49
105
  try {
@@ -91,12 +147,21 @@ export class WolfpackClient {
91
147
  params.append('teamId', options.teamId.toString());
92
148
  if (options?.stage)
93
149
  params.append('stage', options.stage);
94
- if (options?.limit)
95
- params.append('limit', options.limit.toString());
96
- if (options?.offset)
97
- params.append('offset', options.offset.toString());
98
- const query = params.toString();
99
- return this.api.get(`/radar-items${query ? `?${query}` : ''}`);
150
+ // If explicit limit/offset provided, use single request
151
+ if (options?.limit !== undefined || options?.offset !== undefined) {
152
+ if (options?.limit)
153
+ params.append('limit', options.limit.toString());
154
+ if (options?.offset)
155
+ params.append('offset', options.offset.toString());
156
+ const query = params.toString();
157
+ const response = await this.api.get(`/radar-items${query ? `?${query}` : ''}`);
158
+ return {
159
+ items: response.items,
160
+ total: response.total,
161
+ truncated: response.total > response.items.length,
162
+ };
163
+ }
164
+ return this.fetchAllPages('/radar-items', params);
100
165
  }
101
166
  async getRadarItem(itemId, teamId) {
102
167
  try {
@@ -126,12 +191,21 @@ export class WolfpackClient {
126
191
  params.append('type', options.type);
127
192
  if (options?.assignedToId)
128
193
  params.append('assignedToId', options.assignedToId);
129
- if (options?.limit)
130
- params.append('limit', options.limit.toString());
131
- if (options?.offset)
132
- params.append('offset', options.offset.toString());
133
- const query = params.toString();
134
- return this.api.get(`/issues${query ? `?${query}` : ''}`);
194
+ // If explicit limit/offset provided, use single request
195
+ if (options?.limit !== undefined || options?.offset !== undefined) {
196
+ if (options?.limit)
197
+ params.append('limit', options.limit.toString());
198
+ if (options?.offset)
199
+ params.append('offset', options.offset.toString());
200
+ const query = params.toString();
201
+ const response = await this.api.get(`/issues${query ? `?${query}` : ''}`);
202
+ return {
203
+ items: response.items,
204
+ total: response.total,
205
+ truncated: response.total > response.items.length,
206
+ };
207
+ }
208
+ return this.fetchAllPages('/issues', params);
135
209
  }
136
210
  async getIssue(issueId, teamId) {
137
211
  try {
@@ -161,12 +235,21 @@ export class WolfpackClient {
161
235
  // Wiki Page methods
162
236
  async listWikiPages(options) {
163
237
  const params = new URLSearchParams();
164
- if (options?.limit)
165
- params.append('limit', options.limit.toString());
166
- if (options?.offset)
167
- params.append('offset', options.offset.toString());
168
- const query = params.toString();
169
- return this.api.get(`/wiki-pages${query ? `?${query}` : ''}`);
238
+ // If explicit limit/offset provided, use single request
239
+ if (options?.limit !== undefined || options?.offset !== undefined) {
240
+ if (options?.limit)
241
+ params.append('limit', options.limit.toString());
242
+ if (options?.offset)
243
+ params.append('offset', options.offset.toString());
244
+ const query = params.toString();
245
+ const response = await this.api.get(`/wiki-pages${query ? `?${query}` : ''}`);
246
+ return {
247
+ items: response.items,
248
+ total: response.total,
249
+ truncated: response.total > response.items.length,
250
+ };
251
+ }
252
+ return this.fetchAllPages('/wiki-pages', params);
170
253
  }
171
254
  async getWikiPage(pageId) {
172
255
  try {
@@ -188,12 +271,21 @@ export class WolfpackClient {
188
271
  // Journal Entry methods
189
272
  async listJournalEntries(options) {
190
273
  const params = new URLSearchParams();
191
- if (options?.limit)
192
- params.append('limit', options.limit.toString());
193
- if (options?.offset)
194
- params.append('offset', options.offset.toString());
195
- const query = params.toString();
196
- return this.api.get(`/journal-entries${query ? `?${query}` : ''}`);
274
+ // If explicit limit/offset provided, use single request
275
+ if (options?.limit !== undefined || options?.offset !== undefined) {
276
+ if (options?.limit)
277
+ params.append('limit', options.limit.toString());
278
+ if (options?.offset)
279
+ params.append('offset', options.offset.toString());
280
+ const query = params.toString();
281
+ const response = await this.api.get(`/journal-entries${query ? `?${query}` : ''}`);
282
+ return {
283
+ items: response.items,
284
+ total: response.total,
285
+ truncated: response.total > response.items.length,
286
+ };
287
+ }
288
+ return this.fetchAllPages('/journal-entries', params);
197
289
  }
198
290
  async getJournalEntry(entryId, teamId) {
199
291
  try {
package/dist/index.js CHANGED
@@ -573,14 +573,18 @@ class WolfpackMCPServer {
573
573
  // Work Item handlers
574
574
  case 'list_work_items': {
575
575
  const parsed = ListWorkItemsSchema.parse(args);
576
- const workItems = await this.client.listWorkItems({
576
+ const result = await this.client.listWorkItems({
577
577
  teamId: parsed.team_id || this.client.getTeamId() || undefined,
578
578
  status: parsed.status,
579
579
  limit: parsed.limit,
580
580
  offset: parsed.offset,
581
581
  });
582
+ let text = JSON.stringify(result.items, null, 2);
583
+ if (result.truncated) {
584
+ text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use status filter or limit/offset for pagination.\n\n${text}`;
585
+ }
582
586
  return {
583
- content: [{ type: 'text', text: JSON.stringify(workItems, null, 2) }],
587
+ content: [{ type: 'text', text }],
584
588
  };
585
589
  }
586
590
  case 'get_work_item': {
@@ -632,14 +636,18 @@ class WolfpackMCPServer {
632
636
  // Radar Item handlers
633
637
  case 'list_radar_items': {
634
638
  const parsed = ListRadarItemsSchema.parse(args);
635
- const radarItems = await this.client.listRadarItems({
639
+ const result = await this.client.listRadarItems({
636
640
  teamId: parsed.team_id,
637
641
  stage: parsed.stage,
638
642
  limit: parsed.limit,
639
643
  offset: parsed.offset,
640
644
  });
645
+ let text = JSON.stringify(result.items, null, 2);
646
+ if (result.truncated) {
647
+ text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use stage filter or limit/offset for pagination.\n\n${text}`;
648
+ }
641
649
  return {
642
- content: [{ type: 'text', text: JSON.stringify(radarItems, null, 2) }],
650
+ content: [{ type: 'text', text }],
643
651
  };
644
652
  }
645
653
  case 'get_radar_item': {
@@ -657,7 +665,7 @@ class WolfpackMCPServer {
657
665
  // Issue handlers
658
666
  case 'list_issues': {
659
667
  const parsed = ListIssuesSchema.parse(args);
660
- const issues = await this.client.listIssues({
668
+ const result = await this.client.listIssues({
661
669
  teamId: parsed.team_id,
662
670
  status: parsed.status,
663
671
  severity: parsed.severity,
@@ -666,8 +674,12 @@ class WolfpackMCPServer {
666
674
  limit: parsed.limit,
667
675
  offset: parsed.offset,
668
676
  });
677
+ let text = JSON.stringify(result.items, null, 2);
678
+ if (result.truncated) {
679
+ text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} items. Use filters or limit/offset for pagination.\n\n${text}`;
680
+ }
669
681
  return {
670
- content: [{ type: 'text', text: JSON.stringify(issues, null, 2) }],
682
+ content: [{ type: 'text', text }],
671
683
  };
672
684
  }
673
685
  case 'get_issue': {
@@ -747,12 +759,16 @@ class WolfpackMCPServer {
747
759
  // Wiki Page handlers
748
760
  case 'list_wiki_pages': {
749
761
  const parsed = ListWikiPagesSchema.parse(args);
750
- const pages = await this.client.listWikiPages({
762
+ const result = await this.client.listWikiPages({
751
763
  limit: parsed.limit,
752
764
  offset: parsed.offset,
753
765
  });
766
+ let text = JSON.stringify(result.items, null, 2);
767
+ if (result.truncated) {
768
+ text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} pages. Use limit/offset for pagination.\n\n${text}`;
769
+ }
754
770
  return {
755
- content: [{ type: 'text', text: JSON.stringify(pages, null, 2) }],
771
+ content: [{ type: 'text', text }],
756
772
  };
757
773
  }
758
774
  case 'get_wiki_page': {
@@ -801,12 +817,16 @@ class WolfpackMCPServer {
801
817
  // Journal Entry handlers
802
818
  case 'list_journal_entries': {
803
819
  const parsed = ListJournalEntriesSchema.parse(args);
804
- const entries = await this.client.listJournalEntries({
820
+ const result = await this.client.listJournalEntries({
805
821
  limit: parsed.limit,
806
822
  offset: parsed.offset,
807
823
  });
824
+ let text = JSON.stringify(result.items, null, 2);
825
+ if (result.truncated) {
826
+ text = `Note: Results truncated. Showing ${result.items.length} of ${result.total} entries. Use limit/offset for pagination.\n\n${text}`;
827
+ }
808
828
  return {
809
- content: [{ type: 'text', text: JSON.stringify(entries, null, 2) }],
829
+ content: [{ type: 'text', text }],
810
830
  };
811
831
  }
812
832
  case 'get_journal_entry': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolfpack-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "MCP server for Wolfpack AI-enhanced software delivery tools",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",