wolfpack-mcp 1.0.89 → 1.0.91

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.
@@ -113,6 +113,10 @@ export const AGENT_BUILDER_TOOLS = [
113
113
  items: { type: 'string' },
114
114
  description: 'Replace the full set of MCP permissions granted to the agent\'s session API key (e.g. ["mcp:work_items:read", "mcp:comments:create"]). Grant only what the agent\'s tasks need. An empty array falls back to a read-only default.',
115
115
  },
116
+ scheduling_enabled: {
117
+ type: 'boolean',
118
+ description: "The agent-level scheduling switch. No schedule fires while it is off, whatever the schedule's own enabled flag says.",
119
+ },
116
120
  ...ORG_SLUG_PROP,
117
121
  },
118
122
  required: ['agent_id'],
@@ -428,6 +432,12 @@ export const AGENT_BUILDER_TOOLS = [
428
432
  properties: {
429
433
  agent_id: { type: 'string', description: 'Agent profile ID' },
430
434
  task_id: { type: 'string', description: 'Task ID to run' },
435
+ prompt: {
436
+ type: 'string',
437
+ description: "Extra instructions for this run only, appended to the task's saved prompt. " +
438
+ 'The task still runs as written — this is added after it, and the task is not changed. ' +
439
+ 'Omit it to run the task exactly as saved.',
440
+ },
431
441
  project_slug: { type: 'string', description: 'Project to scope the session to (optional)' },
432
442
  git_ref: {
433
443
  type: 'string',
@@ -526,6 +536,23 @@ export const AGENT_BUILDER_TOOLS = [
526
536
  description: 'When true, tasks run once with access to all assigned projects. ' +
527
537
  'When false, tasks run once per project.',
528
538
  },
539
+ preflight_check: {
540
+ type: 'string',
541
+ enum: ['claimable-work', 'claimable-check'],
542
+ description: 'LLM-free condition evaluated when the schedule fires; a false result skips the fire with no session and no cost. ' +
543
+ '"claimable-work": an approved, unclaimed item is assigned to the agent or sits in one of its work pools. ' +
544
+ '"claimable-check": a pending, unclaimed review check sits on an item in one of its pools. Null to clear.',
545
+ },
546
+ check_kinds: {
547
+ type: 'array',
548
+ items: { type: 'string' },
549
+ description: 'With "claimable-check": only checks of these kinds wake the schedule (e.g. ["security-review"]), so reviewers ' +
550
+ 'sharing a pool each answer their own kind. Empty for every kind.',
551
+ },
552
+ skip_while_active: {
553
+ type: 'boolean',
554
+ description: 'Skip a fire entirely while the agent still has a queued or running task, or leads an item awaiting review.',
555
+ },
529
556
  task_ids: {
530
557
  type: 'array',
531
558
  items: { type: 'string' },
@@ -569,6 +596,23 @@ export const AGENT_BUILDER_TOOLS = [
569
596
  type: 'boolean',
570
597
  description: 'Run once across all projects (true) or once per project (false)',
571
598
  },
599
+ preflight_check: {
600
+ type: 'string',
601
+ enum: ['claimable-work', 'claimable-check'],
602
+ description: 'LLM-free condition evaluated when the schedule fires; a false result skips the fire with no session and no cost. ' +
603
+ '"claimable-work": an approved, unclaimed item is assigned to the agent or sits in one of its work pools. ' +
604
+ '"claimable-check": a pending, unclaimed review check sits on an item in one of its pools. Null to clear.',
605
+ },
606
+ check_kinds: {
607
+ type: 'array',
608
+ items: { type: 'string' },
609
+ description: 'With "claimable-check": only checks of these kinds wake the schedule (e.g. ["security-review"]), so reviewers ' +
610
+ 'sharing a pool each answer their own kind. Empty for every kind.',
611
+ },
612
+ skip_while_active: {
613
+ type: 'boolean',
614
+ description: 'Skip a fire entirely while the agent still has a queued or running task, or leads an item awaiting review.',
615
+ },
572
616
  task_ids: {
573
617
  type: 'array',
574
618
  items: { type: 'string' },
@@ -792,6 +836,19 @@ const AgentTaskSchema = z.object({
792
836
  org_slug: orgSlugField,
793
837
  });
794
838
  const SkillIdSchema = z.object({ skill_id: z.string(), org_slug: orgSlugField });
839
+ /**
840
+ * A schedule enabled on an agent whose own scheduling switch is off never
841
+ * fires (#2083) — say so in the result rather than letting the caller find
842
+ * out from a schedule that stays silent.
843
+ */
844
+ async function schedulingOffWarning(client, agentId, scheduleEnabled, orgSlug) {
845
+ if (!scheduleEnabled)
846
+ return '';
847
+ const agent = await client.getAgent(agentId, orgSlug);
848
+ return !agent || agent.schedulingEnabled
849
+ ? ''
850
+ : "\n\nWARNING: this agent's scheduling is switched off, so the schedule will not fire until update_agent sets scheduling_enabled: true.";
851
+ }
795
852
  export async function handleAgentBuilderTool(name, args, client) {
796
853
  const text = (t) => JSON.stringify(t, null, 2);
797
854
  switch (name) {
@@ -849,6 +906,7 @@ export async function handleAgentBuilderTool(name, args, client) {
849
906
  llm_model: z.string().nullable().optional(),
850
907
  llm_family: z.string().nullable().optional(),
851
908
  api_key_permissions: z.array(z.string()).optional(),
909
+ scheduling_enabled: z.boolean().optional(),
852
910
  org_slug: orgSlugField,
853
911
  })
854
912
  .parse(args);
@@ -872,6 +930,8 @@ export async function handleAgentBuilderTool(name, args, client) {
872
930
  fields.llmFamily = rest.llm_family;
873
931
  if (rest.api_key_permissions !== undefined)
874
932
  fields.apiKeyPermissions = rest.api_key_permissions;
933
+ if (rest.scheduling_enabled !== undefined)
934
+ fields.schedulingEnabled = rest.scheduling_enabled;
875
935
  const agent = await client.updateAgent(agent_id, fields, resolveOrg(parsed));
876
936
  return { content: [{ type: 'text', text: `Updated agent\n\n${text(agent)}` }] };
877
937
  }
@@ -1110,13 +1170,14 @@ export async function handleAgentBuilderTool(name, args, client) {
1110
1170
  .object({
1111
1171
  agent_id: z.string(),
1112
1172
  task_id: z.string(),
1173
+ prompt: z.string().optional(),
1113
1174
  project_slug: z.string().optional(),
1114
1175
  git_ref: z.string().optional(),
1115
1176
  pr_number: z.number().int().positive().optional(),
1116
1177
  org_slug: orgSlugField,
1117
1178
  })
1118
1179
  .parse(args);
1119
- const result = await client.runAgentTask(parsed.agent_id, parsed.task_id, parsed.project_slug, resolveOrg(parsed), parsed.git_ref, parsed.pr_number);
1180
+ const result = await client.runAgentTask(parsed.agent_id, parsed.task_id, parsed.project_slug, resolveOrg(parsed), parsed.git_ref, parsed.pr_number, parsed.prompt);
1120
1181
  return {
1121
1182
  content: [
1122
1183
  {
@@ -1159,6 +1220,9 @@ export async function handleAgentBuilderTool(name, args, client) {
1159
1220
  timezone: z.string().optional(),
1160
1221
  dst_aware: z.boolean().optional(),
1161
1222
  multi_project: z.boolean().optional(),
1223
+ preflight_check: z.enum(['claimable-work', 'claimable-check']).nullable().optional(),
1224
+ check_kinds: z.array(z.string()).optional(),
1225
+ skip_while_active: z.boolean().optional(),
1162
1226
  task_ids: z.array(z.string()).optional(),
1163
1227
  org_slug: orgSlugField,
1164
1228
  })
@@ -1183,12 +1247,22 @@ export async function handleAgentBuilderTool(name, args, client) {
1183
1247
  body.dstAware = rest.dst_aware;
1184
1248
  if (rest.multi_project !== undefined)
1185
1249
  body.multiProject = rest.multi_project;
1250
+ if (rest.preflight_check !== undefined)
1251
+ body.preflightCheck = rest.preflight_check;
1252
+ if (rest.check_kinds !== undefined)
1253
+ body.checkKinds = rest.check_kinds;
1254
+ if (rest.skip_while_active !== undefined)
1255
+ body.skipWhileActive = rest.skip_while_active;
1186
1256
  if (rest.task_ids !== undefined)
1187
1257
  body.taskIds = rest.task_ids;
1188
1258
  const schedule = await client.createAgentSchedule(agent_id, body, resolveOrg(parsed));
1259
+ const warning = await schedulingOffWarning(client, agent_id, schedule.enabled, resolveOrg(parsed));
1189
1260
  return {
1190
1261
  content: [
1191
- { type: 'text', text: `Created schedule "${schedule.name}"\n\n${text(schedule)}` },
1262
+ {
1263
+ type: 'text',
1264
+ text: `Created schedule "${schedule.name}"${warning}\n\n${text(schedule)}`,
1265
+ },
1192
1266
  ],
1193
1267
  };
1194
1268
  }
@@ -1206,6 +1280,9 @@ export async function handleAgentBuilderTool(name, args, client) {
1206
1280
  timezone: z.string().optional(),
1207
1281
  dst_aware: z.boolean().optional(),
1208
1282
  multi_project: z.boolean().optional(),
1283
+ preflight_check: z.enum(['claimable-work', 'claimable-check']).nullable().optional(),
1284
+ check_kinds: z.array(z.string()).optional(),
1285
+ skip_while_active: z.boolean().optional(),
1209
1286
  task_ids: z.array(z.string()).optional(),
1210
1287
  org_slug: orgSlugField,
1211
1288
  })
@@ -1230,10 +1307,19 @@ export async function handleAgentBuilderTool(name, args, client) {
1230
1307
  body.dstAware = rest.dst_aware;
1231
1308
  if (rest.multi_project !== undefined)
1232
1309
  body.multiProject = rest.multi_project;
1310
+ if (rest.preflight_check !== undefined)
1311
+ body.preflightCheck = rest.preflight_check;
1312
+ if (rest.check_kinds !== undefined)
1313
+ body.checkKinds = rest.check_kinds;
1314
+ if (rest.skip_while_active !== undefined)
1315
+ body.skipWhileActive = rest.skip_while_active;
1233
1316
  if (rest.task_ids !== undefined)
1234
1317
  body.taskIds = rest.task_ids;
1235
1318
  const schedule = await client.updateAgentSchedule(agent_id, schedule_id, body, resolveOrg(parsed));
1236
- return { content: [{ type: 'text', text: `Updated schedule\n\n${text(schedule)}` }] };
1319
+ const warning = await schedulingOffWarning(client, agent_id, schedule.enabled, resolveOrg(parsed));
1320
+ return {
1321
+ content: [{ type: 'text', text: `Updated schedule${warning}\n\n${text(schedule)}` }],
1322
+ };
1237
1323
  }
1238
1324
  // ─── Skills ─────────────────────────────────────────────────────────────
1239
1325
  case 'create_skill': {
@@ -74,3 +74,92 @@ describe('per-task model pin over MCP (#2034)', () => {
74
74
  expect(updateAgentTask.mock.calls[0][2]).toEqual({ prompt: 'Analyse the transcript twice.' });
75
75
  });
76
76
  });
77
+ // #2048 — run_agent_task can add instructions for one run without editing the
78
+ // task. The prompt is the 7th argument of client.runAgentTask, so these assert
79
+ // on the position as well as the value.
80
+ describe('extra instructions on a task run over MCP (#2048)', () => {
81
+ const runClient = () => {
82
+ const runAgentTask = vi.fn().mockResolvedValue({ entryId: 'e1', position: 0, executing: true });
83
+ return { client: { runAgentTask }, runAgentTask };
84
+ };
85
+ it('advertises the prompt argument as an addition, not a replacement', () => {
86
+ const properties = toolNamed('run_agent_task').inputSchema.properties;
87
+ expect(properties.prompt.description).toContain("appended to the task's saved prompt");
88
+ });
89
+ it('sends the extra instructions with the run', async () => {
90
+ const { client, runAgentTask } = runClient();
91
+ await handleAgentBuilderTool('run_agent_task', { agent_id: 'agent-1', task_id: 'task-1', prompt: 'Only cover last week.' }, client);
92
+ expect(runAgentTask.mock.calls[0][1]).toBe('task-1');
93
+ expect(runAgentTask.mock.calls[0][6]).toBe('Only cover last week.');
94
+ });
95
+ it('sends none when the caller only wants the task as saved', async () => {
96
+ const { client, runAgentTask } = runClient();
97
+ await handleAgentBuilderTool('run_agent_task', { agent_id: 'agent-1', task_id: 'task-1' }, client);
98
+ expect(runAgentTask.mock.calls[0][6]).toBeUndefined();
99
+ });
100
+ });
101
+ // #2083: everything the schedule editor can set is settable over MCP, and a
102
+ // schedule enabled on an agent whose scheduling switch is off says so.
103
+ describe('schedule pre-flight and scheduling switch over MCP (#2083)', () => {
104
+ const SCHEDULE_FIELDS = ['preflight_check', 'check_kinds', 'skip_while_active'];
105
+ it.each(['create_agent_schedule', 'update_agent_schedule'])('%s advertises the pre-flight fields', (name) => {
106
+ const properties = toolNamed(name).inputSchema.properties;
107
+ expect(Object.keys(properties)).toEqual(expect.arrayContaining(SCHEDULE_FIELDS));
108
+ });
109
+ it('update_agent advertises the scheduling switch', () => {
110
+ const properties = toolNamed('update_agent').inputSchema.properties;
111
+ expect(Object.keys(properties)).toContain('scheduling_enabled');
112
+ });
113
+ function scheduleClient(schedulingEnabled) {
114
+ const schedule = { id: 'sched-1', name: 'Reviews', enabled: true };
115
+ const createAgentSchedule = vi.fn().mockResolvedValue(schedule);
116
+ const updateAgentSchedule = vi.fn().mockResolvedValue(schedule);
117
+ const updateAgent = vi.fn().mockResolvedValue({ id: 'agent-1', schedulingEnabled });
118
+ const getAgent = vi.fn().mockResolvedValue({ id: 'agent-1', schedulingEnabled });
119
+ return {
120
+ client: {
121
+ createAgentSchedule,
122
+ updateAgentSchedule,
123
+ updateAgent,
124
+ getAgent,
125
+ },
126
+ createAgentSchedule,
127
+ updateAgentSchedule,
128
+ updateAgent,
129
+ };
130
+ }
131
+ it('sends the pre-flight, kinds and skip-while-active when creating a schedule', async () => {
132
+ const { client, createAgentSchedule } = scheduleClient(true);
133
+ await handleAgentBuilderTool('create_agent_schedule', {
134
+ agent_id: 'agent-1',
135
+ preflight_check: 'claimable-check',
136
+ check_kinds: ['security-review'],
137
+ skip_while_active: true,
138
+ }, client);
139
+ expect(createAgentSchedule.mock.calls[0][1]).toMatchObject({
140
+ preflightCheck: 'claimable-check',
141
+ checkKinds: ['security-review'],
142
+ skipWhileActive: true,
143
+ });
144
+ });
145
+ it('sends the same fields when updating a schedule', async () => {
146
+ const { client, updateAgentSchedule } = scheduleClient(true);
147
+ await handleAgentBuilderTool('update_agent_schedule', { agent_id: 'agent-1', schedule_id: 'sched-1', preflight_check: null, check_kinds: [] }, client);
148
+ expect(updateAgentSchedule.mock.calls[0][2]).toEqual({ preflightCheck: null, checkKinds: [] });
149
+ });
150
+ it('sends the scheduling switch when updating an agent', async () => {
151
+ const { client, updateAgent } = scheduleClient(true);
152
+ await handleAgentBuilderTool('update_agent', { agent_id: 'agent-1', scheduling_enabled: true }, client);
153
+ expect(updateAgent.mock.calls[0][1]).toEqual({ schedulingEnabled: true });
154
+ });
155
+ it('warns when an enabled schedule lands on an agent whose scheduling is off', async () => {
156
+ const { client } = scheduleClient(false);
157
+ const result = await handleAgentBuilderTool('create_agent_schedule', { agent_id: 'agent-1', enabled: true }, client);
158
+ expect(result.content[0].text).toContain('scheduling is switched off');
159
+ });
160
+ it('stays quiet when the agent is scheduling', async () => {
161
+ const { client } = scheduleClient(true);
162
+ const result = await handleAgentBuilderTool('create_agent_schedule', { agent_id: 'agent-1', enabled: true }, client);
163
+ expect(result.content[0].text).not.toContain('WARNING');
164
+ });
165
+ });
package/dist/client.js CHANGED
@@ -247,6 +247,8 @@ export class WolfpackClient {
247
247
  params.set('workItemId', filter.workItemId);
248
248
  if (filter.status)
249
249
  params.set('status', filter.status);
250
+ if (filter.kind)
251
+ params.set('kind', filter.kind);
250
252
  const query = params.toString();
251
253
  return this.api.get(this.withTeamSlug(`/work-item-checks${query ? `?${query}` : ''}`, teamSlug));
252
254
  }
@@ -502,6 +504,16 @@ export class WolfpackClient {
502
504
  const query = params.toString();
503
505
  return this.api.get(`/categories${query ? `?${query}` : ''}`);
504
506
  }
507
+ // Work pool methods (#2083)
508
+ async listWorkPools(teamSlug) {
509
+ return this.api.get(this.withTeamSlug('/work-pools', teamSlug));
510
+ }
511
+ async addWorkPoolMember(workPool, userId, teamSlug) {
512
+ return this.api.post(this.withTeamSlug(`/work-pools/${encodeURIComponent(workPool)}/members`, teamSlug), { userId });
513
+ }
514
+ async removeWorkPoolMember(workPool, userId, teamSlug) {
515
+ await this.api.delete(this.withTeamSlug(`/work-pools/${encodeURIComponent(workPool)}/members/${encodeURIComponent(userId)}`, teamSlug));
516
+ }
505
517
  // Tag methods
506
518
  async listTags(teamSlug) {
507
519
  const params = new URLSearchParams();
@@ -748,8 +760,9 @@ export class WolfpackClient {
748
760
  async updateAgentTask(agentId, taskId, body, orgSlug) {
749
761
  return this.api.patch(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}`, orgSlug), body);
750
762
  }
751
- async runAgentTask(agentId, taskId, teamSlug, orgSlug, gitRef, prNumber) {
752
- return this.api.post(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}/run`, orgSlug), { teamSlug, gitRef, prNumber });
763
+ /** `prompt` is appended to the task's saved prompt for this run only (#2048). */
764
+ async runAgentTask(agentId, taskId, teamSlug, orgSlug, gitRef, prNumber, prompt) {
765
+ return this.api.post(this.withOrgSlug(`/agents/${agentId}/tasks/${taskId}/run`, orgSlug), { teamSlug, gitRef, prNumber, prompt });
753
766
  }
754
767
  // ─── Agent Builder: Queue ──────────────────────────────────────────────────
755
768
  async listAgentQueue(agentId, status, orgSlug) {
package/dist/index.js CHANGED
@@ -215,11 +215,20 @@ const SubmitWorkItemFormSchema = z.object({
215
215
  .optional()
216
216
  .describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
217
217
  });
218
+ const WorkPoolMemberSchema = z.object({
219
+ work_pool: z.string().describe('Work pool id or name'),
220
+ user_id: z.string().describe('The user id to add or remove'),
221
+ project_slug: z
222
+ .string()
223
+ .optional()
224
+ .describe('Project slug (required for multi-project users, use list_projects to get slugs)'),
225
+ });
218
226
  const ListWorkItemChecksSchema = z.object({
219
227
  work_item_id: refIdString()
220
228
  .optional()
221
229
  .describe('The refId of a work item; omit for your reviewer inbox'),
222
230
  status: z.enum(['pending', 'passed', 'failed']).optional().describe('Filter by check status'),
231
+ kind: z.string().optional().describe('Filter by check kind, e.g. code-review or security-review'),
223
232
  project_slug: z
224
233
  .string()
225
234
  .optional()
@@ -1100,6 +1109,10 @@ class WolfpackMCPServer {
1100
1109
  enum: ['pending', 'passed', 'failed'],
1101
1110
  description: 'Filter by check status',
1102
1111
  },
1112
+ kind: {
1113
+ type: 'string',
1114
+ description: 'Filter by check kind (code-review, security-review, ...). A reviewer that answers one kind lists only that kind.',
1115
+ },
1103
1116
  project_slug: {
1104
1117
  type: 'string',
1105
1118
  description: 'Project slug (required for multi-project users, use list_projects to get slugs)',
@@ -1837,6 +1850,52 @@ class WolfpackMCPServer {
1837
1850
  },
1838
1851
  },
1839
1852
  },
1853
+ // Work pool tools (#2083)
1854
+ {
1855
+ name: 'list_work_pools',
1856
+ description: 'List the work pools in a project with their members. Reviewer and DevOps agents find their checks through pool membership, so this is how to see who is routed where.',
1857
+ inputSchema: {
1858
+ type: 'object',
1859
+ properties: {
1860
+ project_slug: {
1861
+ type: 'string',
1862
+ description: 'Project slug (required for multi-project users, use list_projects to get slugs)',
1863
+ },
1864
+ },
1865
+ },
1866
+ },
1867
+ {
1868
+ name: 'add_work_pool_member',
1869
+ description: "Add a user or agent (by user id, e.g. an agent profile's userId) to a work pool, named by id or name. Requires mcp:agents:update.",
1870
+ inputSchema: {
1871
+ type: 'object',
1872
+ properties: {
1873
+ work_pool: { type: 'string', description: 'Work pool id or name' },
1874
+ user_id: { type: 'string', description: 'The user id to add' },
1875
+ project_slug: {
1876
+ type: 'string',
1877
+ description: 'Project slug (required for multi-project users, use list_projects to get slugs)',
1878
+ },
1879
+ },
1880
+ required: ['work_pool', 'user_id'],
1881
+ },
1882
+ },
1883
+ {
1884
+ name: 'remove_work_pool_member',
1885
+ description: 'Remove a user or agent from a work pool. Requires mcp:agents:update.',
1886
+ inputSchema: {
1887
+ type: 'object',
1888
+ properties: {
1889
+ work_pool: { type: 'string', description: 'Work pool id or name' },
1890
+ user_id: { type: 'string', description: 'The user id to remove' },
1891
+ project_slug: {
1892
+ type: 'string',
1893
+ description: 'Project slug (required for multi-project users, use list_projects to get slugs)',
1894
+ },
1895
+ },
1896
+ required: ['work_pool', 'user_id'],
1897
+ },
1898
+ },
1840
1899
  // Tag tools
1841
1900
  {
1842
1901
  name: 'list_tags',
@@ -2439,7 +2498,7 @@ class WolfpackMCPServer {
2439
2498
  case 'list_work_item_checks': {
2440
2499
  const parsed = ListWorkItemChecksSchema.parse(args);
2441
2500
  const teamSlug = parsed.project_slug || this.client.getProjectSlug() || undefined;
2442
- const checks = await this.client.listWorkItemChecks({ workItemId: parsed.work_item_id, status: parsed.status }, teamSlug);
2501
+ const checks = await this.client.listWorkItemChecks({ workItemId: parsed.work_item_id, status: parsed.status, kind: parsed.kind }, teamSlug);
2443
2502
  const text = checks.length === 0
2444
2503
  ? parsed.work_item_id
2445
2504
  ? 'No review checks on this work item'
@@ -2938,6 +2997,36 @@ class WolfpackMCPServer {
2938
2997
  content: [{ type: 'text', text: JSON.stringify(categories, null, 2) }],
2939
2998
  };
2940
2999
  }
3000
+ // Work pool handlers (#2083)
3001
+ case 'list_work_pools': {
3002
+ const parsed = ListCategoriesSchema.parse(args);
3003
+ const pools = await this.client.listWorkPools(parsed.project_slug || this.client.getProjectSlug() || undefined);
3004
+ return { content: [{ type: 'text', text: JSON.stringify(pools, null, 2) }] };
3005
+ }
3006
+ case 'add_work_pool_member': {
3007
+ const parsed = WorkPoolMemberSchema.parse(args);
3008
+ await this.client.addWorkPoolMember(parsed.work_pool, parsed.user_id, parsed.project_slug || this.client.getProjectSlug() || undefined);
3009
+ return {
3010
+ content: [
3011
+ {
3012
+ type: 'text',
3013
+ text: `Added ${parsed.user_id} to work pool "${parsed.work_pool}"`,
3014
+ },
3015
+ ],
3016
+ };
3017
+ }
3018
+ case 'remove_work_pool_member': {
3019
+ const parsed = WorkPoolMemberSchema.parse(args);
3020
+ await this.client.removeWorkPoolMember(parsed.work_pool, parsed.user_id, parsed.project_slug || this.client.getProjectSlug() || undefined);
3021
+ return {
3022
+ content: [
3023
+ {
3024
+ type: 'text',
3025
+ text: `Removed ${parsed.user_id} from work pool "${parsed.work_pool}"`,
3026
+ },
3027
+ ],
3028
+ };
3029
+ }
2941
3030
  // Tag handlers
2942
3031
  case 'list_tags': {
2943
3032
  const parsed = ListTagsSchema.parse(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolfpack-mcp",
3
- "version": "1.0.89",
3
+ "version": "1.0.91",
4
4
  "description": "MCP server for Wolfpack AI-enhanced software delivery tools",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",