agent-planner-mcp 0.6.0 → 0.6.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-planner-mcp",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "MCP server for AgentPlanner — AI agent orchestration with planning, dependencies, knowledge graphs, and human oversight",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/api-client.js CHANGED
@@ -552,45 +552,47 @@ const goals = {
552
552
  return response.data;
553
553
  },
554
554
 
555
- updateMetrics: async (goalId, metrics) => {
556
- const response = await apiClient.put(`/goals/${goalId}/metrics`, { metrics });
557
- return response.data;
558
- },
559
-
560
555
  delete: async (goalId) => {
561
556
  const response = await apiClient.delete(`/goals/${goalId}`);
562
557
  return response.data;
563
558
  },
564
-
559
+
565
560
  linkPlan: async (goalId, planId) => {
566
- const response = await apiClient.post(`/goals/${goalId}/plans/${planId}`);
561
+ const response = await apiClient.post(`/goals/${goalId}/links`, {
562
+ linkedType: 'plan', linkedId: planId
563
+ });
567
564
  return response.data;
568
565
  },
569
-
566
+
570
567
  unlinkPlan: async (goalId, planId) => {
571
- const response = await apiClient.delete(`/goals/${goalId}/plans/${planId}`);
568
+ const goal = await apiClient.get(`/goals/${goalId}`);
569
+ const link = (goal.data.links || []).find(
570
+ l => l.linkedType === 'plan' && l.linkedId === planId
571
+ );
572
+ if (!link) return { success: false, message: 'Link not found' };
573
+ const response = await apiClient.delete(`/goals/${goalId}/links/${link.id}`);
572
574
  return response.data;
573
575
  },
574
576
 
575
577
  // v2 goal-dependency endpoints
576
578
  getPath: async (goalId, maxDepth) => {
577
579
  const params = maxDepth ? `?max_depth=${maxDepth}` : '';
578
- const response = await apiClient.get(`/goals/v2/${goalId}/path${params}`);
580
+ const response = await apiClient.get(`/goals/${goalId}/path${params}`);
579
581
  return response.data;
580
582
  },
581
583
 
582
584
  getProgress: async (goalId) => {
583
- const response = await apiClient.get(`/goals/v2/${goalId}/progress`);
585
+ const response = await apiClient.get(`/goals/${goalId}/progress`);
584
586
  return response.data;
585
587
  },
586
588
 
587
589
  listAchievers: async (goalId) => {
588
- const response = await apiClient.get(`/goals/v2/${goalId}/achievers`);
590
+ const response = await apiClient.get(`/goals/${goalId}/achievers`);
589
591
  return response.data;
590
592
  },
591
593
 
592
594
  addAchiever: async (goalId, sourceNodeId, weight) => {
593
- const response = await apiClient.post(`/goals/v2/${goalId}/achievers`, {
595
+ const response = await apiClient.post(`/goals/${goalId}/achievers`, {
594
596
  source_node_id: sourceNodeId,
595
597
  weight: weight ?? 1,
596
598
  });
@@ -598,17 +600,17 @@ const goals = {
598
600
  },
599
601
 
600
602
  removeAchiever: async (goalId, depId) => {
601
- const response = await apiClient.delete(`/goals/v2/${goalId}/achievers/${depId}`);
603
+ const response = await apiClient.delete(`/goals/${goalId}/achievers/${depId}`);
602
604
  return response.data;
603
605
  },
604
606
 
605
607
  getKnowledgeGaps: async (goalId) => {
606
- const response = await apiClient.get(`/goals/v2/${goalId}/knowledge-gaps`);
608
+ const response = await apiClient.get(`/goals/${goalId}/knowledge-gaps`);
607
609
  return response.data;
608
610
  },
609
611
 
610
612
  getDashboard: async () => {
611
- const response = await apiClient.get('/goals/v2/dashboard');
613
+ const response = await apiClient.get('/goals/dashboard');
612
614
  return response.data;
613
615
  },
614
616
  };
@@ -866,17 +868,21 @@ function createApiClient(token) {
866
868
  get: async (goalId) => (await client.get(`/goals/${goalId}`)).data,
867
869
  create: async (data) => (await client.post('/goals', data)).data,
868
870
  update: async (goalId, data) => (await client.put(`/goals/${goalId}`, data)).data,
869
- updateMetrics: async (goalId, metrics) => (await client.put(`/goals/${goalId}/metrics`, { metrics })).data,
870
871
  delete: async (goalId) => (await client.delete(`/goals/${goalId}`)).data,
871
- linkPlan: async (goalId, planId) => (await client.post(`/goals/${goalId}/plans/${planId}`)).data,
872
- unlinkPlan: async (goalId, planId) => (await client.delete(`/goals/${goalId}/plans/${planId}`)).data,
873
- getPath: async (goalId, maxDepth) => { const p = maxDepth ? `?max_depth=${maxDepth}` : ''; return (await client.get(`/goals/v2/${goalId}/path${p}`)).data; },
874
- getProgress: async (goalId) => (await client.get(`/goals/v2/${goalId}/progress`)).data,
875
- listAchievers: async (goalId) => (await client.get(`/goals/v2/${goalId}/achievers`)).data,
876
- addAchiever: async (goalId, sourceNodeId, weight) => (await client.post(`/goals/v2/${goalId}/achievers`, { source_node_id: sourceNodeId, weight: weight ?? 1 })).data,
877
- removeAchiever: async (goalId, depId) => (await client.delete(`/goals/v2/${goalId}/achievers/${depId}`)).data,
878
- getKnowledgeGaps: async (goalId) => (await client.get(`/goals/v2/${goalId}/knowledge-gaps`)).data,
879
- getDashboard: async () => (await client.get('/goals/v2/dashboard')).data,
872
+ linkPlan: async (goalId, planId) => (await client.post(`/goals/${goalId}/links`, { linkedType: 'plan', linkedId: planId })).data,
873
+ unlinkPlan: async (goalId, planId) => {
874
+ const goal = await client.get(`/goals/${goalId}`);
875
+ const link = (goal.data.links || []).find(l => l.linkedType === 'plan' && l.linkedId === planId);
876
+ if (!link) return { success: false, message: 'Link not found' };
877
+ return (await client.delete(`/goals/${goalId}/links/${link.id}`)).data;
878
+ },
879
+ getPath: async (goalId, maxDepth) => { const p = maxDepth ? `?max_depth=${maxDepth}` : ''; return (await client.get(`/goals/${goalId}/path${p}`)).data; },
880
+ getProgress: async (goalId) => (await client.get(`/goals/${goalId}/progress`)).data,
881
+ listAchievers: async (goalId) => (await client.get(`/goals/${goalId}/achievers`)).data,
882
+ addAchiever: async (goalId, sourceNodeId, weight) => (await client.post(`/goals/${goalId}/achievers`, { source_node_id: sourceNodeId, weight: weight ?? 1 })).data,
883
+ removeAchiever: async (goalId, depId) => (await client.delete(`/goals/${goalId}/achievers/${depId}`)).data,
884
+ getKnowledgeGaps: async (goalId) => (await client.get(`/goals/${goalId}/knowledge-gaps`)).data,
885
+ getDashboard: async () => (await client.get('/goals/dashboard')).data,
880
886
  },
881
887
  context: {
882
888
  getNodeContext: async (nodeId, options = {}) => {
package/src/index.js CHANGED
@@ -42,12 +42,9 @@ async function main() {
42
42
  console.error(`MCP Server Name: ${process.env.MCP_SERVER_NAME || 'planning-system-mcp'}`);
43
43
  console.error(`MCP Server Version: ${process.env.MCP_SERVER_VERSION || version}`);
44
44
 
45
- // Validate required environment variables
46
- if (!userApiToken) {
47
- throw new Error('USER_API_TOKEN environment variable is required. Please generate one from the Agent Planner UI and set it in .env file.');
48
- }
49
-
50
45
  if (transport === 'http') {
46
+ // HTTP mode: tokens come from the Authorization header on each request
47
+ // No USER_API_TOKEN needed — per-session clients are created in server-http.js
51
48
  // HTTP/SSE transport mode
52
49
  const httpServer = new MCPHTTPServer({
53
50
  port: process.env.PORT || 3100,
@@ -69,7 +66,11 @@ async function main() {
69
66
  process.exit(0);
70
67
  });
71
68
  } else {
72
- // Stdio transport mode (default)
69
+ // Stdio transport mode (default) — requires USER_API_TOKEN since there's no HTTP request
70
+ if (!userApiToken) {
71
+ throw new Error('USER_API_TOKEN environment variable is required for stdio mode. Please generate one from the Agent Planner UI and set it in .env file.');
72
+ }
73
+
73
74
  const server = new Server({
74
75
  name: process.env.MCP_SERVER_NAME || "planning-system-mcp",
75
76
  version: process.env.MCP_SERVER_VERSION || version
package/src/tools.js CHANGED
@@ -285,14 +285,19 @@ function setupTools(server, apiClientOverride) {
285
285
  // ===== PLAN MANAGEMENT TOOLS =====
286
286
  {
287
287
  name: "list_plans",
288
- description: "List all plans or filter by status",
288
+ description: "List plans. By default excludes completed/archived plans set include_completed to true to see all.",
289
289
  inputSchema: {
290
290
  type: "object",
291
291
  properties: {
292
- status: {
293
- type: "string",
292
+ status: {
293
+ type: "string",
294
294
  description: "Optional filter by plan status",
295
295
  enum: ["draft", "active", "completed", "archived"]
296
+ },
297
+ include_completed: {
298
+ type: "boolean",
299
+ description: "If true, include completed and archived plans (default: false)",
300
+ default: false
296
301
  }
297
302
  }
298
303
  }
@@ -815,15 +820,20 @@ function setupTools(server, apiClientOverride) {
815
820
  // ===== GOAL TOOLS =====
816
821
  {
817
822
  name: "list_goals",
818
- description: "List goals, optionally filtered by organization or status",
823
+ description: "List goals. By default returns only active goals — set include_inactive to true to see all.",
819
824
  inputSchema: {
820
825
  type: "object",
821
826
  properties: {
822
827
  organization_id: { type: "string", description: "Filter by organization ID" },
823
- status: {
824
- type: "string",
828
+ status: {
829
+ type: "string",
825
830
  description: "Filter by status",
826
831
  enum: ["active", "achieved", "at_risk", "abandoned"]
832
+ },
833
+ include_inactive: {
834
+ type: "boolean",
835
+ description: "If true, include achieved/paused/abandoned goals (default: false)",
836
+ default: false
827
837
  }
828
838
  }
829
839
  }
@@ -848,21 +858,10 @@ function setupTools(server, apiClientOverride) {
848
858
  organization_id: { type: "string", description: "Organization ID" },
849
859
  title: { type: "string", description: "Goal title" },
850
860
  description: { type: "string", description: "Goal description" },
851
- success_metrics: {
852
- type: "array",
853
- description: "Success metrics array [{metric, target, current, unit}]",
854
- items: {
855
- type: "object",
856
- properties: {
857
- metric: { type: "string" },
858
- target: { type: "number" },
859
- current: { type: "number" },
860
- unit: { type: "string" }
861
- }
862
- }
863
- },
864
- time_horizon: { type: "string", description: "Target date (ISO format)" },
865
- github_repo_url: { type: "string", description: "Related GitHub repo URL" }
861
+ type: { type: "string", enum: ["outcome", "constraint", "metric", "principle"], description: "Goal type (default: outcome)" },
862
+ success_criteria: { type: "object", description: "Success criteria as JSON" },
863
+ priority: { type: "number", description: "Priority (higher = more important, default: 0)" },
864
+ parent_goal_id: { type: "string", description: "Parent goal ID for hierarchy" }
866
865
  },
867
866
  required: ["organization_id", "title"]
868
867
  }
@@ -876,13 +875,15 @@ function setupTools(server, apiClientOverride) {
876
875
  goal_id: { type: "string", description: "Goal ID" },
877
876
  title: { type: "string", description: "New title" },
878
877
  description: { type: "string", description: "New description" },
879
- status: {
880
- type: "string",
878
+ type: { type: "string", enum: ["outcome", "constraint", "metric", "principle"], description: "Goal type" },
879
+ status: {
880
+ type: "string",
881
881
  description: "New status",
882
- enum: ["active", "achieved", "at_risk", "abandoned"]
882
+ enum: ["active", "achieved", "paused", "abandoned"]
883
883
  },
884
- success_metrics: { type: "array", description: "Updated metrics" },
885
- time_horizon: { type: "string", description: "New target date" }
884
+ success_criteria: { type: "object", description: "Success criteria as JSON" },
885
+ priority: { type: "number", description: "Priority (higher = more important)" },
886
+ parent_goal_id: { type: "string", description: "Parent goal ID for hierarchy" }
886
887
  },
887
888
  required: ["goal_id"]
888
889
  }
@@ -1655,9 +1656,16 @@ function setupTools(server, apiClientOverride) {
1655
1656
 
1656
1657
  // ===== PLAN MANAGEMENT =====
1657
1658
  if (name === "list_plans") {
1658
- const { status } = args;
1659
+ const { status, include_completed } = args;
1659
1660
  const plans = await apiClient.plans.getPlans();
1660
- const filteredPlans = status ? plans.filter(p => p.status === status) : plans;
1661
+ let filteredPlans;
1662
+ if (status) {
1663
+ filteredPlans = plans.filter(p => p.status === status);
1664
+ } else if (!include_completed) {
1665
+ filteredPlans = plans.filter(p => p.status !== 'completed' && p.status !== 'archived');
1666
+ } else {
1667
+ filteredPlans = plans;
1668
+ }
1661
1669
  return formatResponse(filteredPlans);
1662
1670
  }
1663
1671
 
@@ -2006,8 +2014,9 @@ function setupTools(server, apiClientOverride) {
2006
2014
 
2007
2015
  // ===== GOAL TOOLS =====
2008
2016
  if (name === "list_goals") {
2009
- const { organization_id, status } = args;
2010
- const result = await apiClient.goals.list({ organization_id, status });
2017
+ const { organization_id, status, include_inactive } = args;
2018
+ const effectiveStatus = status || (!include_inactive ? 'active' : undefined);
2019
+ const result = await apiClient.goals.list({ organization_id, status: effectiveStatus });
2011
2020
  return formatResponse(result);
2012
2021
  }
2013
2022
 
@@ -2018,20 +2027,24 @@ function setupTools(server, apiClientOverride) {
2018
2027
  }
2019
2028
 
2020
2029
  if (name === "create_goal") {
2021
- const { organization_id, title, description, success_metrics, time_horizon, github_repo_url } = args;
2030
+ const { organization_id, title, description, type, success_criteria, priority, parent_goal_id } = args;
2022
2031
  const result = await apiClient.goals.create({
2023
2032
  organization_id,
2024
2033
  title,
2025
2034
  description,
2026
- success_metrics,
2027
- time_horizon,
2028
- github_repo_url
2035
+ type: type || 'outcome',
2036
+ successCriteria: success_criteria || null,
2037
+ priority: priority || 0,
2038
+ parentGoalId: parent_goal_id || null,
2029
2039
  });
2030
2040
  return formatResponse(result);
2031
2041
  }
2032
2042
 
2033
2043
  if (name === "update_goal") {
2034
- const { goal_id, ...updateData } = args;
2044
+ const { goal_id, parent_goal_id, success_criteria, ...rest } = args;
2045
+ const updateData = { ...rest };
2046
+ if (parent_goal_id !== undefined) updateData.parentGoalId = parent_goal_id;
2047
+ if (success_criteria !== undefined) updateData.successCriteria = success_criteria;
2035
2048
  const result = await apiClient.goals.update(goal_id, updateData);
2036
2049
  return formatResponse(result);
2037
2050
  }