wolfpack-mcp 1.0.30 → 1.0.31
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 +23 -23
- package/dist/config.js +4 -4
- package/dist/index.js +87 -72
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -5,47 +5,47 @@ const MAX_ITEMS_THRESHOLD = 200;
|
|
|
5
5
|
const PAGE_SIZE = 50;
|
|
6
6
|
export class WolfpackClient {
|
|
7
7
|
api;
|
|
8
|
-
|
|
8
|
+
projectId = null;
|
|
9
9
|
constructor() {
|
|
10
10
|
this.api = new ApiClient();
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Fetch and cache the
|
|
14
|
-
* Uses the MCP team endpoint to
|
|
13
|
+
* Fetch and cache the project ID from a project slug.
|
|
14
|
+
* Uses the MCP team endpoint to resolve slug to ID.
|
|
15
15
|
*/
|
|
16
|
-
async
|
|
16
|
+
async resolveProjectSlug(projectSlug) {
|
|
17
17
|
try {
|
|
18
|
-
const
|
|
19
|
-
this.
|
|
20
|
-
return
|
|
18
|
+
const project = await this.api.get(`/team/${projectSlug}`);
|
|
19
|
+
this.projectId = project.id;
|
|
20
|
+
return project.id;
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
|
23
|
-
throw new Error(`Failed to resolve
|
|
23
|
+
throw new Error(`Failed to resolve project slug "${projectSlug}": ${error instanceof Error ? error.message : String(error)}`);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
return this.
|
|
26
|
+
getProjectId() {
|
|
27
|
+
return this.projectId;
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
this.
|
|
29
|
+
setProjectId(projectId) {
|
|
30
|
+
this.projectId = projectId;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Resolve a
|
|
33
|
+
* Resolve a project slug from a project ID or the cached project ID.
|
|
34
34
|
*/
|
|
35
|
-
async resolveSlug(
|
|
36
|
-
const id =
|
|
35
|
+
async resolveSlug(projectId) {
|
|
36
|
+
const id = projectId || this.projectId;
|
|
37
37
|
if (!id)
|
|
38
|
-
throw new Error('No
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
if (!
|
|
42
|
-
throw new Error(`
|
|
43
|
-
return
|
|
38
|
+
throw new Error('No project selected. Use list_projects first.');
|
|
39
|
+
const projects = await this.listProjects();
|
|
40
|
+
const project = projects.find((t) => t.id === id);
|
|
41
|
+
if (!project)
|
|
42
|
+
throw new Error(`Project with ID ${id} not found`);
|
|
43
|
+
return project.slug;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
* List all
|
|
46
|
+
* List all projects the authenticated user is a member of.
|
|
47
47
|
*/
|
|
48
|
-
async
|
|
48
|
+
async listProjects() {
|
|
49
49
|
const response = await this.api.get('/teams');
|
|
50
50
|
return response.teams;
|
|
51
51
|
}
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const config = {
|
|
2
2
|
apiUrl: process.env.WOLFPACK_API_URL || 'https://wolfpacks.work/api/mcp',
|
|
3
3
|
apiKey: process.env.WOLFPACK_API_KEY,
|
|
4
|
-
|
|
4
|
+
projectSlug: process.env.WOLFPACK_PROJECT_SLUG || process.env.WOLFPACK_TEAM_SLUG,
|
|
5
5
|
};
|
|
6
6
|
// Validate configuration on startup
|
|
7
7
|
export function validateConfig() {
|
|
@@ -17,10 +17,10 @@ export function validateConfig() {
|
|
|
17
17
|
process.exit(1);
|
|
18
18
|
}
|
|
19
19
|
console.error(`MCP Server connecting to: ${config.apiUrl}`);
|
|
20
|
-
if (config.
|
|
21
|
-
console.error(`
|
|
20
|
+
if (config.projectSlug) {
|
|
21
|
+
console.error(`Project configured: ${config.projectSlug}`);
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
|
-
console.error('No
|
|
24
|
+
console.error('No project configured - will auto-detect or use list_projects tool');
|
|
25
25
|
}
|
|
26
26
|
}
|
package/dist/index.js
CHANGED
|
@@ -46,7 +46,7 @@ async function checkForUpdates() {
|
|
|
46
46
|
// Work Item schemas
|
|
47
47
|
// Use z.coerce.string() to handle any type coercion issues from MCP args
|
|
48
48
|
const ListWorkItemsSchema = z.object({
|
|
49
|
-
|
|
49
|
+
project_id: z.number().optional().describe('Project ID to filter work items'),
|
|
50
50
|
status: z.coerce
|
|
51
51
|
.string()
|
|
52
52
|
.optional()
|
|
@@ -85,7 +85,7 @@ const ListWorkItemsSchema = z.object({
|
|
|
85
85
|
});
|
|
86
86
|
const GetWorkItemSchema = z.object({
|
|
87
87
|
work_item_id: z.string().describe('The ID (UUID) or refId (number) of the work item'),
|
|
88
|
-
|
|
88
|
+
project_id: z.number().optional().describe('Project ID (required when looking up by refId)'),
|
|
89
89
|
});
|
|
90
90
|
const UpdateWorkProgressSchema = z.object({
|
|
91
91
|
work_item_id: z.string().describe('The ID of the work item'),
|
|
@@ -111,7 +111,7 @@ const PullWorkItemSchema = z.object({
|
|
|
111
111
|
});
|
|
112
112
|
// Radar Item (Initiative/Roadmap) schemas
|
|
113
113
|
const ListRadarItemsSchema = z.object({
|
|
114
|
-
|
|
114
|
+
project_id: z.number().optional().describe('Project ID to filter radar items'),
|
|
115
115
|
stage: z
|
|
116
116
|
.enum(['pending', 'now', 'next', 'later', 'completed'])
|
|
117
117
|
.optional()
|
|
@@ -122,11 +122,11 @@ const ListRadarItemsSchema = z.object({
|
|
|
122
122
|
});
|
|
123
123
|
const GetRadarItemSchema = z.object({
|
|
124
124
|
item_id: z.string().describe('The ID (UUID) or refId (number) of the radar item'),
|
|
125
|
-
|
|
125
|
+
project_id: z.number().optional().describe('Project ID (required when looking up by refId)'),
|
|
126
126
|
});
|
|
127
127
|
// Issue schemas
|
|
128
128
|
const ListIssuesSchema = z.object({
|
|
129
|
-
|
|
129
|
+
project_id: z.number().optional().describe('Project ID to filter issues'),
|
|
130
130
|
status: z
|
|
131
131
|
.enum(['open', 'in-progress', 'resolved', 'closed'])
|
|
132
132
|
.optional()
|
|
@@ -159,7 +159,7 @@ const ListIssuesSchema = z.object({
|
|
|
159
159
|
});
|
|
160
160
|
const GetIssueSchema = z.object({
|
|
161
161
|
issue_id: z.string().describe('The ID (UUID) or refId (number) of the issue'),
|
|
162
|
-
|
|
162
|
+
project_id: z.number().optional().describe('Project ID (required when looking up by refId)'),
|
|
163
163
|
});
|
|
164
164
|
// Create schemas
|
|
165
165
|
const CreateWorkItemSchema = z.object({
|
|
@@ -223,7 +223,14 @@ const GetWikiPageSchema = z.object({
|
|
|
223
223
|
page_id: z.string().describe('The page UUID or slug'),
|
|
224
224
|
});
|
|
225
225
|
const CreateWikiPageSchema = z.object({
|
|
226
|
-
slug: z
|
|
226
|
+
slug: z
|
|
227
|
+
.string()
|
|
228
|
+
.describe('URL slug for the page (without team prefix). The system automatically prepends the team and wiki path. For example, to create a page at "myteam/wiki/guides/onboarding", pass just "guides/onboarding". Do NOT include the team slug or "wiki/" prefix.')
|
|
229
|
+
.transform((slug) => {
|
|
230
|
+
// Strip accidental team/wiki prefix (e.g., "myteam/wiki/foo" → "foo")
|
|
231
|
+
const wikiPrefix = /^[^/]+\/wiki\//;
|
|
232
|
+
return slug.replace(wikiPrefix, '');
|
|
233
|
+
}),
|
|
227
234
|
title: z.string().describe('Page title'),
|
|
228
235
|
content: z
|
|
229
236
|
.string()
|
|
@@ -253,7 +260,7 @@ const ListJournalEntriesSchema = z.object({
|
|
|
253
260
|
});
|
|
254
261
|
const GetJournalEntrySchema = z.object({
|
|
255
262
|
entry_id: z.string().describe('The entry UUID or refId'),
|
|
256
|
-
|
|
263
|
+
project_id: z.number().optional().describe('Project ID (required when looking up by refId)'),
|
|
257
264
|
});
|
|
258
265
|
const CreateJournalEntrySchema = z.object({
|
|
259
266
|
title: z.string().describe('Entry title'),
|
|
@@ -295,10 +302,10 @@ const UploadImageSchema = z.object({
|
|
|
295
302
|
.string()
|
|
296
303
|
.describe('Absolute path to an image file on disk (e.g., "/tmp/screenshot.png"). ' +
|
|
297
304
|
'Supported formats: JPEG, PNG, GIF, WebP. Max 5MB.'),
|
|
298
|
-
|
|
305
|
+
project_id: z
|
|
299
306
|
.number()
|
|
300
307
|
.optional()
|
|
301
|
-
.describe('
|
|
308
|
+
.describe('Project ID (required for multi-project users, use list_projects to get IDs)'),
|
|
302
309
|
});
|
|
303
310
|
const DownloadImageSchema = z.object({
|
|
304
311
|
image_url: z
|
|
@@ -336,18 +343,17 @@ class WolfpackMCPServer {
|
|
|
336
343
|
setupHandlers() {
|
|
337
344
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
338
345
|
tools: [
|
|
339
|
-
//
|
|
346
|
+
// Project tools
|
|
340
347
|
{
|
|
341
|
-
name: '
|
|
342
|
-
description: 'List all
|
|
343
|
-
'TERMINOLOGY: In this software, "team" and "project" are synonymous and interchangeable. All tool names and parameters use "team" (e.g., team_id), but the concepts are identical. ' +
|
|
348
|
+
name: 'list_projects',
|
|
349
|
+
description: 'List all projects you have access to. Projects can be "personal" (single user) or "team" (multi-member). ' +
|
|
344
350
|
'IMPORTANT - PROJECT FOCUS RULES: ' +
|
|
345
|
-
'1) Call this FIRST to identify which
|
|
346
|
-
'2) Once you identify a
|
|
347
|
-
'3) NEVER perform bulk actions across multiple
|
|
348
|
-
'4) If the user mentions a specific
|
|
349
|
-
'5) If unclear which
|
|
350
|
-
'Returns
|
|
351
|
+
'1) Call this FIRST to identify which project you are working in. ' +
|
|
352
|
+
'2) Once you identify a project, STAY WITHIN that project for all operations unless the user explicitly asks to switch. ' +
|
|
353
|
+
'3) NEVER perform bulk actions across multiple projects - always work in one project at a time. ' +
|
|
354
|
+
'4) If the user mentions a specific project, use that for all subsequent operations. ' +
|
|
355
|
+
'5) If unclear which project to use, ASK the user before proceeding. ' +
|
|
356
|
+
'Returns project IDs, slugs, names, and types. Single-project users have their project auto-selected; multi-project users must specify project_id in other tool calls.',
|
|
351
357
|
inputSchema: {
|
|
352
358
|
type: 'object',
|
|
353
359
|
properties: {},
|
|
@@ -368,9 +374,9 @@ class WolfpackMCPServer {
|
|
|
368
374
|
inputSchema: {
|
|
369
375
|
type: 'object',
|
|
370
376
|
properties: {
|
|
371
|
-
|
|
377
|
+
project_id: {
|
|
372
378
|
type: 'number',
|
|
373
|
-
description: '
|
|
379
|
+
description: 'Project ID (required for multi-project users, use list_projects to get IDs)',
|
|
374
380
|
},
|
|
375
381
|
status: {
|
|
376
382
|
type: 'string',
|
|
@@ -434,9 +440,9 @@ class WolfpackMCPServer {
|
|
|
434
440
|
type: 'string',
|
|
435
441
|
description: 'The ID (UUID) or refId (number) of the work item',
|
|
436
442
|
},
|
|
437
|
-
|
|
443
|
+
project_id: {
|
|
438
444
|
type: 'number',
|
|
439
|
-
description: '
|
|
445
|
+
description: 'Project ID (required when looking up by refId)',
|
|
440
446
|
},
|
|
441
447
|
},
|
|
442
448
|
required: ['work_item_id'],
|
|
@@ -488,7 +494,8 @@ class WolfpackMCPServer {
|
|
|
488
494
|
{
|
|
489
495
|
name: 'update_work_item_assignee',
|
|
490
496
|
description: 'Change the assignee (leading user) on a work item. ' +
|
|
491
|
-
'Use this to assign work to yourself or another
|
|
497
|
+
'Use this to assign work to yourself or another project member, or to unassign by passing null. ' +
|
|
498
|
+
'Not applicable for personal projects (single user).',
|
|
492
499
|
inputSchema: {
|
|
493
500
|
type: 'object',
|
|
494
501
|
properties: {
|
|
@@ -510,7 +517,8 @@ class WolfpackMCPServer {
|
|
|
510
517
|
'REQUIRED: Use this when starting work on a "pending" (backlog) item. ' +
|
|
511
518
|
'This claims the item (assigns to you) and sets status to "new". ' +
|
|
512
519
|
'After pulling, move to "doing" to indicate active work, then "review" when done. ' +
|
|
513
|
-
'If no assignee is specified, assigns to the API key owner.'
|
|
520
|
+
'If no assignee is specified, assigns to the API key owner. ' +
|
|
521
|
+
'In personal projects, items are always assigned to the owner.',
|
|
514
522
|
inputSchema: {
|
|
515
523
|
type: 'object',
|
|
516
524
|
properties: {
|
|
@@ -533,7 +541,10 @@ class WolfpackMCPServer {
|
|
|
533
541
|
inputSchema: {
|
|
534
542
|
type: 'object',
|
|
535
543
|
properties: {
|
|
536
|
-
|
|
544
|
+
project_id: {
|
|
545
|
+
type: 'number',
|
|
546
|
+
description: 'Project ID (use list_projects to get IDs)',
|
|
547
|
+
},
|
|
537
548
|
stage: {
|
|
538
549
|
type: 'string',
|
|
539
550
|
enum: ['pending', 'now', 'next', 'later', 'completed'],
|
|
@@ -559,9 +570,9 @@ class WolfpackMCPServer {
|
|
|
559
570
|
type: 'string',
|
|
560
571
|
description: 'The ID (UUID) or refId (number) of the radar item',
|
|
561
572
|
},
|
|
562
|
-
|
|
573
|
+
project_id: {
|
|
563
574
|
type: 'number',
|
|
564
|
-
description: '
|
|
575
|
+
description: 'Project ID (required when looking up by refId)',
|
|
565
576
|
},
|
|
566
577
|
},
|
|
567
578
|
required: ['item_id'],
|
|
@@ -578,9 +589,9 @@ class WolfpackMCPServer {
|
|
|
578
589
|
inputSchema: {
|
|
579
590
|
type: 'object',
|
|
580
591
|
properties: {
|
|
581
|
-
|
|
592
|
+
project_id: {
|
|
582
593
|
type: 'number',
|
|
583
|
-
description: '
|
|
594
|
+
description: 'Project ID (required for multi-project users, use list_projects to get IDs)',
|
|
584
595
|
},
|
|
585
596
|
status: {
|
|
586
597
|
type: 'string',
|
|
@@ -637,9 +648,9 @@ class WolfpackMCPServer {
|
|
|
637
648
|
type: 'string',
|
|
638
649
|
description: 'The ID (UUID) or refId (number) of the issue',
|
|
639
650
|
},
|
|
640
|
-
|
|
651
|
+
project_id: {
|
|
641
652
|
type: 'number',
|
|
642
|
-
description: '
|
|
653
|
+
description: 'Project ID (required when looking up by refId)',
|
|
643
654
|
},
|
|
644
655
|
},
|
|
645
656
|
required: ['issue_id'],
|
|
@@ -648,7 +659,7 @@ class WolfpackMCPServer {
|
|
|
648
659
|
// Create/Update tools
|
|
649
660
|
{
|
|
650
661
|
name: 'create_work_item',
|
|
651
|
-
description: 'Create a new work item in your current
|
|
662
|
+
description: 'Create a new work item in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:work_items:create permission.',
|
|
652
663
|
inputSchema: {
|
|
653
664
|
type: 'object',
|
|
654
665
|
properties: {
|
|
@@ -683,7 +694,7 @@ class WolfpackMCPServer {
|
|
|
683
694
|
},
|
|
684
695
|
{
|
|
685
696
|
name: 'create_issue',
|
|
686
|
-
description: 'Create a new issue in your current
|
|
697
|
+
description: 'Create a new issue in your current project (auto-selected for single-project users, or use list_projects first for multi-project). Requires mcp:issues:create permission.',
|
|
687
698
|
inputSchema: {
|
|
688
699
|
type: 'object',
|
|
689
700
|
properties: {
|
|
@@ -783,7 +794,10 @@ class WolfpackMCPServer {
|
|
|
783
794
|
inputSchema: {
|
|
784
795
|
type: 'object',
|
|
785
796
|
properties: {
|
|
786
|
-
slug: {
|
|
797
|
+
slug: {
|
|
798
|
+
type: 'string',
|
|
799
|
+
description: 'URL slug for the page (without team prefix). The system automatically prepends the team and wiki path. For example, to create a page at "myteam/wiki/guides/onboarding", pass just "guides/onboarding". Do NOT include the team slug or "wiki/" prefix.',
|
|
800
|
+
},
|
|
787
801
|
title: { type: 'string', description: 'Page title' },
|
|
788
802
|
content: {
|
|
789
803
|
type: 'string',
|
|
@@ -841,9 +855,9 @@ class WolfpackMCPServer {
|
|
|
841
855
|
type: 'object',
|
|
842
856
|
properties: {
|
|
843
857
|
entry_id: { type: 'string', description: 'The entry UUID or refId' },
|
|
844
|
-
|
|
858
|
+
project_id: {
|
|
845
859
|
type: 'number',
|
|
846
|
-
description: '
|
|
860
|
+
description: 'Project ID (required when looking up by refId)',
|
|
847
861
|
},
|
|
848
862
|
},
|
|
849
863
|
required: ['entry_id'],
|
|
@@ -912,7 +926,8 @@ class WolfpackMCPServer {
|
|
|
912
926
|
'USE COMMENTS FOR: 1) Blocking reasons when moving to "blocked" (what failed, what was tried, what is needed). ' +
|
|
913
927
|
'2) Completion summaries when moving to "review" (what was done, files changed, testing notes). ' +
|
|
914
928
|
'3) Important observations or decisions that should be visible in the activity history. ' +
|
|
915
|
-
'USE DESCRIPTION (update_work_progress) FOR: Plans, checklists, and progress tracking that need to be updated over time.'
|
|
929
|
+
'USE DESCRIPTION (update_work_progress) FOR: Plans, checklists, and progress tracking that need to be updated over time. ' +
|
|
930
|
+
'Comments are typically not used in personal projects.',
|
|
916
931
|
inputSchema: {
|
|
917
932
|
type: 'object',
|
|
918
933
|
properties: {
|
|
@@ -955,9 +970,9 @@ class WolfpackMCPServer {
|
|
|
955
970
|
description: 'Absolute path to an image file on disk (e.g., "/tmp/screenshot.png"). ' +
|
|
956
971
|
'Supported formats: JPEG, PNG, GIF, WebP. Max 5MB.',
|
|
957
972
|
},
|
|
958
|
-
|
|
973
|
+
project_id: {
|
|
959
974
|
type: 'number',
|
|
960
|
-
description: '
|
|
975
|
+
description: 'Project ID (required for multi-project users, use list_projects to get IDs)',
|
|
961
976
|
},
|
|
962
977
|
},
|
|
963
978
|
required: ['file_path'],
|
|
@@ -986,20 +1001,20 @@ class WolfpackMCPServer {
|
|
|
986
1001
|
const { name, arguments: args } = request.params;
|
|
987
1002
|
try {
|
|
988
1003
|
switch (name) {
|
|
989
|
-
//
|
|
990
|
-
case '
|
|
991
|
-
const teams = await this.client.
|
|
992
|
-
const currentTeamId = this.client.
|
|
1004
|
+
// Project handlers
|
|
1005
|
+
case 'list_projects': {
|
|
1006
|
+
const teams = await this.client.listProjects();
|
|
1007
|
+
const currentTeamId = this.client.getProjectId();
|
|
993
1008
|
return {
|
|
994
1009
|
content: [
|
|
995
1010
|
{
|
|
996
1011
|
type: 'text',
|
|
997
1012
|
text: JSON.stringify({
|
|
998
|
-
teams,
|
|
999
|
-
currentTeamId,
|
|
1013
|
+
projects: teams,
|
|
1014
|
+
currentProjectId: currentTeamId,
|
|
1000
1015
|
hint: teams.length === 1
|
|
1001
|
-
? 'Only one
|
|
1002
|
-
: 'Multiple
|
|
1016
|
+
? 'Only one project available - it will be used automatically.'
|
|
1017
|
+
: 'Multiple projects available. Use project_id parameter in other tools to specify which project to use.',
|
|
1003
1018
|
}, null, 2),
|
|
1004
1019
|
},
|
|
1005
1020
|
],
|
|
@@ -1009,7 +1024,7 @@ class WolfpackMCPServer {
|
|
|
1009
1024
|
case 'list_work_items': {
|
|
1010
1025
|
const parsed = ListWorkItemsSchema.parse(args);
|
|
1011
1026
|
const result = await this.client.listWorkItems({
|
|
1012
|
-
teamId: parsed.
|
|
1027
|
+
teamId: parsed.project_id || this.client.getProjectId() || undefined,
|
|
1013
1028
|
status: parsed.status,
|
|
1014
1029
|
assignedToId: parsed.assigned_to_id,
|
|
1015
1030
|
search: parsed.search,
|
|
@@ -1035,7 +1050,7 @@ class WolfpackMCPServer {
|
|
|
1035
1050
|
}
|
|
1036
1051
|
case 'get_work_item': {
|
|
1037
1052
|
const parsed = GetWorkItemSchema.parse(args);
|
|
1038
|
-
const workItem = await this.client.getWorkItem(parsed.work_item_id, parsed.
|
|
1053
|
+
const workItem = await this.client.getWorkItem(parsed.work_item_id, parsed.project_id || this.client.getProjectId() || undefined);
|
|
1039
1054
|
if (workItem) {
|
|
1040
1055
|
let text = JSON.stringify(workItem, null, 2);
|
|
1041
1056
|
// Add hint if no plan detected in description
|
|
@@ -1131,7 +1146,7 @@ class WolfpackMCPServer {
|
|
|
1131
1146
|
case 'list_radar_items': {
|
|
1132
1147
|
const parsed = ListRadarItemsSchema.parse(args);
|
|
1133
1148
|
const result = await this.client.listRadarItems({
|
|
1134
|
-
teamId: parsed.
|
|
1149
|
+
teamId: parsed.project_id,
|
|
1135
1150
|
stage: parsed.stage,
|
|
1136
1151
|
search: parsed.search,
|
|
1137
1152
|
limit: parsed.limit,
|
|
@@ -1147,7 +1162,7 @@ class WolfpackMCPServer {
|
|
|
1147
1162
|
}
|
|
1148
1163
|
case 'get_radar_item': {
|
|
1149
1164
|
const parsed = GetRadarItemSchema.parse(args);
|
|
1150
|
-
const radarItem = await this.client.getRadarItem(parsed.item_id, parsed.
|
|
1165
|
+
const radarItem = await this.client.getRadarItem(parsed.item_id, parsed.project_id);
|
|
1151
1166
|
if (radarItem) {
|
|
1152
1167
|
return {
|
|
1153
1168
|
content: [{ type: 'text', text: JSON.stringify(radarItem, null, 2) }],
|
|
@@ -1161,7 +1176,7 @@ class WolfpackMCPServer {
|
|
|
1161
1176
|
case 'list_issues': {
|
|
1162
1177
|
const parsed = ListIssuesSchema.parse(args);
|
|
1163
1178
|
const result = await this.client.listIssues({
|
|
1164
|
-
teamId: parsed.
|
|
1179
|
+
teamId: parsed.project_id,
|
|
1165
1180
|
status: parsed.status,
|
|
1166
1181
|
severity: parsed.severity,
|
|
1167
1182
|
type: parsed.type,
|
|
@@ -1184,7 +1199,7 @@ class WolfpackMCPServer {
|
|
|
1184
1199
|
}
|
|
1185
1200
|
case 'get_issue': {
|
|
1186
1201
|
const parsed = GetIssueSchema.parse(args);
|
|
1187
|
-
const issue = await this.client.getIssue(parsed.issue_id, parsed.
|
|
1202
|
+
const issue = await this.client.getIssue(parsed.issue_id, parsed.project_id);
|
|
1188
1203
|
if (issue) {
|
|
1189
1204
|
return {
|
|
1190
1205
|
content: [{ type: 'text', text: JSON.stringify(issue, null, 2) }],
|
|
@@ -1339,7 +1354,7 @@ class WolfpackMCPServer {
|
|
|
1339
1354
|
}
|
|
1340
1355
|
case 'get_journal_entry': {
|
|
1341
1356
|
const parsed = GetJournalEntrySchema.parse(args);
|
|
1342
|
-
const entry = await this.client.getJournalEntry(parsed.entry_id, parsed.
|
|
1357
|
+
const entry = await this.client.getJournalEntry(parsed.entry_id, parsed.project_id);
|
|
1343
1358
|
if (entry) {
|
|
1344
1359
|
return {
|
|
1345
1360
|
content: [{ type: 'text', text: JSON.stringify(entry, null, 2) }],
|
|
@@ -1425,7 +1440,7 @@ class WolfpackMCPServer {
|
|
|
1425
1440
|
}
|
|
1426
1441
|
case 'upload_image': {
|
|
1427
1442
|
const parsed = UploadImageSchema.parse(args);
|
|
1428
|
-
const teamSlug = await this.client.resolveSlug(parsed.
|
|
1443
|
+
const teamSlug = await this.client.resolveSlug(parsed.project_id || this.client.getProjectId() || undefined);
|
|
1429
1444
|
const filePath = resolve(parsed.file_path);
|
|
1430
1445
|
// Validate file extension
|
|
1431
1446
|
const ext = extname(filePath).toLowerCase();
|
|
@@ -1521,37 +1536,37 @@ class WolfpackMCPServer {
|
|
|
1521
1536
|
async start() {
|
|
1522
1537
|
// Start version check early (non-blocking)
|
|
1523
1538
|
const updateCheckPromise = checkForUpdates();
|
|
1524
|
-
// Resolve
|
|
1525
|
-
if (config.
|
|
1526
|
-
// Explicit
|
|
1539
|
+
// Resolve project on startup
|
|
1540
|
+
if (config.projectSlug) {
|
|
1541
|
+
// Explicit project slug configured - use it
|
|
1527
1542
|
try {
|
|
1528
|
-
const teamId = await this.client.
|
|
1529
|
-
console.error(`Resolved
|
|
1543
|
+
const teamId = await this.client.resolveProjectSlug(config.projectSlug);
|
|
1544
|
+
console.error(`Resolved project "${config.projectSlug}" to ID: ${teamId}`);
|
|
1530
1545
|
}
|
|
1531
1546
|
catch (error) {
|
|
1532
|
-
console.error(`Failed to resolve
|
|
1547
|
+
console.error(`Failed to resolve project slug: ${error instanceof Error ? error.message : String(error)}`);
|
|
1533
1548
|
process.exit(1);
|
|
1534
1549
|
}
|
|
1535
1550
|
}
|
|
1536
1551
|
else {
|
|
1537
|
-
// No
|
|
1552
|
+
// No project slug configured - try to auto-detect
|
|
1538
1553
|
try {
|
|
1539
|
-
const teams = await this.client.
|
|
1554
|
+
const teams = await this.client.listProjects();
|
|
1540
1555
|
if (teams.length === 1) {
|
|
1541
|
-
// Auto-select the only
|
|
1542
|
-
this.client.
|
|
1543
|
-
console.error(`Auto-selected
|
|
1556
|
+
// Auto-select the only project
|
|
1557
|
+
this.client.setProjectId(teams[0].id);
|
|
1558
|
+
console.error(`Auto-selected project: ${teams[0].name} (${teams[0].slug})`);
|
|
1544
1559
|
}
|
|
1545
1560
|
else if (teams.length === 0) {
|
|
1546
|
-
console.error('Warning: No
|
|
1561
|
+
console.error('Warning: No projects found for this API key');
|
|
1547
1562
|
}
|
|
1548
1563
|
else {
|
|
1549
|
-
console.error(`Multiple
|
|
1564
|
+
console.error(`Multiple projects available (${teams.length}). Use list_projects tool to see them, then specify project_id in tool calls.`);
|
|
1550
1565
|
}
|
|
1551
1566
|
}
|
|
1552
1567
|
catch (error) {
|
|
1553
|
-
console.error(`Warning: Could not fetch
|
|
1554
|
-
// Don't exit - let the user use
|
|
1568
|
+
console.error(`Warning: Could not fetch projects: ${error instanceof Error ? error.message : String(error)}`);
|
|
1569
|
+
// Don't exit - let the user use list_projects tool manually
|
|
1555
1570
|
}
|
|
1556
1571
|
}
|
|
1557
1572
|
const transport = new StdioServerTransport();
|