@nestr/mcp 0.1.45 → 0.1.47
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 +42 -2
- package/build/analytics/ga4.js +2 -5
- package/build/analytics/ga4.js.map +1 -1
- package/build/api/client.d.ts +22 -3
- package/build/api/client.d.ts.map +1 -1
- package/build/api/client.js +58 -6
- package/build/api/client.js.map +1 -1
- package/build/http.d.ts.map +1 -1
- package/build/http.js +94 -40
- package/build/http.js.map +1 -1
- package/build/oauth/storage.d.ts +8 -0
- package/build/oauth/storage.d.ts.map +1 -1
- package/build/oauth/storage.js +65 -0
- package/build/oauth/storage.js.map +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +103 -221
- package/build/server.js.map +1 -1
- package/build/skills/doing-work.d.ts +10 -0
- package/build/skills/doing-work.d.ts.map +1 -0
- package/build/skills/doing-work.js +257 -0
- package/build/skills/doing-work.js.map +1 -0
- package/build/skills/tension-processing.d.ts.map +1 -1
- package/build/skills/tension-processing.js +88 -12
- package/build/skills/tension-processing.js.map +1 -1
- package/build/tools/index.d.ts +874 -65
- package/build/tools/index.d.ts.map +1 -1
- package/build/tools/index.js +241 -44
- package/build/tools/index.js.map +1 -1
- package/package.json +7 -5
- package/web/favicon.png +0 -0
- package/web/index.html +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAiB,KAAK,WAAW,EAA6C,MAAM,kBAAkB,CAAC;AA+E9G,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAiB,KAAK,WAAW,EAA6C,MAAM,kBAAkB,CAAC;AA+E9G,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmanB,CAAC;AAQF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAqhC3B,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAuBF,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC,CAcrB"}
|
package/build/tools/index.js
CHANGED
|
@@ -77,7 +77,7 @@ export const schemas = {
|
|
|
77
77
|
}),
|
|
78
78
|
createWorkspace: z.object({
|
|
79
79
|
title: z.string().describe("Workspace name"),
|
|
80
|
-
purpose: z.string().optional().describe("Workspace purpose
|
|
80
|
+
purpose: z.string().optional().describe("Workspace purpose — the aspirational future state of the organization. Defines the north star that all circles and roles serve."),
|
|
81
81
|
type: z.enum(['personal', 'collaborative']).optional().describe("'personal' for individual use (free forever), 'collaborative' for team use (free trial, then paid). Defaults to 'collaborative'."),
|
|
82
82
|
governance: z.enum(['holacracy', 'sociocracy', 'roles_circles']).optional().describe("Self-organization model. Defaults to 'roles_circles' (generic role-based)."),
|
|
83
83
|
plan: z.enum(['starter', 'pro']).optional().describe("Subscription plan for collaborative workspaces. Defaults to 'pro' (17-day trial)."),
|
|
@@ -94,18 +94,20 @@ export const schemas = {
|
|
|
94
94
|
getNest: z.object({
|
|
95
95
|
nestId: z.string().describe("Nest ID. Supports comma-separated IDs to fetch multiple nests in one call (e.g., 'id1,id2,id3') — returns an array instead of a single object. Keep total URL under 2000 chars to avoid HTTP limits."),
|
|
96
96
|
fieldsMetaData: z.boolean().optional().describe("Set to true to include field schema metadata (e.g., available options for project.status)"),
|
|
97
|
+
hints: z.boolean().optional().describe("Include contextual hints on each nest (default: true). Hints surface actionable signals like unassigned roles, stale projects, or unread comments. Set to false for bulk lookups where you only need structural data, not contextual guidance."),
|
|
97
98
|
}),
|
|
98
99
|
getNestChildren: z.object({
|
|
99
100
|
nestId: z.string().describe("Parent nest ID"),
|
|
100
101
|
limit: z.number().optional().describe("Max results per page. Omit to see full count in meta.total."),
|
|
101
102
|
page: z.number().optional().describe("Page number for pagination"),
|
|
103
|
+
hints: z.boolean().optional().describe("Include contextual hints on each child nest (default: true). Set to false for large result sets or bulk operations where contextual signals aren't needed."),
|
|
102
104
|
_listTitle: z.string().optional().describe("Short descriptive title for the list UI (e.g., \"Tasks for Website Redesign\"). Omit for default."),
|
|
103
105
|
}),
|
|
104
106
|
createNest: z.object({
|
|
105
107
|
parentId: z.string().describe("Parent nest ID (workspace, circle, or project)"),
|
|
106
108
|
title: z.string().describe("Title of the new nest (plain text, HTML stripped)"),
|
|
107
|
-
purpose: z.string().optional().describe("Purpose
|
|
108
|
-
description: z.string().optional().describe("Detailed description
|
|
109
|
+
purpose: z.string().optional().describe("Purpose — the aspirational future state this nest is working towards. Most important for workspaces, circles, and roles where it defines the north star and context boundary. For other nests, prefer description or fields for detailed information — but purpose can be set if meaningful. Supports HTML."),
|
|
110
|
+
description: z.string().optional().describe("Detailed description — the primary field for storing information about a nest. Use for project details, task context, acceptance criteria, Definition of Done, etc. Supports HTML: <b>, <i>, <code>, <ul>, <li>, <a>."),
|
|
109
111
|
labels: z.array(z.string()).optional().describe("Label IDs to apply"),
|
|
110
112
|
users: z.array(z.string()).optional().describe("User IDs to assign (required for tasks/projects to associate with a person)"),
|
|
111
113
|
accountabilities: z.array(z.string()).optional().describe("Accountability titles for roles/circles. Only used when labels include 'role' or 'circle'. Each string becomes an accountability child nest."),
|
|
@@ -115,8 +117,8 @@ export const schemas = {
|
|
|
115
117
|
updateNest: z.object({
|
|
116
118
|
nestId: z.string().describe("Nest ID to update"),
|
|
117
119
|
title: z.string().optional().describe("New title (plain text, HTML stripped)"),
|
|
118
|
-
purpose: z.string().optional().describe("New purpose
|
|
119
|
-
description: z.string().optional().describe("New description
|
|
120
|
+
purpose: z.string().optional().describe("New purpose — the aspirational future state. Most important for workspaces, circles, and roles. For other nests, prefer description or fields — but purpose can be set if meaningful. Supports HTML."),
|
|
121
|
+
description: z.string().optional().describe("New description — the primary field for detailed information. Use for project details, task context, acceptance criteria, etc. Supports HTML."),
|
|
120
122
|
parentId: z.string().optional().describe("New parent ID (move nest to different location, e.g., move inbox item to a role or project)"),
|
|
121
123
|
labels: z.array(z.string()).optional().describe("Label IDs to set (e.g., ['project'] to convert an item into a project)"),
|
|
122
124
|
fields: z.record(z.unknown()).optional().describe("Field updates (e.g., { 'project.status': 'Current' })"),
|
|
@@ -295,7 +297,7 @@ export const schemas = {
|
|
|
295
297
|
markNotificationsRead: z.object({}),
|
|
296
298
|
// Tension tools
|
|
297
299
|
createTension: z.object({
|
|
298
|
-
nestId: z.string().describe("ID of the
|
|
300
|
+
nestId: z.string().describe("ID of the role or circle to create the tension on. Use a role ID when that role is sensing the tension. Use a circle ID for cross-role, governance, or personally sensed tensions."),
|
|
299
301
|
title: z.string().describe("The gap you're sensing — what is the difference between current reality and desired state (plain text)"),
|
|
300
302
|
description: z.string().optional().describe("The observable facts — what you see/hear/experience that creates this tension (supports HTML)"),
|
|
301
303
|
feeling: z.string().optional().describe("The feeling this tension evokes in you — separated from the facts to keep the organizational response clean (plain text)"),
|
|
@@ -333,35 +335,58 @@ export const schemas = {
|
|
|
333
335
|
_id: z.string().optional().describe("ID of an existing governance item to change or remove. Omit to propose a new item."),
|
|
334
336
|
title: z.string().optional().describe("Title for the governance item"),
|
|
335
337
|
labels: z.array(z.string()).optional().describe("Labels defining the item type (e.g., ['role'], ['circle'], ['policy'], ['accountability'], ['domain'])"),
|
|
336
|
-
purpose: z.string().optional().describe("Purpose
|
|
337
|
-
description: z.string().optional().describe("Description
|
|
338
|
+
purpose: z.string().optional().describe("Purpose — aspirational future state. Most important for roles/circles where it defines the north star. Supports HTML."),
|
|
339
|
+
description: z.string().optional().describe("Description — detailed information about the item. Supports HTML."),
|
|
338
340
|
parentId: z.string().optional().describe("Parent ID — use to move/restructure items (e.g., move role to different circle)"),
|
|
339
341
|
users: z.array(z.string()).optional().describe("User IDs to assign (e.g., for role elections: assign the elected user to the role)"),
|
|
340
342
|
due: z.string().optional().describe("Due date / re-election date (ISO format)"),
|
|
341
|
-
accountabilities: z.array(z.string()).optional().describe("Accountability titles to set on a role (replaces
|
|
342
|
-
domains: z.array(z.string()).optional().describe("Domain titles to set on a role (replaces
|
|
343
|
-
removeNest: z.boolean().optional().describe("Set to true with _id to propose removal of the existing governance item"),
|
|
343
|
+
accountabilities: z.array(z.string()).optional().describe("Accountability titles to set on a role (replaces all — use children endpoint for individual management)"),
|
|
344
|
+
domains: z.array(z.string()).optional().describe("Domain titles to set on a role (replaces all — use children endpoint for individual management)"),
|
|
344
345
|
}),
|
|
345
346
|
modifyTensionPart: z.object({
|
|
346
347
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
347
348
|
tensionId: z.string().describe("Tension ID"),
|
|
348
349
|
partId: z.string().describe("Part ID to modify"),
|
|
349
350
|
title: z.string().optional().describe("Updated title"),
|
|
350
|
-
purpose: z.string().optional().describe("Updated purpose
|
|
351
|
-
description: z.string().optional().describe("Updated description
|
|
351
|
+
purpose: z.string().optional().describe("Updated purpose — aspirational future state. Most important for roles/circles. Supports HTML."),
|
|
352
|
+
description: z.string().optional().describe("Updated description — detailed information. Supports HTML."),
|
|
352
353
|
labels: z.array(z.string()).optional().describe("Updated labels"),
|
|
353
354
|
parentId: z.string().optional().describe("Updated parent ID"),
|
|
354
355
|
users: z.array(z.string()).optional().describe("Updated user assignments"),
|
|
355
356
|
due: z.string().optional().describe("Updated due date (ISO format)"),
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
domains: z.array(z.string()).optional().describe("Updated domains"),
|
|
357
|
+
accountabilities: z.array(z.string()).optional().describe("Updated accountabilities (replaces all — use children endpoint for individual management)"),
|
|
358
|
+
domains: z.array(z.string()).optional().describe("Updated domains (replaces all — use children endpoint for individual management)"),
|
|
359
359
|
}),
|
|
360
360
|
removeTensionPart: z.object({
|
|
361
361
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
362
362
|
tensionId: z.string().describe("Tension ID"),
|
|
363
363
|
partId: z.string().describe("Part ID to remove from the proposal"),
|
|
364
364
|
}),
|
|
365
|
+
getTensionPartChildren: z.object({
|
|
366
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
367
|
+
tensionId: z.string().describe("Tension ID"),
|
|
368
|
+
partId: z.string().describe("Part ID"),
|
|
369
|
+
}),
|
|
370
|
+
createTensionPartChild: z.object({
|
|
371
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
372
|
+
tensionId: z.string().describe("Tension ID"),
|
|
373
|
+
partId: z.string().describe("Part ID"),
|
|
374
|
+
title: z.string().describe("Title for the new accountability or domain"),
|
|
375
|
+
labels: z.array(z.string()).describe("Labels defining the type: ['accountability'] or ['domain']"),
|
|
376
|
+
}),
|
|
377
|
+
updateTensionPartChild: z.object({
|
|
378
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
379
|
+
tensionId: z.string().describe("Tension ID"),
|
|
380
|
+
partId: z.string().describe("Part ID"),
|
|
381
|
+
childId: z.string().describe("Child ID to update"),
|
|
382
|
+
title: z.string().describe("Updated title"),
|
|
383
|
+
}),
|
|
384
|
+
deleteTensionPartChild: z.object({
|
|
385
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
386
|
+
tensionId: z.string().describe("Tension ID"),
|
|
387
|
+
partId: z.string().describe("Part ID"),
|
|
388
|
+
childId: z.string().describe("Child ID to soft-delete (will remove the original accountability/domain when enacted)"),
|
|
389
|
+
}),
|
|
365
390
|
getTensionChanges: z.object({
|
|
366
391
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
367
392
|
tensionId: z.string().describe("Tension ID"),
|
|
@@ -376,6 +401,24 @@ export const schemas = {
|
|
|
376
401
|
tensionId: z.string().describe("Tension ID"),
|
|
377
402
|
status: z.enum(["proposed", "draft"]).describe("'proposed' to submit for voting, 'draft' to retract back to draft"),
|
|
378
403
|
}),
|
|
404
|
+
// Graph link tools
|
|
405
|
+
getGraphLinks: z.object({
|
|
406
|
+
nestId: z.string().describe("Nest ID to get graph links for"),
|
|
407
|
+
relation: z.string().describe("Relation name (e.g., 'meeting' for meeting agenda items)"),
|
|
408
|
+
direction: z.enum(["outgoing", "incoming"]).optional().describe("Link direction: 'outgoing' (default) = links FROM this nest, 'incoming' = links TO this nest"),
|
|
409
|
+
limit: z.number().optional().describe("Max results per page (default 50)"),
|
|
410
|
+
page: z.number().optional().describe("Page number for pagination"),
|
|
411
|
+
}),
|
|
412
|
+
addGraphLink: z.object({
|
|
413
|
+
nestId: z.string().describe("Source nest ID"),
|
|
414
|
+
relation: z.string().describe("Relation name (e.g., 'meeting' to link a tension to a meeting as an agenda item)"),
|
|
415
|
+
targetId: z.string().describe("Target nest ID to link to"),
|
|
416
|
+
}),
|
|
417
|
+
removeGraphLink: z.object({
|
|
418
|
+
nestId: z.string().describe("Source nest ID"),
|
|
419
|
+
relation: z.string().describe("Relation name (e.g., 'meeting')"),
|
|
420
|
+
targetId: z.string().describe("Target nest ID to unlink"),
|
|
421
|
+
}),
|
|
379
422
|
};
|
|
380
423
|
// Tool annotations for MCP - hints for clients on tool behavior
|
|
381
424
|
const readOnly = { annotations: { readOnlyHint: true, destructiveHint: false } };
|
|
@@ -474,6 +517,7 @@ export const toolDefinitions = [
|
|
|
474
517
|
properties: {
|
|
475
518
|
nestId: { type: "string", description: "Nest ID, or comma-separated IDs to fetch multiple nests at once (e.g., 'id1,id2,id3'). Keep total URL under 2000 chars." },
|
|
476
519
|
fieldsMetaData: { type: "boolean", description: "Set to true to include field schema metadata (available options, field types)" },
|
|
520
|
+
hints: { type: "boolean", description: "Include contextual hints (default: true). Set to false for bulk lookups where you only need structural data." },
|
|
477
521
|
stripDescription: { type: "boolean", description: "Set true to strip description fields from response, significantly reducing size." },
|
|
478
522
|
},
|
|
479
523
|
required: ["nestId"],
|
|
@@ -489,6 +533,7 @@ export const toolDefinitions = [
|
|
|
489
533
|
nestId: { type: "string", description: "Parent nest ID" },
|
|
490
534
|
limit: { type: "number", description: "Omit on first call to see meta.total count" },
|
|
491
535
|
page: { type: "number", description: "Page number (1-indexed)" },
|
|
536
|
+
hints: { type: "boolean", description: "Include contextual hints (default: true). Set to false for large result sets or bulk operations." },
|
|
492
537
|
stripDescription: { type: "boolean", description: "Set true to strip description fields from response, significantly reducing size. Ideal for bulk/index operations." },
|
|
493
538
|
_listTitle: { type: "string", description: "Short descriptive title for the list UI header (e.g., \"Tasks for Website Redesign\", \"API project sub-tasks\"). Include the parent name for context." },
|
|
494
539
|
},
|
|
@@ -505,8 +550,8 @@ export const toolDefinitions = [
|
|
|
505
550
|
properties: {
|
|
506
551
|
parentId: { type: "string", description: "Parent nest ID (workspace, circle, or project)" },
|
|
507
552
|
title: { type: "string", description: "Title of the new nest (plain text, HTML tags stripped)" },
|
|
508
|
-
purpose: { type: "string", description: "Purpose
|
|
509
|
-
description: { type: "string", description: "Detailed description
|
|
553
|
+
purpose: { type: "string", description: "Purpose — the aspirational future state this nest works towards. Most important for workspaces/circles/roles where it defines the north star and context boundary. For other nests, prefer description or fields — but purpose can be set if meaningful. Supports HTML." },
|
|
554
|
+
description: { type: "string", description: "Detailed description — primary field for nest information: project details, task context, acceptance criteria, DoD, etc. Use fields (e.g., project.status) for structured data and comments for progress updates. Supports HTML." },
|
|
510
555
|
labels: {
|
|
511
556
|
type: "array",
|
|
512
557
|
items: { type: "string" },
|
|
@@ -544,8 +589,8 @@ export const toolDefinitions = [
|
|
|
544
589
|
properties: {
|
|
545
590
|
nestId: { type: "string", description: "Nest ID to update" },
|
|
546
591
|
title: { type: "string", description: "New title (plain text, HTML tags stripped)" },
|
|
547
|
-
purpose: { type: "string", description: "New purpose
|
|
548
|
-
description: { type: "string", description: "New description
|
|
592
|
+
purpose: { type: "string", description: "New purpose — aspirational future state. Most important for workspaces/circles/roles. For other nests, prefer description or fields — but purpose can be set if meaningful. Supports HTML." },
|
|
593
|
+
description: { type: "string", description: "New description — primary field for nest information. Use for details, context, criteria. Use fields for structured data, comments for progress. Supports HTML." },
|
|
549
594
|
parentId: { type: "string", description: "New parent ID (move nest to different location)" },
|
|
550
595
|
labels: {
|
|
551
596
|
type: "array",
|
|
@@ -1127,11 +1172,11 @@ export const toolDefinitions = [
|
|
|
1127
1172
|
// Tension tools
|
|
1128
1173
|
{
|
|
1129
1174
|
name: "nestr_create_tension",
|
|
1130
|
-
description: "Create a new tension — the fundamental unit of inter-role communication. Tensions represent a gap between current reality and potential. Use for ALL cross-role communication: requesting information, sharing information, requesting outcomes/projects, requesting actions/tasks, or setting expectations (governance).
|
|
1175
|
+
description: "Create a new tension — the fundamental unit of inter-role communication. Tensions represent a gap between current reality and potential. Use for ALL cross-role communication: requesting information, sharing information, requesting outcomes/projects, requesting actions/tasks, or setting expectations (governance). Placement matters: use a role ID as nestId when that role is sensing the tension, or a circle ID for cross-role, governance, or personally sensed tensions.",
|
|
1131
1176
|
inputSchema: {
|
|
1132
1177
|
type: "object",
|
|
1133
1178
|
properties: {
|
|
1134
|
-
nestId: { type: "string", description: "ID of the
|
|
1179
|
+
nestId: { type: "string", description: "ID of the role or circle to create the tension on. Place on a role to indicate that role is sensing the tension. Place on a circle for cross-role or governance tensions (use individual-action label if sensed personally without role authority)." },
|
|
1135
1180
|
title: { type: "string", description: "The gap — what is the difference between current reality and desired state (plain text)" },
|
|
1136
1181
|
description: { type: "string", description: "The observable facts — what you see/hear/experience (supports HTML)" },
|
|
1137
1182
|
feeling: { type: "string", description: "The feeling this tension evokes — separated to keep the organizational response clean (plain text)" },
|
|
@@ -1216,11 +1261,13 @@ export const toolDefinitions = [
|
|
|
1216
1261
|
name: "nestr_add_tension_part",
|
|
1217
1262
|
description: `Add a governance change to a tension. Three modes based on input:
|
|
1218
1263
|
|
|
1219
|
-
**New item** (no _id): Propose creating a new governance item. Provide title and labels (e.g., ["role"], ["circle"], ["policy"], ["accountability"], ["domain"]). For roles, include accountabilities and/or domains.
|
|
1264
|
+
**New item** (no _id): Propose creating a new governance item. Provide title and labels (e.g., ["role"], ["circle"], ["policy"], ["accountability"], ["domain"]). For roles, include accountabilities and/or domains as bulk shorthand.
|
|
1265
|
+
|
|
1266
|
+
**Change existing item** (_id provided): Propose changes to an existing governance item. Provide the _id of the item plus fields to change. Supports title/purpose changes, restructuring (parentId to move between circles), conversions (labels to convert role↔circle), user assignment changes (for elections), and accountability/domain changes. When updating a role with _id, if accountabilities/domains arrays are not provided, existing children are auto-copied into the proposal — use nestr_get_tension_part_children to list them and manage individually.
|
|
1220
1267
|
|
|
1221
|
-
**
|
|
1268
|
+
**Remove existing item** (_id only, no other fields): Use nestr_remove_tension_part after adding the part, or use DELETE /parts to propose removal.
|
|
1222
1269
|
|
|
1223
|
-
|
|
1270
|
+
The accountabilities/domains arrays are bulk shorthand — they replace all children at once. For individual management (rename, add, remove single accountabilities/domains), use the tension part children tools instead.`,
|
|
1224
1271
|
inputSchema: {
|
|
1225
1272
|
type: "object",
|
|
1226
1273
|
properties: {
|
|
@@ -1234,9 +1281,8 @@ export const toolDefinitions = [
|
|
|
1234
1281
|
parentId: { type: "string", description: "Parent ID — use to move/restructure items (e.g., move role to different circle)" },
|
|
1235
1282
|
users: { type: "array", items: { type: "string" }, description: "User IDs to assign (e.g., for elections: assign elected user to the role)" },
|
|
1236
1283
|
due: { type: "string", description: "Due date / re-election date (ISO format)" },
|
|
1237
|
-
accountabilities: { type: "array", items: { type: "string" }, description: "Accountability titles to set on a role (replaces
|
|
1238
|
-
domains: { type: "array", items: { type: "string" }, description: "Domain titles to set on a role (replaces
|
|
1239
|
-
removeNest: { type: "boolean", description: "Set to true with _id to propose removal of the existing governance item" },
|
|
1284
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Accountability titles to set on a role (replaces all — use children endpoint for individual management)" },
|
|
1285
|
+
domains: { type: "array", items: { type: "string" }, description: "Domain titles to set on a role (replaces all — use children endpoint for individual management)" },
|
|
1240
1286
|
},
|
|
1241
1287
|
required: ["nestId", "tensionId"],
|
|
1242
1288
|
},
|
|
@@ -1244,7 +1290,7 @@ export const toolDefinitions = [
|
|
|
1244
1290
|
},
|
|
1245
1291
|
{
|
|
1246
1292
|
name: "nestr_modify_tension_part",
|
|
1247
|
-
description: "Modify an existing proposal part. Use to refine proposed values after initial creation — e.g., adjust a role's title or
|
|
1293
|
+
description: "Modify an existing proposal part. Use to refine proposed values after initial creation — e.g., adjust a role's title or purpose. For individual accountability/domain changes, prefer the children endpoint (nestr_get_tension_part_children, etc.).",
|
|
1248
1294
|
inputSchema: {
|
|
1249
1295
|
type: "object",
|
|
1250
1296
|
properties: {
|
|
@@ -1258,9 +1304,8 @@ export const toolDefinitions = [
|
|
|
1258
1304
|
parentId: { type: "string", description: "Updated parent ID" },
|
|
1259
1305
|
users: { type: "array", items: { type: "string" }, description: "Updated user assignments" },
|
|
1260
1306
|
due: { type: "string", description: "Updated due date (ISO format)" },
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
domains: { type: "array", items: { type: "string" }, description: "Updated domains" },
|
|
1307
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Updated accountabilities (replaces all — use children endpoint for individual management)" },
|
|
1308
|
+
domains: { type: "array", items: { type: "string" }, description: "Updated domains (replaces all — use children endpoint for individual management)" },
|
|
1264
1309
|
},
|
|
1265
1310
|
required: ["nestId", "tensionId", "partId"],
|
|
1266
1311
|
},
|
|
@@ -1268,7 +1313,7 @@ export const toolDefinitions = [
|
|
|
1268
1313
|
},
|
|
1269
1314
|
{
|
|
1270
1315
|
name: "nestr_remove_tension_part",
|
|
1271
|
-
description: "Remove a part from the proposal entirely
|
|
1316
|
+
description: "Remove a part from the proposal entirely, or propose deletion of a governance item. When used on a part that references an existing item (_id), this proposes removal of that governance item. When used on a part for a new item, it simply removes the proposal part.",
|
|
1272
1317
|
inputSchema: {
|
|
1273
1318
|
type: "object",
|
|
1274
1319
|
properties: {
|
|
@@ -1280,6 +1325,63 @@ export const toolDefinitions = [
|
|
|
1280
1325
|
},
|
|
1281
1326
|
...destructive,
|
|
1282
1327
|
},
|
|
1328
|
+
{
|
|
1329
|
+
name: "nestr_get_tension_part_children",
|
|
1330
|
+
description: "List children (accountabilities/domains) of a proposal part. When a part proposes changes to an existing role (_id), existing accountabilities/domains are auto-copied into the proposal. Use this to see them and then manage individually with create/update/delete children tools.",
|
|
1331
|
+
inputSchema: {
|
|
1332
|
+
type: "object",
|
|
1333
|
+
properties: {
|
|
1334
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1335
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1336
|
+
partId: { type: "string", description: "Part ID" },
|
|
1337
|
+
},
|
|
1338
|
+
required: ["nestId", "tensionId", "partId"],
|
|
1339
|
+
},
|
|
1340
|
+
},
|
|
1341
|
+
{
|
|
1342
|
+
name: "nestr_create_tension_part_child",
|
|
1343
|
+
description: "Add a new accountability or domain to a proposal part. When the proposal is enacted, this creates a new accountability/domain on the role.",
|
|
1344
|
+
inputSchema: {
|
|
1345
|
+
type: "object",
|
|
1346
|
+
properties: {
|
|
1347
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1348
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1349
|
+
partId: { type: "string", description: "Part ID" },
|
|
1350
|
+
title: { type: "string", description: "Title for the new accountability or domain" },
|
|
1351
|
+
labels: { type: "array", items: { type: "string" }, description: "Labels defining the type: ['accountability'] or ['domain']" },
|
|
1352
|
+
},
|
|
1353
|
+
required: ["nestId", "tensionId", "partId", "title", "labels"],
|
|
1354
|
+
},
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
name: "nestr_update_tension_part_child",
|
|
1358
|
+
description: "Rename an accountability or domain within a proposal part. When the proposal is enacted, the original accountability/domain is updated.",
|
|
1359
|
+
inputSchema: {
|
|
1360
|
+
type: "object",
|
|
1361
|
+
properties: {
|
|
1362
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1363
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1364
|
+
partId: { type: "string", description: "Part ID" },
|
|
1365
|
+
childId: { type: "string", description: "Child ID to update" },
|
|
1366
|
+
title: { type: "string", description: "Updated title" },
|
|
1367
|
+
},
|
|
1368
|
+
required: ["nestId", "tensionId", "partId", "childId", "title"],
|
|
1369
|
+
},
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
name: "nestr_delete_tension_part_child",
|
|
1373
|
+
description: "Soft-delete an accountability or domain from a proposal part. When the proposal is enacted, the original accountability/domain is removed from the role.",
|
|
1374
|
+
inputSchema: {
|
|
1375
|
+
type: "object",
|
|
1376
|
+
properties: {
|
|
1377
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1378
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1379
|
+
partId: { type: "string", description: "Part ID" },
|
|
1380
|
+
childId: { type: "string", description: "Child ID to soft-delete" },
|
|
1381
|
+
},
|
|
1382
|
+
required: ["nestId", "tensionId", "partId", "childId"],
|
|
1383
|
+
},
|
|
1384
|
+
},
|
|
1283
1385
|
{
|
|
1284
1386
|
name: "nestr_get_tension_changes",
|
|
1285
1387
|
description: "Get the namespaced diff for a proposal part. Returns { nestId, variable, newValue, oldValue } entries showing exactly what will change. Variables are namespaced: role.title, accountability.title, domain.title, policy.title, etc. For creates: oldValue is null. For deletes: newValue is null.",
|
|
@@ -1321,6 +1423,51 @@ export const toolDefinitions = [
|
|
|
1321
1423
|
},
|
|
1322
1424
|
...mutating,
|
|
1323
1425
|
},
|
|
1426
|
+
// Graph link tools
|
|
1427
|
+
{
|
|
1428
|
+
name: "nestr_get_graph_links",
|
|
1429
|
+
description: "Get nests linked via a named graph relation. Use relation 'meeting' on a meeting with direction 'incoming' to get its agenda items (linked tensions), or on a tension with direction 'outgoing' to see which meetings it's on. Supports pagination.",
|
|
1430
|
+
inputSchema: {
|
|
1431
|
+
type: "object",
|
|
1432
|
+
properties: {
|
|
1433
|
+
nestId: { type: "string", description: "Nest ID to get graph links for" },
|
|
1434
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting' for meeting agenda items)" },
|
|
1435
|
+
direction: { type: "string", enum: ["outgoing", "incoming"], description: "Link direction: 'outgoing' (default) = links FROM this nest, 'incoming' = links TO this nest" },
|
|
1436
|
+
limit: { type: "number", description: "Max results per page (default 50)" },
|
|
1437
|
+
page: { type: "number", description: "Page number for pagination" },
|
|
1438
|
+
},
|
|
1439
|
+
required: ["nestId", "relation"],
|
|
1440
|
+
},
|
|
1441
|
+
...readOnly,
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
name: "nestr_add_graph_link",
|
|
1445
|
+
description: "Create a bidirectional graph link between two nests. Primary use case: link a tension to a meeting as an agenda item using relation 'meeting' (nestId = tension, targetId = meeting). Links are bidirectional — queryable from either side.",
|
|
1446
|
+
inputSchema: {
|
|
1447
|
+
type: "object",
|
|
1448
|
+
properties: {
|
|
1449
|
+
nestId: { type: "string", description: "Source nest ID" },
|
|
1450
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting' to link a tension to a meeting)" },
|
|
1451
|
+
targetId: { type: "string", description: "Target nest ID to link to" },
|
|
1452
|
+
},
|
|
1453
|
+
required: ["nestId", "relation", "targetId"],
|
|
1454
|
+
},
|
|
1455
|
+
...mutating,
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
name: "nestr_remove_graph_link",
|
|
1459
|
+
description: "Remove a graph link between two nests. For example, remove a tension from a meeting's agenda by removing the 'meeting' relation.",
|
|
1460
|
+
inputSchema: {
|
|
1461
|
+
type: "object",
|
|
1462
|
+
properties: {
|
|
1463
|
+
nestId: { type: "string", description: "Source nest ID" },
|
|
1464
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting')" },
|
|
1465
|
+
targetId: { type: "string", description: "Target nest ID to unlink" },
|
|
1466
|
+
},
|
|
1467
|
+
required: ["nestId", "relation", "targetId"],
|
|
1468
|
+
},
|
|
1469
|
+
...destructive,
|
|
1470
|
+
},
|
|
1324
1471
|
];
|
|
1325
1472
|
// Strip description fields from nest objects in response data
|
|
1326
1473
|
function stripDescriptionFields(data) {
|
|
@@ -1399,6 +1546,7 @@ async function _handleToolCall(client, name, args) {
|
|
|
1399
1546
|
const nest = await client.getNest(parsed.nestId, {
|
|
1400
1547
|
cleanText: true,
|
|
1401
1548
|
fieldsMetaData: parsed.fieldsMetaData,
|
|
1549
|
+
hints: parsed.hints !== false,
|
|
1402
1550
|
});
|
|
1403
1551
|
return formatResult(nest);
|
|
1404
1552
|
}
|
|
@@ -1408,6 +1556,7 @@ async function _handleToolCall(client, name, args) {
|
|
|
1408
1556
|
limit: parsed.limit,
|
|
1409
1557
|
page: parsed.page,
|
|
1410
1558
|
cleanText: true,
|
|
1559
|
+
hints: parsed.hints !== false,
|
|
1411
1560
|
});
|
|
1412
1561
|
return formatResult(completableResponse(compactResponse(children), "children", parsed._listTitle || "Sub-items"));
|
|
1413
1562
|
}
|
|
@@ -1717,17 +1866,30 @@ async function _handleToolCall(client, name, args) {
|
|
|
1717
1866
|
case "nestr_get_me": {
|
|
1718
1867
|
const parsed = schemas.getMe.parse(args);
|
|
1719
1868
|
try {
|
|
1720
|
-
|
|
1869
|
+
let user = await client.getCurrentUser({
|
|
1721
1870
|
fullWorkspaces: parsed.fullWorkspaces,
|
|
1722
1871
|
});
|
|
1723
|
-
|
|
1872
|
+
// Guard against oversized responses (e.g. many workspaces with large adminUsers arrays).
|
|
1873
|
+
// If the serialized user exceeds 50KB, retry without fullWorkspaces to avoid
|
|
1874
|
+
// blowing past MCP client token limits.
|
|
1875
|
+
const MAX_USER_RESPONSE_BYTES = 50_000;
|
|
1876
|
+
let droppedFullWorkspaces = false;
|
|
1877
|
+
if (parsed.fullWorkspaces && JSON.stringify(user).length > MAX_USER_RESPONSE_BYTES) {
|
|
1878
|
+
user = await client.getCurrentUser({ fullWorkspaces: false });
|
|
1879
|
+
droppedFullWorkspaces = true;
|
|
1880
|
+
}
|
|
1881
|
+
const result = {
|
|
1724
1882
|
authMode: "oauth",
|
|
1725
1883
|
user,
|
|
1726
1884
|
mode: user.bot ? "role-filler" : "assistant",
|
|
1727
1885
|
hint: user.bot
|
|
1728
1886
|
? "You are a bot energizing roles. You have no authority as an agent — only through the roles you fill. Act autonomously within your roles' accountabilities. Process tensions proactively."
|
|
1729
1887
|
: "You are assisting a human who energizes roles. Defer to them for decisions. Help them articulate tensions and navigate governance.",
|
|
1730
|
-
}
|
|
1888
|
+
};
|
|
1889
|
+
if (droppedFullWorkspaces) {
|
|
1890
|
+
result.warning = "fullWorkspaces was dropped because the response exceeded the size limit. Use nestr_list_workspaces to browse workspaces individually.";
|
|
1891
|
+
}
|
|
1892
|
+
return formatResult(result);
|
|
1731
1893
|
}
|
|
1732
1894
|
catch (err) {
|
|
1733
1895
|
// If the error is from the tokenProvider (expired OAuth session),
|
|
@@ -1824,14 +1986,9 @@ async function _handleToolCall(client, name, args) {
|
|
|
1824
1986
|
}
|
|
1825
1987
|
case "nestr_add_tension_part": {
|
|
1826
1988
|
const parsed = schemas.addTensionPart.parse(args);
|
|
1827
|
-
const { nestId, tensionId,
|
|
1828
|
-
if (body._id
|
|
1829
|
-
// Propose
|
|
1830
|
-
const part = await client.proposeTensionRemoval(nestId, tensionId, { _id: body._id });
|
|
1831
|
-
return formatResult({ message: "Removal proposal added successfully", part });
|
|
1832
|
-
}
|
|
1833
|
-
else if (body._id) {
|
|
1834
|
-
// Propose change to existing item
|
|
1989
|
+
const { nestId, tensionId, ...body } = parsed;
|
|
1990
|
+
if (body._id) {
|
|
1991
|
+
// Propose change to existing item (existing children auto-copied if accountabilities/domains not provided)
|
|
1835
1992
|
const part = await client.proposeTensionChange(nestId, tensionId, body);
|
|
1836
1993
|
return formatResult({ message: "Change proposal added successfully", part });
|
|
1837
1994
|
}
|
|
@@ -1852,6 +2009,26 @@ async function _handleToolCall(client, name, args) {
|
|
|
1852
2009
|
await client.removeTensionPart(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
1853
2010
|
return formatResult({ message: `Tension part ${parsed.partId} removed successfully` });
|
|
1854
2011
|
}
|
|
2012
|
+
case "nestr_get_tension_part_children": {
|
|
2013
|
+
const parsed = schemas.getTensionPartChildren.parse(args);
|
|
2014
|
+
const children = await client.getTensionPartChildren(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
2015
|
+
return formatResult(children);
|
|
2016
|
+
}
|
|
2017
|
+
case "nestr_create_tension_part_child": {
|
|
2018
|
+
const parsed = schemas.createTensionPartChild.parse(args);
|
|
2019
|
+
const child = await client.createTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, { title: parsed.title, labels: parsed.labels });
|
|
2020
|
+
return formatResult({ message: "Child created successfully", child });
|
|
2021
|
+
}
|
|
2022
|
+
case "nestr_update_tension_part_child": {
|
|
2023
|
+
const parsed = schemas.updateTensionPartChild.parse(args);
|
|
2024
|
+
const child = await client.updateTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, parsed.childId, { title: parsed.title });
|
|
2025
|
+
return formatResult({ message: "Child updated successfully", child });
|
|
2026
|
+
}
|
|
2027
|
+
case "nestr_delete_tension_part_child": {
|
|
2028
|
+
const parsed = schemas.deleteTensionPartChild.parse(args);
|
|
2029
|
+
await client.deleteTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, parsed.childId);
|
|
2030
|
+
return formatResult({ message: `Child ${parsed.childId} soft-deleted successfully` });
|
|
2031
|
+
}
|
|
1855
2032
|
case "nestr_get_tension_changes": {
|
|
1856
2033
|
const parsed = schemas.getTensionChanges.parse(args);
|
|
1857
2034
|
const changes = await client.getTensionPartChanges(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
@@ -1867,6 +2044,26 @@ async function _handleToolCall(client, name, args) {
|
|
|
1867
2044
|
const status = await client.updateTensionStatus(parsed.nestId, parsed.tensionId, parsed.status);
|
|
1868
2045
|
return formatResult({ message: `Tension status updated to '${parsed.status}'`, status });
|
|
1869
2046
|
}
|
|
2047
|
+
// Graph link tools
|
|
2048
|
+
case "nestr_get_graph_links": {
|
|
2049
|
+
const parsed = schemas.getGraphLinks.parse(args);
|
|
2050
|
+
const result = await client.getGraphLinks(parsed.nestId, parsed.relation, {
|
|
2051
|
+
direction: parsed.direction,
|
|
2052
|
+
limit: parsed.limit,
|
|
2053
|
+
page: parsed.page,
|
|
2054
|
+
});
|
|
2055
|
+
return formatResult(compactResponse(result));
|
|
2056
|
+
}
|
|
2057
|
+
case "nestr_add_graph_link": {
|
|
2058
|
+
const parsed = schemas.addGraphLink.parse(args);
|
|
2059
|
+
const result = await client.addGraphLink(parsed.nestId, parsed.relation, parsed.targetId);
|
|
2060
|
+
return formatResult(result);
|
|
2061
|
+
}
|
|
2062
|
+
case "nestr_remove_graph_link": {
|
|
2063
|
+
const parsed = schemas.removeGraphLink.parse(args);
|
|
2064
|
+
const result = await client.removeGraphLink(parsed.nestId, parsed.relation, parsed.targetId);
|
|
2065
|
+
return formatResult({ message: "Graph link removed" });
|
|
2066
|
+
}
|
|
1870
2067
|
default:
|
|
1871
2068
|
return formatError({
|
|
1872
2069
|
error: true,
|