agent-planner-mcp 0.6.1 → 0.7.0
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/AGENT_GUIDE.md +12 -0
- package/README.md +4 -0
- package/SKILL.md +57 -0
- package/package.json +1 -1
- package/src/api-client.js +45 -26
- package/src/index.js +7 -6
- package/src/tools.js +100 -31
package/AGENT_GUIDE.md
CHANGED
|
@@ -5,6 +5,8 @@ This guide is optimized for AI agents using AgentPlanner MCP tools.
|
|
|
5
5
|
## Core Workflow
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
+
0. check_coherence_pending() → See if plans/goals need alignment review
|
|
9
|
+
→ If stale items: run_coherence_check(plan_id) on each
|
|
8
10
|
1. suggest_next_tasks(plan_id) → Find ready tasks (dependency-aware)
|
|
9
11
|
2. get_task_context(node_id, depth=2) → Load progressive context
|
|
10
12
|
3. Work on tasks (quick_status to track)
|
|
@@ -15,6 +17,16 @@ This guide is optimized for AI agents using AgentPlanner MCP tools.
|
|
|
15
17
|
|
|
16
18
|
## Essential Tools
|
|
17
19
|
|
|
20
|
+
### Preflight: Alignment Check
|
|
21
|
+
```javascript
|
|
22
|
+
check_coherence_pending()
|
|
23
|
+
// → Returns stale plans/goals that changed since last review
|
|
24
|
+
|
|
25
|
+
run_coherence_check({ plan_id: "..." })
|
|
26
|
+
// → Evaluates quality (coverage, specificity, ordering, knowledge)
|
|
27
|
+
// → Stamps plan as reviewed, returns score breakdown
|
|
28
|
+
```
|
|
29
|
+
|
|
18
30
|
### Before Starting Work
|
|
19
31
|
```javascript
|
|
20
32
|
get_plan_context({ plan_id: "..." })
|
package/README.md
CHANGED
|
@@ -149,6 +149,10 @@ Add the same JSON config to your Cline MCP settings in VS Code.
|
|
|
149
149
|
- `claim_task` / `release_task` - Task locking
|
|
150
150
|
- `share_plan` - Collaboration management
|
|
151
151
|
|
|
152
|
+
### Alignment & Review
|
|
153
|
+
- `check_coherence_pending` - See which plans/goals need alignment review (staleness check)
|
|
154
|
+
- `run_coherence_check` - Evaluate plan quality and stamp as reviewed
|
|
155
|
+
|
|
152
156
|
## LLM Skill Reference
|
|
153
157
|
|
|
154
158
|
See **[SKILL.md](./SKILL.md)** for a complete reference designed to be consumed by LLMs. Include it in system prompts or agent configurations to give any LLM full knowledge of how to use AgentPlanner tools effectively.
|
package/SKILL.md
CHANGED
|
@@ -31,12 +31,43 @@ You have access to the AgentPlanner MCP tools. AgentPlanner is a collaborative p
|
|
|
31
31
|
- You need to coordinate with humans on multi-step projects
|
|
32
32
|
- You want to persist findings, decisions, or progress across sessions
|
|
33
33
|
- You are asked to plan, research, or implement something as part of a tracked workflow
|
|
34
|
+
- A user wants help defining or refining a goal
|
|
35
|
+
|
|
36
|
+
## Goal Coaching
|
|
37
|
+
|
|
38
|
+
When a user expresses an intent, objective, or want — help them turn it into a well-structured goal. Don't just create a goal from their words. Coach them through it:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
1. Listen to the user's intent (however vague)
|
|
42
|
+
2. recall_knowledge() → Search for related context in the knowledge graph
|
|
43
|
+
3. list_goals() → Check for overlap with existing goals
|
|
44
|
+
4. list_plans() → Find related work that might link to this goal
|
|
45
|
+
5. Propose a structured goal:
|
|
46
|
+
- Clear title
|
|
47
|
+
- Description explaining why this matters
|
|
48
|
+
- Success criteria with specific metrics + targets
|
|
49
|
+
- Linked plans (existing or suggest new ones)
|
|
50
|
+
6. create_goal() + link plans
|
|
51
|
+
7. assess_goal_quality() → Check quality and get improvement suggestions
|
|
52
|
+
8. Iterate with the user until quality is high
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**What makes a good goal:**
|
|
56
|
+
- **Clear** — has a title and description that explain what and why
|
|
57
|
+
- **Measurable** — has success criteria with specific metrics and targets (e.g., "API latency < 100ms p99")
|
|
58
|
+
- **Actionable** — has at least one linked plan with concrete tasks
|
|
59
|
+
- **Knowledge-grounded** — related facts exist in the knowledge graph (if not, suggest researching first)
|
|
60
|
+
- **Committed** — promoted from desire to intention when ready, with a time reference
|
|
61
|
+
|
|
62
|
+
Use `assess_goal_quality(goal_id)` after creation to check quality and surface suggestions. Share the results with the user and help them address gaps.
|
|
34
63
|
|
|
35
64
|
## Workflow
|
|
36
65
|
|
|
37
66
|
Follow this sequence when working on a plan:
|
|
38
67
|
|
|
39
68
|
```
|
|
69
|
+
0. PREFLIGHT → check_coherence_pending to see if anything needs alignment review
|
|
70
|
+
↳ If stale plans found, run_coherence_check on each before starting task work
|
|
40
71
|
1. ORIENT → suggest_next_tasks or get_task_context to understand what needs doing
|
|
41
72
|
2. CLAIM → quick_status to mark the task in_progress
|
|
42
73
|
3. WORK → Do the actual work (code, research, analysis, etc.)
|
|
@@ -46,6 +77,22 @@ Follow this sequence when working on a plan:
|
|
|
46
77
|
6. NEXT → suggest_next_tasks to find the next ready task
|
|
47
78
|
```
|
|
48
79
|
|
|
80
|
+
### Preflight: Alignment Check
|
|
81
|
+
|
|
82
|
+
Before diving into tasks, check if goals, plans, and knowledge are aligned:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
check_coherence_pending()
|
|
86
|
+
→ Returns stale plans/goals that changed since last review
|
|
87
|
+
→ If stale items found:
|
|
88
|
+
run_coherence_check({ plan_id: "<plan_id>" })
|
|
89
|
+
→ Evaluates quality (coverage, specificity, ordering, knowledge)
|
|
90
|
+
→ Stamps the plan as reviewed
|
|
91
|
+
→ Returns quality breakdown + coherence issues
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This is a lightweight check (seconds, not minutes). Do it at the start of each work session. Skip if you already checked recently.
|
|
95
|
+
|
|
49
96
|
## Loading Context
|
|
50
97
|
|
|
51
98
|
Always load context before starting work. Use `get_task_context` — it gives you exactly the right amount of information based on depth level.
|
|
@@ -205,6 +252,16 @@ Cross-plan dependencies work the same as regular dependencies (`blocks`, `requir
|
|
|
205
252
|
| `claim_task` | Claim exclusive ownership of a task (prevents agent collisions) |
|
|
206
253
|
| `release_task` | Release a previously claimed task |
|
|
207
254
|
|
|
255
|
+
### Alignment & Review
|
|
256
|
+
|
|
257
|
+
Check if goals, plans, and knowledge are aligned. Run as a preflight check before starting work.
|
|
258
|
+
|
|
259
|
+
| Tool | Purpose |
|
|
260
|
+
|------|---------|
|
|
261
|
+
| `check_coherence_pending` | See what needs review — returns stale plans/goals that changed since last check |
|
|
262
|
+
| `run_coherence_check` | Evaluate a plan's quality (coverage, specificity, ordering, knowledge) and stamp as reviewed |
|
|
263
|
+
| `assess_goal_quality` | Check how well-defined a goal is (clarity, measurability, actionability, knowledge, commitment) |
|
|
264
|
+
|
|
208
265
|
### Knowledge (Temporal Knowledge Graph)
|
|
209
266
|
|
|
210
267
|
All knowledge is stored in the Graphiti temporal knowledge graph, which automatically extracts entities and relationships and enables cross-plan knowledge retrieval. The temporal graph is **cross-plan** and **persists across sessions** — anything recorded is available to all future agents and conversations within the organization.
|
package/package.json
CHANGED
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}/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,22 @@ const goals = {
|
|
|
598
600
|
},
|
|
599
601
|
|
|
600
602
|
removeAchiever: async (goalId, depId) => {
|
|
601
|
-
const response = await apiClient.delete(`/goals
|
|
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
|
|
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/
|
|
613
|
+
const response = await apiClient.get('/goals/dashboard');
|
|
614
|
+
return response.data;
|
|
615
|
+
},
|
|
616
|
+
|
|
617
|
+
getQuality: async (goalId) => {
|
|
618
|
+
const response = await apiClient.get(`/goals/${goalId}/quality`);
|
|
612
619
|
return response.data;
|
|
613
620
|
},
|
|
614
621
|
};
|
|
@@ -866,17 +873,21 @@ function createApiClient(token) {
|
|
|
866
873
|
get: async (goalId) => (await client.get(`/goals/${goalId}`)).data,
|
|
867
874
|
create: async (data) => (await client.post('/goals', data)).data,
|
|
868
875
|
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
876
|
delete: async (goalId) => (await client.delete(`/goals/${goalId}`)).data,
|
|
871
|
-
linkPlan: async (goalId, planId) => (await client.post(`/goals/${goalId}/
|
|
872
|
-
unlinkPlan: async (goalId, planId) =>
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
877
|
+
linkPlan: async (goalId, planId) => (await client.post(`/goals/${goalId}/links`, { linkedType: 'plan', linkedId: planId })).data,
|
|
878
|
+
unlinkPlan: async (goalId, planId) => {
|
|
879
|
+
const goal = await client.get(`/goals/${goalId}`);
|
|
880
|
+
const link = (goal.data.links || []).find(l => l.linkedType === 'plan' && l.linkedId === planId);
|
|
881
|
+
if (!link) return { success: false, message: 'Link not found' };
|
|
882
|
+
return (await client.delete(`/goals/${goalId}/links/${link.id}`)).data;
|
|
883
|
+
},
|
|
884
|
+
getPath: async (goalId, maxDepth) => { const p = maxDepth ? `?max_depth=${maxDepth}` : ''; return (await client.get(`/goals/${goalId}/path${p}`)).data; },
|
|
885
|
+
getProgress: async (goalId) => (await client.get(`/goals/${goalId}/progress`)).data,
|
|
886
|
+
listAchievers: async (goalId) => (await client.get(`/goals/${goalId}/achievers`)).data,
|
|
887
|
+
addAchiever: async (goalId, sourceNodeId, weight) => (await client.post(`/goals/${goalId}/achievers`, { source_node_id: sourceNodeId, weight: weight ?? 1 })).data,
|
|
888
|
+
removeAchiever: async (goalId, depId) => (await client.delete(`/goals/${goalId}/achievers/${depId}`)).data,
|
|
889
|
+
getKnowledgeGaps: async (goalId) => (await client.get(`/goals/${goalId}/knowledge-gaps`)).data,
|
|
890
|
+
getDashboard: async () => (await client.get('/goals/dashboard')).data,
|
|
880
891
|
},
|
|
881
892
|
context: {
|
|
882
893
|
getNodeContext: async (nodeId, options = {}) => {
|
|
@@ -913,6 +924,13 @@ function createApiClient(token) {
|
|
|
913
924
|
// Export the axios instance for direct use
|
|
914
925
|
const axiosInstance = apiClient;
|
|
915
926
|
|
|
927
|
+
// ─── Coherence ────────────────────────────────────────────────
|
|
928
|
+
const coherence = {
|
|
929
|
+
getPending: () => apiClient.get('/coherence/pending').then(r => r.data),
|
|
930
|
+
runCheck: (planId, goalId) => apiClient.post(`/plans/${planId}/coherence/check`, goalId ? { goal_id: goalId } : {}).then(r => r.data),
|
|
931
|
+
getPlanCoherence: (planId) => apiClient.get(`/plans/${planId}/coherence`).then(r => r.data),
|
|
932
|
+
};
|
|
933
|
+
|
|
916
934
|
module.exports = {
|
|
917
935
|
plans,
|
|
918
936
|
nodes,
|
|
@@ -926,6 +944,7 @@ module.exports = {
|
|
|
926
944
|
context,
|
|
927
945
|
graphiti,
|
|
928
946
|
dependencies,
|
|
947
|
+
coherence,
|
|
929
948
|
axiosInstance, // Export for direct API calls
|
|
930
949
|
createApiClient // Factory for per-session clients (HTTP mode)
|
|
931
950
|
};
|
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
|
@@ -178,6 +178,41 @@ function setupTools(server, apiClientOverride) {
|
|
|
178
178
|
}
|
|
179
179
|
},
|
|
180
180
|
|
|
181
|
+
// ========================================
|
|
182
|
+
// COHERENCE - Check alignment across goals/plans/knowledge
|
|
183
|
+
// ========================================
|
|
184
|
+
{
|
|
185
|
+
name: "check_coherence_pending",
|
|
186
|
+
description: "Check what needs coherence review. Returns stale plans and goals that have changed since their last coherence check. Call this at the start of a maintenance cycle to discover what needs attention. Uses timestamp comparison (updated_at vs coherence_checked_at) — no expensive processing.",
|
|
187
|
+
inputSchema: {
|
|
188
|
+
type: "object",
|
|
189
|
+
properties: {}
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "run_coherence_check",
|
|
194
|
+
description: "Run a coherence check on a specific plan. Evaluates quality (coverage, specificity, ordering, knowledge completeness), flags contradictions, and stamps the plan as checked. Returns quality breakdown with sub-scores and rationale.",
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: "object",
|
|
197
|
+
properties: {
|
|
198
|
+
plan_id: { type: "string", description: "Plan ID to check" },
|
|
199
|
+
goal_id: { type: "string", description: "Optional goal ID to evaluate coverage against" }
|
|
200
|
+
},
|
|
201
|
+
required: ["plan_id"]
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: "assess_goal_quality",
|
|
206
|
+
description: "Assess how well-defined a goal is. Evaluates 5 dimensions: clarity (title+description), measurability (success criteria), actionability (linked plans), knowledge grounding (related facts), and commitment (desire vs intention, deadline). Returns score, dimension breakdown, and specific improvement suggestions. Use this when helping users define or refine goals.",
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: "object",
|
|
209
|
+
properties: {
|
|
210
|
+
goal_id: { type: "string", description: "Goal ID to assess" }
|
|
211
|
+
},
|
|
212
|
+
required: ["goal_id"]
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
|
|
181
216
|
// ========================================
|
|
182
217
|
// CONTEXT LOADING - Get everything you need
|
|
183
218
|
// Use before starting work on a plan/goal
|
|
@@ -858,21 +893,10 @@ function setupTools(server, apiClientOverride) {
|
|
|
858
893
|
organization_id: { type: "string", description: "Organization ID" },
|
|
859
894
|
title: { type: "string", description: "Goal title" },
|
|
860
895
|
description: { type: "string", description: "Goal description" },
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
type: "object",
|
|
866
|
-
properties: {
|
|
867
|
-
metric: { type: "string" },
|
|
868
|
-
target: { type: "number" },
|
|
869
|
-
current: { type: "number" },
|
|
870
|
-
unit: { type: "string" }
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
},
|
|
874
|
-
time_horizon: { type: "string", description: "Target date (ISO format)" },
|
|
875
|
-
github_repo_url: { type: "string", description: "Related GitHub repo URL" }
|
|
896
|
+
type: { type: "string", enum: ["outcome", "constraint", "metric", "principle"], description: "Goal type (default: outcome)" },
|
|
897
|
+
success_criteria: { type: "object", description: "Success criteria as JSON" },
|
|
898
|
+
priority: { type: "number", description: "Priority (higher = more important, default: 0)" },
|
|
899
|
+
parent_goal_id: { type: "string", description: "Parent goal ID for hierarchy" }
|
|
876
900
|
},
|
|
877
901
|
required: ["organization_id", "title"]
|
|
878
902
|
}
|
|
@@ -886,13 +910,15 @@ function setupTools(server, apiClientOverride) {
|
|
|
886
910
|
goal_id: { type: "string", description: "Goal ID" },
|
|
887
911
|
title: { type: "string", description: "New title" },
|
|
888
912
|
description: { type: "string", description: "New description" },
|
|
889
|
-
|
|
890
|
-
|
|
913
|
+
type: { type: "string", enum: ["outcome", "constraint", "metric", "principle"], description: "Goal type" },
|
|
914
|
+
status: {
|
|
915
|
+
type: "string",
|
|
891
916
|
description: "New status",
|
|
892
|
-
enum: ["active", "achieved", "
|
|
917
|
+
enum: ["active", "achieved", "paused", "abandoned"]
|
|
893
918
|
},
|
|
894
|
-
|
|
895
|
-
|
|
919
|
+
success_criteria: { type: "object", description: "Success criteria as JSON" },
|
|
920
|
+
priority: { type: "number", description: "Priority (higher = more important)" },
|
|
921
|
+
parent_goal_id: { type: "string", description: "Parent goal ID for hierarchy" }
|
|
896
922
|
},
|
|
897
923
|
required: ["goal_id"]
|
|
898
924
|
}
|
|
@@ -2036,20 +2062,24 @@ function setupTools(server, apiClientOverride) {
|
|
|
2036
2062
|
}
|
|
2037
2063
|
|
|
2038
2064
|
if (name === "create_goal") {
|
|
2039
|
-
const { organization_id, title, description,
|
|
2065
|
+
const { organization_id, title, description, type, success_criteria, priority, parent_goal_id } = args;
|
|
2040
2066
|
const result = await apiClient.goals.create({
|
|
2041
2067
|
organization_id,
|
|
2042
2068
|
title,
|
|
2043
2069
|
description,
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2070
|
+
type: type || 'outcome',
|
|
2071
|
+
successCriteria: success_criteria || null,
|
|
2072
|
+
priority: priority || 0,
|
|
2073
|
+
parentGoalId: parent_goal_id || null,
|
|
2047
2074
|
});
|
|
2048
2075
|
return formatResponse(result);
|
|
2049
2076
|
}
|
|
2050
2077
|
|
|
2051
2078
|
if (name === "update_goal") {
|
|
2052
|
-
const { goal_id, ...
|
|
2079
|
+
const { goal_id, parent_goal_id, success_criteria, ...rest } = args;
|
|
2080
|
+
const updateData = { ...rest };
|
|
2081
|
+
if (parent_goal_id !== undefined) updateData.parentGoalId = parent_goal_id;
|
|
2082
|
+
if (success_criteria !== undefined) updateData.successCriteria = success_criteria;
|
|
2053
2083
|
const result = await apiClient.goals.update(goal_id, updateData);
|
|
2054
2084
|
return formatResponse(result);
|
|
2055
2085
|
}
|
|
@@ -2238,12 +2268,14 @@ function setupTools(server, apiClientOverride) {
|
|
|
2238
2268
|
"Knowledge - Persistent storage for decisions, context, constraints, and learnings"
|
|
2239
2269
|
],
|
|
2240
2270
|
recommended_workflow: [
|
|
2241
|
-
"1.
|
|
2242
|
-
"
|
|
2243
|
-
"
|
|
2244
|
-
"
|
|
2245
|
-
"
|
|
2246
|
-
"
|
|
2271
|
+
"1. PREFLIGHT: check_coherence_pending to see if any plans/goals need alignment review",
|
|
2272
|
+
" → If stale items found, run_coherence_check on each before starting task work",
|
|
2273
|
+
"2. Check list_goals to understand current objectives",
|
|
2274
|
+
"3. Use list_plans to see existing plans",
|
|
2275
|
+
"4. Before working on a plan, use get_plan_context to get the full picture",
|
|
2276
|
+
"5. Update task statuses as you work (update_node with status)",
|
|
2277
|
+
"6. Store important decisions and learnings using add_learning",
|
|
2278
|
+
"7. Check recall_knowledge before making decisions to see past context"
|
|
2247
2279
|
],
|
|
2248
2280
|
quick_tips: [
|
|
2249
2281
|
"Always capture WHY decisions were made, not just WHAT",
|
|
@@ -2380,6 +2412,43 @@ function setupTools(server, apiClientOverride) {
|
|
|
2380
2412
|
});
|
|
2381
2413
|
}
|
|
2382
2414
|
|
|
2415
|
+
// ===== COHERENCE =====
|
|
2416
|
+
if (name === "check_coherence_pending") {
|
|
2417
|
+
const result = await apiClient.coherence.getPending();
|
|
2418
|
+
const totalStale = (result.stale_plans?.length || 0) + (result.stale_goals?.length || 0);
|
|
2419
|
+
return formatResponse({
|
|
2420
|
+
...result,
|
|
2421
|
+
tip: totalStale > 0
|
|
2422
|
+
? "Review stale items. For each stale plan, call run_coherence_check to evaluate quality and stamp as checked."
|
|
2423
|
+
: "Everything is up to date. No coherence review needed."
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
if (name === "assess_goal_quality") {
|
|
2428
|
+
const { goal_id } = args;
|
|
2429
|
+
const result = await apiClient.goals.getQuality(goal_id);
|
|
2430
|
+
const lowDims = Object.entries(result.dimensions || {})
|
|
2431
|
+
.filter(([, v]) => v.score < 0.5)
|
|
2432
|
+
.map(([k]) => k);
|
|
2433
|
+
return formatResponse({
|
|
2434
|
+
...result,
|
|
2435
|
+
tip: result.suggestions?.length > 0
|
|
2436
|
+
? `Goal needs improvement in: ${lowDims.join(', ') || 'minor areas'}. Follow the suggestions to strengthen it.`
|
|
2437
|
+
: 'Goal is well-defined. Ready for agent execution.'
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
if (name === "run_coherence_check") {
|
|
2442
|
+
const { plan_id, goal_id } = args;
|
|
2443
|
+
const result = await apiClient.coherence.runCheck(plan_id, goal_id);
|
|
2444
|
+
return formatResponse({
|
|
2445
|
+
...result,
|
|
2446
|
+
tip: result.coherence_issues_count > 0
|
|
2447
|
+
? `${result.coherence_issues_count} coherence issues found. Review tasks with stale_beliefs or contradiction_detected status.`
|
|
2448
|
+
: "Plan is coherent. Quality score and checked_at timestamp updated."
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2383
2452
|
// Tool not found
|
|
2384
2453
|
throw new Error(`Unknown tool: ${name}`);
|
|
2385
2454
|
} catch (error) {
|