wolfpack-mcp 1.0.52 → 1.0.53
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/README.md +19 -0
- package/dist/agentBuilderTools.js +178 -70
- package/dist/agentSelfTools.js +124 -0
- package/dist/client.js +175 -66
- package/dist/config.js +4 -0
- package/dist/index.js +37 -7
- package/dist/procedureTools.js +208 -0
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
function text(data) {
|
|
3
|
+
return JSON.stringify(data, null, 2);
|
|
4
|
+
}
|
|
5
|
+
// ─── Tool definitions ──────────────────────────────────────────────────────────
|
|
6
|
+
export const AGENT_SELF_TOOLS = [
|
|
7
|
+
{
|
|
8
|
+
name: 'get_self',
|
|
9
|
+
description: 'Get your own agent profile with full composed context: template system prompt, agent instructions, skills, LLM model, and assigned projects. ' +
|
|
10
|
+
'Use this to understand how you are configured and what capabilities you have. ' +
|
|
11
|
+
'Essential for self-reflection and improvement proposals.',
|
|
12
|
+
inputSchema: { type: 'object', properties: {} },
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'get_own_sessions',
|
|
16
|
+
description: 'List your own recent sessions. Returns session metadata including status, trigger type, and timestamps. ' +
|
|
17
|
+
'Use this to review your recent activity for retrospective analysis.',
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
limit: { type: 'number', description: 'Max sessions to return (default 10)' },
|
|
22
|
+
offset: { type: 'number', description: 'Skip first N sessions (default 0)' },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'list_memories',
|
|
28
|
+
description: 'List all your persistent memory entries. Memory persists across sessions and is scoped to you. ' +
|
|
29
|
+
'Use this to recall observations, patterns, and notes from previous work.',
|
|
30
|
+
inputSchema: { type: 'object', properties: {} },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'get_memory',
|
|
34
|
+
description: 'Get a specific memory entry by key. Returns the content and metadata for a single memory entry.',
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
key: { type: 'string', description: 'The memory key to retrieve' },
|
|
39
|
+
},
|
|
40
|
+
required: ['key'],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'save_memory',
|
|
45
|
+
description: 'Save a persistent memory entry by key. Creates the entry if it does not exist, or updates it if it does. ' +
|
|
46
|
+
'Use this to persist observations, learnings, and notes across sessions. ' +
|
|
47
|
+
'To clear a memory entry, save it with empty content.',
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
key: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
description: 'A unique key for this memory entry (e.g. "retrospective-notes", "recurring-issues", "session-learnings")',
|
|
54
|
+
},
|
|
55
|
+
content: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'The content to persist. Use markdown for structured notes.',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
required: ['key', 'content'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
// ─── Zod schemas ───────────────────────────────────────────────────────────────
|
|
65
|
+
const GetOwnSessionsSchema = z.object({
|
|
66
|
+
limit: z.number().optional(),
|
|
67
|
+
offset: z.number().optional(),
|
|
68
|
+
});
|
|
69
|
+
const GetMemorySchema = z.object({
|
|
70
|
+
key: z.string(),
|
|
71
|
+
});
|
|
72
|
+
const SaveMemorySchema = z.object({
|
|
73
|
+
key: z.string(),
|
|
74
|
+
content: z.string(),
|
|
75
|
+
});
|
|
76
|
+
// ─── Handler ───────────────────────────────────────────────────────────────────
|
|
77
|
+
export async function handleAgentSelfTool(name, args, client) {
|
|
78
|
+
switch (name) {
|
|
79
|
+
case 'get_self': {
|
|
80
|
+
const self = await client.getSelf();
|
|
81
|
+
return { content: [{ type: 'text', text: text(self) }] };
|
|
82
|
+
}
|
|
83
|
+
case 'get_own_sessions': {
|
|
84
|
+
const parsed = GetOwnSessionsSchema.parse(args || {});
|
|
85
|
+
const sessions = await client.getOwnSessions(parsed);
|
|
86
|
+
return { content: [{ type: 'text', text: text(sessions) }] };
|
|
87
|
+
}
|
|
88
|
+
case 'list_memories': {
|
|
89
|
+
const memories = await client.listMemories();
|
|
90
|
+
if (memories.length === 0) {
|
|
91
|
+
return {
|
|
92
|
+
content: [
|
|
93
|
+
{ type: 'text', text: 'No memory entries found. Use save_memory to create one.' },
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { content: [{ type: 'text', text: text(memories) }] };
|
|
98
|
+
}
|
|
99
|
+
case 'get_memory': {
|
|
100
|
+
const parsed = GetMemorySchema.parse(args);
|
|
101
|
+
const memory = await client.getMemory(parsed.key);
|
|
102
|
+
if (!memory) {
|
|
103
|
+
return {
|
|
104
|
+
content: [{ type: 'text', text: `Memory entry "${parsed.key}" not found.` }],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return { content: [{ type: 'text', text: text(memory) }] };
|
|
108
|
+
}
|
|
109
|
+
case 'save_memory': {
|
|
110
|
+
const parsed = SaveMemorySchema.parse(args);
|
|
111
|
+
const memory = await client.saveMemory(parsed.key, parsed.content);
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: 'text',
|
|
116
|
+
text: `Saved memory "${parsed.key}" (updated: ${memory.dateUpdated})`,
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
default:
|
|
122
|
+
throw new Error(`Unknown agent self tool: ${name}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
package/dist/client.js
CHANGED
|
@@ -17,6 +17,13 @@ export class WolfpackClient {
|
|
|
17
17
|
const sep = path.includes('?') ? '&' : '?';
|
|
18
18
|
return `${path}${sep}teamSlug=${encodeURIComponent(slug)}`;
|
|
19
19
|
}
|
|
20
|
+
/** Build a URL path with optional org_slug query parameter. */
|
|
21
|
+
withOrgSlug(path, orgSlug) {
|
|
22
|
+
if (!orgSlug)
|
|
23
|
+
return path;
|
|
24
|
+
const sep = path.includes('?') ? '&' : '?';
|
|
25
|
+
return `${path}${sep}org_slug=${encodeURIComponent(orgSlug)}`;
|
|
26
|
+
}
|
|
20
27
|
/**
|
|
21
28
|
* Fetch and cache the project slug by verifying it exists.
|
|
22
29
|
* Uses the MCP team endpoint to validate the slug.
|
|
@@ -572,13 +579,18 @@ export class WolfpackClient {
|
|
|
572
579
|
async getCapabilities() {
|
|
573
580
|
return this.api.get('/capabilities');
|
|
574
581
|
}
|
|
582
|
+
// ─── Organisations ──────────────────────────────────────────────────────────
|
|
583
|
+
async listOrganisations() {
|
|
584
|
+
const response = await this.api.get('/organisations');
|
|
585
|
+
return response.organisations;
|
|
586
|
+
}
|
|
575
587
|
// ─── Agent Builder: Agent CRUD ─────────────────────────────────────────────
|
|
576
|
-
async listAgents() {
|
|
577
|
-
return this.api.get('/agents');
|
|
588
|
+
async listAgents(orgSlug) {
|
|
589
|
+
return this.api.get(this.withOrgSlug('/agents', orgSlug));
|
|
578
590
|
}
|
|
579
|
-
async getAgent(agentId) {
|
|
591
|
+
async getAgent(agentId, orgSlug) {
|
|
580
592
|
try {
|
|
581
|
-
return await this.api.get(`/agents/${agentId}
|
|
593
|
+
return await this.api.get(this.withOrgSlug(`/agents/${agentId}`, orgSlug));
|
|
582
594
|
}
|
|
583
595
|
catch (error) {
|
|
584
596
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404)
|
|
@@ -586,26 +598,26 @@ export class WolfpackClient {
|
|
|
586
598
|
throw error;
|
|
587
599
|
}
|
|
588
600
|
}
|
|
589
|
-
async createAgent(body) {
|
|
590
|
-
return this.api.post('/agents', body);
|
|
601
|
+
async createAgent(body, orgSlug) {
|
|
602
|
+
return this.api.post(this.withOrgSlug('/agents', orgSlug), body);
|
|
591
603
|
}
|
|
592
|
-
async updateAgent(agentId, body) {
|
|
593
|
-
return this.api.patch(`/agents/${agentId}`, body);
|
|
604
|
+
async updateAgent(agentId, body, orgSlug) {
|
|
605
|
+
return this.api.patch(this.withOrgSlug(`/agents/${agentId}`, orgSlug), body);
|
|
594
606
|
}
|
|
595
607
|
// ─── Agent Builder: Project Assignment ────────────────────────────────────
|
|
596
|
-
async listAgentProjects(agentId) {
|
|
597
|
-
return this.api.get(`/agents/${agentId}/projects
|
|
608
|
+
async listAgentProjects(agentId, orgSlug) {
|
|
609
|
+
return this.api.get(this.withOrgSlug(`/agents/${agentId}/projects`, orgSlug));
|
|
598
610
|
}
|
|
599
|
-
async assignAgentToProject(agentId, teamSlug) {
|
|
600
|
-
return this.api.post(`/agents/${agentId}/projects/${encodeURIComponent(teamSlug)}`, {});
|
|
611
|
+
async assignAgentToProject(agentId, teamSlug, orgSlug) {
|
|
612
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/projects/${encodeURIComponent(teamSlug)}`, orgSlug), {});
|
|
601
613
|
}
|
|
602
|
-
async removeAgentFromProject(agentId, teamSlug) {
|
|
614
|
+
async removeAgentFromProject(agentId, teamSlug, orgSlug) {
|
|
603
615
|
return this.api
|
|
604
|
-
.delete(`/agents/${agentId}/projects/${encodeURIComponent(teamSlug)}
|
|
616
|
+
.delete(this.withOrgSlug(`/agents/${agentId}/projects/${encodeURIComponent(teamSlug)}`, orgSlug))
|
|
605
617
|
.then(() => ({ success: true }));
|
|
606
618
|
}
|
|
607
619
|
// ─── Agent Builder: Sessions ───────────────────────────────────────────────
|
|
608
|
-
async listAgentSessions(agentId, options) {
|
|
620
|
+
async listAgentSessions(agentId, options, orgSlug) {
|
|
609
621
|
const params = new URLSearchParams();
|
|
610
622
|
if (options?.status)
|
|
611
623
|
params.append('status', options.status);
|
|
@@ -613,12 +625,14 @@ export class WolfpackClient {
|
|
|
613
625
|
params.append('limit', options.limit.toString());
|
|
614
626
|
if (options?.offset !== undefined)
|
|
615
627
|
params.append('offset', options.offset.toString());
|
|
628
|
+
if (orgSlug)
|
|
629
|
+
params.append('org_slug', orgSlug);
|
|
616
630
|
const q = params.toString();
|
|
617
631
|
return this.api.get(`/agents/${agentId}/sessions${q ? `?${q}` : ''}`);
|
|
618
632
|
}
|
|
619
|
-
async getAgentSession(agentId, sessionId) {
|
|
633
|
+
async getAgentSession(agentId, sessionId, orgSlug) {
|
|
620
634
|
try {
|
|
621
|
-
return await this.api.get(`/agents/${agentId}/sessions/${sessionId}
|
|
635
|
+
return await this.api.get(this.withOrgSlug(`/agents/${agentId}/sessions/${sessionId}`, orgSlug));
|
|
622
636
|
}
|
|
623
637
|
catch (error) {
|
|
624
638
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404)
|
|
@@ -626,33 +640,36 @@ export class WolfpackClient {
|
|
|
626
640
|
throw error;
|
|
627
641
|
}
|
|
628
642
|
}
|
|
629
|
-
async getAgentSessionConversation(agentId, sessionId, options) {
|
|
643
|
+
async getAgentSessionConversation(agentId, sessionId, options, orgSlug) {
|
|
630
644
|
const params = new URLSearchParams();
|
|
631
645
|
if (options?.limit !== undefined)
|
|
632
646
|
params.append('limit', options.limit.toString());
|
|
633
647
|
if (options?.offset !== undefined)
|
|
634
648
|
params.append('offset', options.offset.toString());
|
|
649
|
+
if (orgSlug)
|
|
650
|
+
params.append('org_slug', orgSlug);
|
|
635
651
|
const q = params.toString();
|
|
636
652
|
return this.api.get(`/agents/${agentId}/sessions/${sessionId}/conversation${q ? `?${q}` : ''}`);
|
|
637
653
|
}
|
|
638
|
-
async runAgent(agentId, prompt, teamSlug) {
|
|
639
|
-
return this.api.post(`/agents/${agentId}/run`,
|
|
640
|
-
}
|
|
641
|
-
async stopAgentSession(agentId, sessionId) {
|
|
642
|
-
return this.api.post(`/agents/${agentId}/sessions/${sessionId}/stop`, {});
|
|
643
|
-
}
|
|
644
|
-
async resumeAgentSession(agentId, sessionId, prompt) {
|
|
645
|
-
return this.api.post(`/agents/${agentId}/sessions/${sessionId}/resume`, {
|
|
654
|
+
async runAgent(agentId, prompt, teamSlug, orgSlug) {
|
|
655
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/run`, orgSlug), {
|
|
646
656
|
prompt,
|
|
657
|
+
teamSlug,
|
|
647
658
|
});
|
|
648
659
|
}
|
|
660
|
+
async stopAgentSession(agentId, sessionId, orgSlug) {
|
|
661
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/sessions/${sessionId}/stop`, orgSlug), {});
|
|
662
|
+
}
|
|
663
|
+
async resumeAgentSession(agentId, sessionId, prompt, orgSlug) {
|
|
664
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/sessions/${sessionId}/resume`, orgSlug), { prompt });
|
|
665
|
+
}
|
|
649
666
|
// ─── Agent Builder: Tasks ──────────────────────────────────────────────────
|
|
650
|
-
async listAgentTasks(agentId) {
|
|
651
|
-
return this.api.get(`/agents/${agentId}/tasks
|
|
667
|
+
async listAgentTasks(agentId, orgSlug) {
|
|
668
|
+
return this.api.get(this.withOrgSlug(`/agents/${agentId}/tasks`, orgSlug));
|
|
652
669
|
}
|
|
653
|
-
async getAgentTask(agentId, taskId) {
|
|
670
|
+
async getAgentTask(agentId, taskId, orgSlug) {
|
|
654
671
|
try {
|
|
655
|
-
return await this.api.get(`/agents/${agentId}/tasks/${taskId}
|
|
672
|
+
return await this.api.get(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}`, orgSlug));
|
|
656
673
|
}
|
|
657
674
|
catch (error) {
|
|
658
675
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404)
|
|
@@ -660,59 +677,69 @@ export class WolfpackClient {
|
|
|
660
677
|
throw error;
|
|
661
678
|
}
|
|
662
679
|
}
|
|
663
|
-
async createAgentTask(agentId, body) {
|
|
664
|
-
return this.api.post(`/agents/${agentId}/tasks`, body);
|
|
680
|
+
async createAgentTask(agentId, body, orgSlug) {
|
|
681
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/tasks`, orgSlug), body);
|
|
665
682
|
}
|
|
666
|
-
async updateAgentTask(agentId, taskId, body) {
|
|
667
|
-
return this.api.patch(`/agents/${agentId}/tasks/${taskId}`, body);
|
|
683
|
+
async updateAgentTask(agentId, taskId, body, orgSlug) {
|
|
684
|
+
return this.api.patch(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}`, orgSlug), body);
|
|
668
685
|
}
|
|
669
|
-
async runAgentTask(agentId, taskId, teamSlug) {
|
|
670
|
-
return this.api.post(`/agents/${agentId}/tasks/${taskId}/run`, { teamSlug });
|
|
686
|
+
async runAgentTask(agentId, taskId, teamSlug, orgSlug) {
|
|
687
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}/run`, orgSlug), { teamSlug });
|
|
671
688
|
}
|
|
672
689
|
// ─── Agent Builder: Queue ──────────────────────────────────────────────────
|
|
673
|
-
async listAgentQueue(agentId, status) {
|
|
674
|
-
const
|
|
675
|
-
|
|
690
|
+
async listAgentQueue(agentId, status, orgSlug) {
|
|
691
|
+
const params = new URLSearchParams();
|
|
692
|
+
if (status)
|
|
693
|
+
params.append('status', status);
|
|
694
|
+
if (orgSlug)
|
|
695
|
+
params.append('org_slug', orgSlug);
|
|
696
|
+
const q = params.toString();
|
|
697
|
+
return this.api.get(`/agents/${agentId}/queue${q ? `?${q}` : ''}`);
|
|
676
698
|
}
|
|
677
|
-
async cancelQueueEntry(agentId, entryId) {
|
|
678
|
-
return this.api
|
|
699
|
+
async cancelQueueEntry(agentId, entryId, orgSlug) {
|
|
700
|
+
return this.api
|
|
701
|
+
.delete(this.withOrgSlug(`/agents/${agentId}/queue/${entryId}`, orgSlug))
|
|
702
|
+
.then(() => ({ success: true }));
|
|
679
703
|
}
|
|
680
704
|
// ─── Agent Builder: Secrets ────────────────────────────────────────────────
|
|
681
|
-
async listAgentSecrets(agentId) {
|
|
682
|
-
return this.api.get(`/agents/${agentId}/secrets
|
|
705
|
+
async listAgentSecrets(agentId, orgSlug) {
|
|
706
|
+
return this.api.get(this.withOrgSlug(`/agents/${agentId}/secrets`, orgSlug));
|
|
683
707
|
}
|
|
684
|
-
async setAgentSecret(agentId, name, value) {
|
|
685
|
-
return this.api.post(`/agents/${agentId}/secrets`, { name, value });
|
|
708
|
+
async setAgentSecret(agentId, name, value, orgSlug) {
|
|
709
|
+
return this.api.post(this.withOrgSlug(`/agents/${agentId}/secrets`, orgSlug), { name, value });
|
|
686
710
|
}
|
|
687
711
|
// ─── Agent Builder: Skills (write) ────────────────────────────────────────
|
|
688
|
-
async createSkill(body) {
|
|
689
|
-
return this.api.post('/skills', body);
|
|
712
|
+
async createSkill(body, orgSlug) {
|
|
713
|
+
return this.api.post(this.withOrgSlug('/skills', orgSlug), body);
|
|
690
714
|
}
|
|
691
|
-
async updateSkill(skillId, body) {
|
|
692
|
-
return this.api.patch(`/skills/${skillId}`, body);
|
|
715
|
+
async updateSkill(skillId, body, orgSlug) {
|
|
716
|
+
return this.api.patch(this.withOrgSlug(`/skills/${skillId}`, orgSlug), body);
|
|
693
717
|
}
|
|
694
|
-
async createSkillResource(skillId, body) {
|
|
695
|
-
return this.api.post(`/skills/${skillId}/resources`, body);
|
|
718
|
+
async createSkillResource(skillId, body, orgSlug) {
|
|
719
|
+
return this.api.post(this.withOrgSlug(`/skills/${skillId}/resources`, orgSlug), body);
|
|
696
720
|
}
|
|
697
|
-
async updateSkillResource(skillId, resourceId, body) {
|
|
698
|
-
return this.api.patch(`/skills/${skillId}/resources/${resourceId}`, body);
|
|
721
|
+
async updateSkillResource(skillId, resourceId, body, orgSlug) {
|
|
722
|
+
return this.api.patch(this.withOrgSlug(`/skills/${skillId}/resources/${resourceId}`, orgSlug), body);
|
|
699
723
|
}
|
|
700
|
-
async setAgentSkills(agentId, skillIds) {
|
|
701
|
-
return this.api.post(`/skills/agent-assignments/${agentId}`, {
|
|
702
|
-
skillIds,
|
|
703
|
-
});
|
|
724
|
+
async setAgentSkills(agentId, skillIds, orgSlug) {
|
|
725
|
+
return this.api.post(this.withOrgSlug(`/skills/agent-assignments/${agentId}`, orgSlug), { skillIds });
|
|
704
726
|
}
|
|
705
727
|
// ─── Agent Builder: Skills (read) ──────────────────────────────────────────
|
|
706
728
|
async listAgentSkills(agentId) {
|
|
707
729
|
return this.api.get(`/skills/agent-profiles/${agentId}`);
|
|
708
730
|
}
|
|
709
|
-
async listOrgSkills() {
|
|
710
|
-
return this.api.get('/agents/org-skills');
|
|
731
|
+
async listOrgSkills(orgSlug) {
|
|
732
|
+
return this.api.get(this.withOrgSlug('/agents/org-skills', orgSlug));
|
|
711
733
|
}
|
|
712
|
-
async getSkillDetail(name, agentId) {
|
|
734
|
+
async getSkillDetail(name, agentId, orgSlug) {
|
|
713
735
|
try {
|
|
714
|
-
const
|
|
715
|
-
|
|
736
|
+
const params = new URLSearchParams();
|
|
737
|
+
if (agentId)
|
|
738
|
+
params.append('agentProfileId', agentId);
|
|
739
|
+
if (orgSlug)
|
|
740
|
+
params.append('org_slug', orgSlug);
|
|
741
|
+
const q = params.toString();
|
|
742
|
+
return await this.api.get(`/agents/org-skills/${encodeURIComponent(name)}${q ? `?${q}` : ''}`);
|
|
716
743
|
}
|
|
717
744
|
catch (error) {
|
|
718
745
|
if (error && typeof error === 'object' && 'status' in error && error.status === 404)
|
|
@@ -721,11 +748,93 @@ export class WolfpackClient {
|
|
|
721
748
|
}
|
|
722
749
|
}
|
|
723
750
|
// ─── Agent Builder: Discovery ──────────────────────────────────────────────
|
|
724
|
-
async listAgentTemplates() {
|
|
725
|
-
return this.api.get('/agent-builder/templates');
|
|
751
|
+
async listAgentTemplates(orgSlug) {
|
|
752
|
+
return this.api.get(this.withOrgSlug('/agent-builder/templates', orgSlug));
|
|
753
|
+
}
|
|
754
|
+
async listLlmModels(orgSlug) {
|
|
755
|
+
return this.api.get(this.withOrgSlug('/agent-builder/llm-models', orgSlug));
|
|
756
|
+
}
|
|
757
|
+
// ─── Procedures ──────────────────────────────────────────────────────────
|
|
758
|
+
async listProcedures(options) {
|
|
759
|
+
const params = new URLSearchParams();
|
|
760
|
+
if (options?.teamSlug)
|
|
761
|
+
params.append('teamSlug', options.teamSlug);
|
|
762
|
+
if (options?.search)
|
|
763
|
+
params.append('search', options.search);
|
|
764
|
+
if (options?.activeOnly)
|
|
765
|
+
params.append('activeOnly', 'true');
|
|
766
|
+
if (options?.limit !== undefined || options?.offset !== undefined) {
|
|
767
|
+
if (options?.limit)
|
|
768
|
+
params.append('limit', options.limit.toString());
|
|
769
|
+
if (options?.offset)
|
|
770
|
+
params.append('offset', options.offset.toString());
|
|
771
|
+
const query = params.toString();
|
|
772
|
+
const response = await this.api.get(`/procedures${query ? `?${query}` : ''}`);
|
|
773
|
+
if (!response || !Array.isArray(response.items)) {
|
|
774
|
+
throw new Error(`Invalid API response from /procedures: expected { items: [], total: number } but got ${JSON.stringify(response)}`);
|
|
775
|
+
}
|
|
776
|
+
return {
|
|
777
|
+
items: response.items,
|
|
778
|
+
total: response.total,
|
|
779
|
+
truncated: response.total > response.items.length,
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
return this.fetchAllPages('/procedures', params);
|
|
783
|
+
}
|
|
784
|
+
async getProcedure(procedureId, teamSlug) {
|
|
785
|
+
try {
|
|
786
|
+
const params = new URLSearchParams();
|
|
787
|
+
if (teamSlug)
|
|
788
|
+
params.append('teamSlug', teamSlug);
|
|
789
|
+
const query = params.toString();
|
|
790
|
+
return await this.api.get(`/procedures/${procedureId}${query ? `?${query}` : ''}`);
|
|
791
|
+
}
|
|
792
|
+
catch (error) {
|
|
793
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404) {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
throw error;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
async createProcedure(data) {
|
|
800
|
+
const { teamSlug, ...rest } = data;
|
|
801
|
+
return this.api.post('/procedures', { ...rest, teamSlug });
|
|
802
|
+
}
|
|
803
|
+
async updateProcedure(procedureId, data, teamSlug) {
|
|
804
|
+
return this.api.patch(this.withTeamSlug(`/procedures/${procedureId}`, teamSlug), data);
|
|
805
|
+
}
|
|
806
|
+
async deleteProcedure(procedureId, teamSlug) {
|
|
807
|
+
await this.api.delete(this.withTeamSlug(`/procedures/${procedureId}`, teamSlug));
|
|
808
|
+
return { success: true };
|
|
809
|
+
}
|
|
810
|
+
// ─── Agent Self-Introspection ──────────────────────────────────────────────
|
|
811
|
+
async getSelf() {
|
|
812
|
+
return this.api.get('/self');
|
|
813
|
+
}
|
|
814
|
+
async getOwnSessions(options) {
|
|
815
|
+
const params = new URLSearchParams();
|
|
816
|
+
if (options?.limit !== undefined)
|
|
817
|
+
params.append('limit', options.limit.toString());
|
|
818
|
+
if (options?.offset !== undefined)
|
|
819
|
+
params.append('offset', options.offset.toString());
|
|
820
|
+
const q = params.toString();
|
|
821
|
+
return this.api.get(`/self/sessions${q ? `?${q}` : ''}`);
|
|
822
|
+
}
|
|
823
|
+
async listMemories() {
|
|
824
|
+
return this.api.get('/self/memories');
|
|
825
|
+
}
|
|
826
|
+
async getMemory(key) {
|
|
827
|
+
try {
|
|
828
|
+
return await this.api.get(`/self/memories/${encodeURIComponent(key)}`);
|
|
829
|
+
}
|
|
830
|
+
catch (error) {
|
|
831
|
+
if (error && typeof error === 'object' && 'status' in error && error.status === 404)
|
|
832
|
+
return null;
|
|
833
|
+
throw error;
|
|
834
|
+
}
|
|
726
835
|
}
|
|
727
|
-
async
|
|
728
|
-
return this.api.
|
|
836
|
+
async saveMemory(key, content) {
|
|
837
|
+
return this.api.put(`/self/memories/${encodeURIComponent(key)}`, { content });
|
|
729
838
|
}
|
|
730
839
|
close() {
|
|
731
840
|
// No cleanup needed for API client
|
package/dist/config.js
CHANGED
|
@@ -2,6 +2,7 @@ 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
|
+
orgSlug: process.env.WOLFPACK_ORG_SLUG,
|
|
5
6
|
};
|
|
6
7
|
// Validate configuration on startup
|
|
7
8
|
export function validateConfig() {
|
|
@@ -17,6 +18,9 @@ export function validateConfig() {
|
|
|
17
18
|
process.exit(1);
|
|
18
19
|
}
|
|
19
20
|
console.error(`MCP Server connecting to: ${config.apiUrl}`);
|
|
21
|
+
if (config.orgSlug) {
|
|
22
|
+
console.error(`Organisation configured: ${config.orgSlug}`);
|
|
23
|
+
}
|
|
20
24
|
if (config.projectSlug) {
|
|
21
25
|
console.error(`Project configured: ${config.projectSlug}`);
|
|
22
26
|
}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ import { basename, extname, resolve } from 'path';
|
|
|
9
9
|
import { WolfpackClient } from './client.js';
|
|
10
10
|
import { validateConfig, config } from './config.js';
|
|
11
11
|
import { AGENT_BUILDER_TOOLS, handleAgentBuilderTool } from './agentBuilderTools.js';
|
|
12
|
+
import { PROCEDURE_TOOLS, handleProcedureTool } from './procedureTools.js';
|
|
13
|
+
import { AGENT_SELF_TOOLS, handleAgentSelfTool } from './agentSelfTools.js';
|
|
12
14
|
// Get current package version
|
|
13
15
|
const require = createRequire(import.meta.url);
|
|
14
16
|
const packageJson = require('../package.json');
|
|
@@ -46,8 +48,9 @@ async function checkForUpdates() {
|
|
|
46
48
|
}
|
|
47
49
|
// Cross-reference syntax for linking between content items in markdown fields
|
|
48
50
|
const CONTENT_LINKING_HELP = 'CROSS-REFERENCES: In any markdown content, you can link to other items using these patterns: ' +
|
|
49
|
-
'#123 or #
|
|
50
|
-
'#
|
|
51
|
+
'#123, #w123, or #work-123 for work items (DEFAULT — bare #N always means a work item), ' +
|
|
52
|
+
'#i123 or #issue-123 for issues, #r123 or #roadmap-123 for initiatives/roadmap, ' +
|
|
53
|
+
'#j123 or #journal-123 for journal entries, #c123 or #case-123 for cases, #p123 or #proc-123 for procedures. ' +
|
|
51
54
|
'Use @username to mention team members (triggers notifications). ' +
|
|
52
55
|
'Standard markdown links also work: [link text](/project/{slug}/work-items/123).';
|
|
53
56
|
// Work Item schemas
|
|
@@ -643,7 +646,12 @@ class WolfpackMCPServer {
|
|
|
643
646
|
'3) NEVER perform bulk actions across multiple projects - always work in one project at a time. ' +
|
|
644
647
|
'4) If the user mentions a specific project, use that for all subsequent operations. ' +
|
|
645
648
|
'5) If unclear which project to use, ASK the user before proceeding. ' +
|
|
646
|
-
'Returns project slugs, names, and types. Single-project users have their project auto-selected; multi-project users must specify project_slug in other tool calls.'
|
|
649
|
+
'Returns project slugs, names, and types. Single-project users have their project auto-selected; multi-project users must specify project_slug in other tool calls. ' +
|
|
650
|
+
'ID CONVENTION: A bare number like #1 or #42 ALWAYS refers to a WORK ITEM refId — use get_work_item. ' +
|
|
651
|
+
'Other document types REQUIRE a prefix and are never bare numbers: ' +
|
|
652
|
+
'#i1 or #issue-1 for issues, #r1 or #roadmap-1 for roadmap/radar, ' +
|
|
653
|
+
'#j1 or #journal-1 for journal, #c1 or #case-1 for cases, #p1 or #proc-1 for procedures. ' +
|
|
654
|
+
'Wiki pages are referenced by path (e.g. /docs/setup). There is no ambiguity: bare #N = work item.',
|
|
647
655
|
inputSchema: {
|
|
648
656
|
type: 'object',
|
|
649
657
|
properties: {},
|
|
@@ -652,7 +660,8 @@ class WolfpackMCPServer {
|
|
|
652
660
|
// Work Item tools
|
|
653
661
|
{
|
|
654
662
|
name: 'list_work_items',
|
|
655
|
-
description: 'List work items (tasks/tickets) on the Kanban board or backlog.
|
|
663
|
+
description: 'List work items (tasks/tickets) on the Kanban board or backlog. Work items are the PRIMARY entity — bare #N references (e.g. "work on #1") always mean work items. ' +
|
|
664
|
+
'By default lists ALL items in the team, sorted by most recently updated. ' +
|
|
656
665
|
'Use assigned_to_id="me" to filter to only your assigned items. ' +
|
|
657
666
|
'TERMINOLOGY: "board" and "kanban" are synonymous - both refer to the Kanban board of work items. ' +
|
|
658
667
|
'The board has columns: "new" (to do), "doing" (in progress), "review" (pending review), "ready" (code done, awaiting deployment), "blocked", "completed" (deployed). ' +
|
|
@@ -717,7 +726,8 @@ class WolfpackMCPServer {
|
|
|
717
726
|
},
|
|
718
727
|
{
|
|
719
728
|
name: 'get_work_item',
|
|
720
|
-
description: 'Get a specific work item/task by reference number.
|
|
729
|
+
description: 'Get a specific work item/task by reference number. This is the DEFAULT lookup when a user says "#1" or "work on #42" — bare #N always means a work item. ' +
|
|
730
|
+
'Returns full details including description (markdown notes). ' +
|
|
721
731
|
'Call this before updating to see current content. ' +
|
|
722
732
|
'WORKFLOW: When asked to work on an item, check its status and follow the required state transitions ' +
|
|
723
733
|
'(pending→pull first, new→doing, blocked/ready/completed/closed→new→doing, then review when done). ' +
|
|
@@ -1001,8 +1011,9 @@ class WolfpackMCPServer {
|
|
|
1001
1011
|
name: 'list_issues',
|
|
1002
1012
|
description: 'List issues from the Issue Tracker. Issues are a SEPARATE system from work items on the Kanban board. ' +
|
|
1003
1013
|
'Issues track bugs, feature requests, and other reports that may or may not have associated work items. ' +
|
|
1014
|
+
'Issues are referenced with the #i prefix (e.g. #i5). A bare #N (without prefix) is ALWAYS a work item, NOT an issue. ' +
|
|
1004
1015
|
'IMPORTANT: If the user asks about "bugs" or "tasks" in the context of the "board", "kanban", or "backlog", use list_work_items instead - those are work items, not issues. ' +
|
|
1005
|
-
'Only use this tool when the user specifically asks about "issues", the "issue tracker", or is clearly referring to the issue tracking system. ' +
|
|
1016
|
+
'Only use this tool when the user specifically asks about "issues", the "issue tracker", uses the #i prefix, or is clearly referring to the issue tracking system. ' +
|
|
1006
1017
|
'Can filter by status, severity, and type.',
|
|
1007
1018
|
inputSchema: {
|
|
1008
1019
|
type: 'object',
|
|
@@ -1057,7 +1068,9 @@ class WolfpackMCPServer {
|
|
|
1057
1068
|
},
|
|
1058
1069
|
{
|
|
1059
1070
|
name: 'get_issue',
|
|
1060
|
-
description: 'Get a specific issue by
|
|
1071
|
+
description: 'Get a specific issue by its PREFIXED reference #iN (e.g. #i5). ' +
|
|
1072
|
+
'IMPORTANT: A bare #N (without prefix) is ALWAYS a work item, NOT an issue. Only use this tool when the user explicitly says "issue" or uses the #i prefix. ' +
|
|
1073
|
+
'Returns full details including comment and attachment counts. ' +
|
|
1061
1074
|
'IMAGES: Image references in the description (e.g. ``) can be viewed using the download_image tool.',
|
|
1062
1075
|
inputSchema: {
|
|
1063
1076
|
type: 'object',
|
|
@@ -1863,6 +1876,8 @@ class WolfpackMCPServer {
|
|
|
1863
1876
|
required: ['discussion_id', 'content'],
|
|
1864
1877
|
},
|
|
1865
1878
|
},
|
|
1879
|
+
...(this.capabilities.includes('procedures') ? PROCEDURE_TOOLS : []),
|
|
1880
|
+
...(this.capabilities.includes('agent_self') ? AGENT_SELF_TOOLS : []),
|
|
1866
1881
|
...(this.capabilities.includes('agent_builder') ? AGENT_BUILDER_TOOLS : []),
|
|
1867
1882
|
],
|
|
1868
1883
|
}));
|
|
@@ -2702,6 +2717,21 @@ class WolfpackMCPServer {
|
|
|
2702
2717
|
};
|
|
2703
2718
|
}
|
|
2704
2719
|
default: {
|
|
2720
|
+
// Check procedure tools
|
|
2721
|
+
if (this.capabilities.includes('procedures')) {
|
|
2722
|
+
const procedureToolNames = PROCEDURE_TOOLS.map((t) => t.name);
|
|
2723
|
+
if (procedureToolNames.includes(name)) {
|
|
2724
|
+
return handleProcedureTool(name, args, this.client);
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
// Check agent self tools
|
|
2728
|
+
if (this.capabilities.includes('agent_self')) {
|
|
2729
|
+
const selfToolNames = AGENT_SELF_TOOLS.map((t) => t.name);
|
|
2730
|
+
if (selfToolNames.includes(name)) {
|
|
2731
|
+
return handleAgentSelfTool(name, args, this.client);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
// Check agent builder tools
|
|
2705
2735
|
if (this.capabilities.includes('agent_builder')) {
|
|
2706
2736
|
return handleAgentBuilderTool(name, args, this.client);
|
|
2707
2737
|
}
|