@nestr/mcp 0.1.35 → 0.1.36
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/build/api/client.d.ts +79 -0
- package/build/api/client.d.ts.map +1 -1
- package/build/api/client.js +134 -1
- package/build/api/client.js.map +1 -1
- package/build/apps/index.js +1 -1
- package/build/http.d.ts +5 -0
- package/build/http.d.ts.map +1 -1
- package/build/http.js +27 -2
- package/build/http.js.map +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +506 -85
- package/build/server.js.map +1 -1
- package/build/tools/index.d.ts +1759 -60
- package/build/tools/index.d.ts.map +1 -1
- package/build/tools/index.js +518 -6
- package/build/tools/index.js.map +1 -1
- package/package.json +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,EAAkC,MAAM,kBAAkB,CAAC;AA+EnG,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,EAAkC,MAAM,kBAAkB,CAAC;AA+EnG,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2UnB,CAAC;AAGF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmxB3B,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
|
@@ -118,7 +118,7 @@ export const schemas = {
|
|
|
118
118
|
labels: z.array(z.string()).optional().describe("Label IDs to set (e.g., ['project'] to convert an item into a project)"),
|
|
119
119
|
fields: z.record(z.unknown()).optional().describe("Field updates (e.g., { 'project.status': 'Current' })"),
|
|
120
120
|
users: z.array(z.string()).optional().describe("User IDs to assign"),
|
|
121
|
-
data: z.record(z.unknown()).optional().describe("
|
|
121
|
+
data: z.record(z.unknown()).optional().describe("Key-value data store shared with Nestr internals — never overwrite existing keys. Namespace your own data under 'mcp.' (e.g., { 'mcp.lastSync': '...' }). For AI knowledge persistence, use skills instead."),
|
|
122
122
|
due: z.string().optional().describe("Due date (ISO format). For projects/tasks: deadline. For roles: re-election date. For meetings: start time."),
|
|
123
123
|
completed: z.boolean().optional().describe("Mark task as completed (root-level field, not in fields). Note: Projects use fields['project.status'] = 'Done' instead."),
|
|
124
124
|
}),
|
|
@@ -129,6 +129,13 @@ export const schemas = {
|
|
|
129
129
|
nestId: z.string().describe("Nest ID to comment on"),
|
|
130
130
|
body: z.string().describe("Comment text (supports HTML and @mentions)"),
|
|
131
131
|
}),
|
|
132
|
+
updateComment: z.object({
|
|
133
|
+
commentId: z.string().describe("Comment ID to update"),
|
|
134
|
+
body: z.string().describe("Updated comment text (supports HTML and @mentions)"),
|
|
135
|
+
}),
|
|
136
|
+
deleteComment: z.object({
|
|
137
|
+
commentId: z.string().describe("Comment ID to delete"),
|
|
138
|
+
}),
|
|
132
139
|
listCircles: z.object({
|
|
133
140
|
workspaceId: z.string().describe("Workspace ID"),
|
|
134
141
|
limit: z.number().optional().describe("Max results per page. Omit to see full count in meta.total."),
|
|
@@ -179,6 +186,12 @@ export const schemas = {
|
|
|
179
186
|
workspaceId: z.string().describe("Workspace ID"),
|
|
180
187
|
userId: z.string().describe("User ID"),
|
|
181
188
|
}),
|
|
189
|
+
addWorkspaceUser: z.object({
|
|
190
|
+
workspaceId: z.string().describe("Workspace ID"),
|
|
191
|
+
username: z.string().describe("Email address of the user to add"),
|
|
192
|
+
fullName: z.string().optional().describe("Full name of the user (used when creating a new account)"),
|
|
193
|
+
language: z.string().optional().describe("Language preference (e.g., 'en', 'nl', 'de')"),
|
|
194
|
+
}),
|
|
182
195
|
getLabel: z.object({
|
|
183
196
|
workspaceId: z.string().describe("Workspace ID"),
|
|
184
197
|
labelId: z.string().describe("Label ID"),
|
|
@@ -239,6 +252,98 @@ export const schemas = {
|
|
|
239
252
|
}),
|
|
240
253
|
// Daily plan (requires OAuth token)
|
|
241
254
|
getDailyPlan: z.object({}),
|
|
255
|
+
// Current user identity (requires OAuth token)
|
|
256
|
+
getMe: z.object({}),
|
|
257
|
+
// User tension tools (requires OAuth token)
|
|
258
|
+
listMyTensions: z.object({
|
|
259
|
+
context: z.string().optional().describe("Optional context filter (e.g., workspace ID or circle ID)"),
|
|
260
|
+
}),
|
|
261
|
+
listTensionsAwaitingConsent: z.object({
|
|
262
|
+
context: z.string().optional().describe("Optional context filter (e.g., workspace ID or circle ID)"),
|
|
263
|
+
}),
|
|
264
|
+
// Tension tools
|
|
265
|
+
createTension: z.object({
|
|
266
|
+
nestId: z.string().describe("ID of the circle or role to create the tension on"),
|
|
267
|
+
title: z.string().describe("The gap you're sensing — what is the difference between current reality and desired state (plain text)"),
|
|
268
|
+
description: z.string().optional().describe("The observable facts — what you see/hear/experience that creates this tension (supports HTML)"),
|
|
269
|
+
feeling: z.string().optional().describe("The feeling this tension evokes in you — separated from the facts to keep the organizational response clean (plain text)"),
|
|
270
|
+
needs: z.string().optional().describe("The personal or organizational need that is alive — what need is not being met (plain text)"),
|
|
271
|
+
}),
|
|
272
|
+
getTension: z.object({
|
|
273
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
274
|
+
tensionId: z.string().describe("Tension ID"),
|
|
275
|
+
}),
|
|
276
|
+
listTensions: z.object({
|
|
277
|
+
nestId: z.string().describe("ID of the circle or role to list tensions for"),
|
|
278
|
+
search: z.string().optional().describe("Search query to filter tensions"),
|
|
279
|
+
limit: z.number().optional().describe("Max results to return"),
|
|
280
|
+
order: z.string().optional().describe("Sort order (e.g., 'createdAt', '-createdAt')"),
|
|
281
|
+
}),
|
|
282
|
+
updateTension: z.object({
|
|
283
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
284
|
+
tensionId: z.string().describe("Tension ID"),
|
|
285
|
+
title: z.string().optional().describe("Updated title — the gap being sensed (plain text)"),
|
|
286
|
+
description: z.string().optional().describe("Updated description — the observable facts (supports HTML)"),
|
|
287
|
+
feeling: z.string().optional().describe("Updated feeling this tension evokes (plain text)"),
|
|
288
|
+
needs: z.string().optional().describe("Updated need that is alive (plain text)"),
|
|
289
|
+
}),
|
|
290
|
+
deleteTension: z.object({
|
|
291
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
292
|
+
tensionId: z.string().describe("Tension ID to delete"),
|
|
293
|
+
}),
|
|
294
|
+
getTensionParts: z.object({
|
|
295
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
296
|
+
tensionId: z.string().describe("Tension ID"),
|
|
297
|
+
}),
|
|
298
|
+
addTensionPart: z.object({
|
|
299
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
300
|
+
tensionId: z.string().describe("Tension ID"),
|
|
301
|
+
_id: z.string().optional().describe("ID of an existing governance item to change or remove. Omit to propose a new item."),
|
|
302
|
+
title: z.string().optional().describe("Title for the governance item"),
|
|
303
|
+
labels: z.array(z.string()).optional().describe("Labels defining the item type (e.g., ['role'], ['circle'], ['policy'], ['accountability'], ['domain'])"),
|
|
304
|
+
purpose: z.string().optional().describe("Purpose of the item (supports HTML)"),
|
|
305
|
+
description: z.string().optional().describe("Description (supports HTML)"),
|
|
306
|
+
parentId: z.string().optional().describe("Parent ID — use to move/restructure items (e.g., move role to different circle)"),
|
|
307
|
+
users: z.array(z.string()).optional().describe("User IDs to assign (e.g., for role elections: assign the elected user to the role)"),
|
|
308
|
+
due: z.string().optional().describe("Due date / re-election date (ISO format)"),
|
|
309
|
+
accountabilities: z.array(z.string()).optional().describe("Accountability titles to set on a role (replaces existing)"),
|
|
310
|
+
domains: z.array(z.string()).optional().describe("Domain titles to set on a role (replaces existing)"),
|
|
311
|
+
removeNest: z.boolean().optional().describe("Set to true with _id to propose removal of the existing governance item"),
|
|
312
|
+
}),
|
|
313
|
+
modifyTensionPart: z.object({
|
|
314
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
315
|
+
tensionId: z.string().describe("Tension ID"),
|
|
316
|
+
partId: z.string().describe("Part ID to modify"),
|
|
317
|
+
title: z.string().optional().describe("Updated title"),
|
|
318
|
+
purpose: z.string().optional().describe("Updated purpose (supports HTML)"),
|
|
319
|
+
description: z.string().optional().describe("Updated description (supports HTML)"),
|
|
320
|
+
labels: z.array(z.string()).optional().describe("Updated labels"),
|
|
321
|
+
parentId: z.string().optional().describe("Updated parent ID"),
|
|
322
|
+
users: z.array(z.string()).optional().describe("Updated user assignments"),
|
|
323
|
+
due: z.string().optional().describe("Updated due date (ISO format)"),
|
|
324
|
+
removeNest: z.boolean().optional().describe("Change removal flag"),
|
|
325
|
+
accountabilities: z.array(z.string()).optional().describe("Updated accountabilities"),
|
|
326
|
+
domains: z.array(z.string()).optional().describe("Updated domains"),
|
|
327
|
+
}),
|
|
328
|
+
removeTensionPart: z.object({
|
|
329
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
330
|
+
tensionId: z.string().describe("Tension ID"),
|
|
331
|
+
partId: z.string().describe("Part ID to remove from the proposal"),
|
|
332
|
+
}),
|
|
333
|
+
getTensionChanges: z.object({
|
|
334
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
335
|
+
tensionId: z.string().describe("Tension ID"),
|
|
336
|
+
partId: z.string().describe("Part ID to get changes for"),
|
|
337
|
+
}),
|
|
338
|
+
getTensionStatus: z.object({
|
|
339
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
340
|
+
tensionId: z.string().describe("Tension ID"),
|
|
341
|
+
}),
|
|
342
|
+
updateTensionStatus: z.object({
|
|
343
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
344
|
+
tensionId: z.string().describe("Tension ID"),
|
|
345
|
+
status: z.enum(["proposed", "draft"]).describe("'proposed' to submit for voting, 'draft' to retract back to draft"),
|
|
346
|
+
}),
|
|
242
347
|
};
|
|
243
348
|
// Tool definitions for MCP
|
|
244
349
|
export const toolDefinitions = [
|
|
@@ -388,7 +493,7 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
388
493
|
},
|
|
389
494
|
{
|
|
390
495
|
name: "nestr_update_nest",
|
|
391
|
-
description: "Update properties of an existing nest. Use parentId to move a nest (e.g., inbox item to a project).
|
|
496
|
+
description: "Update properties of an existing nest. Use parentId to move a nest (e.g., inbox item to a project). For AI knowledge persistence, create skill-labeled nests under roles/circles instead of using data fields.",
|
|
392
497
|
inputSchema: {
|
|
393
498
|
type: "object",
|
|
394
499
|
properties: {
|
|
@@ -413,7 +518,7 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
413
518
|
},
|
|
414
519
|
data: {
|
|
415
520
|
type: "object",
|
|
416
|
-
description: "
|
|
521
|
+
description: "Key-value data store shared with Nestr internals — never overwrite existing keys. Namespace your own data under 'mcp.' (e.g., { 'mcp.lastSync': '...' }). For AI knowledge persistence, use skills instead.",
|
|
417
522
|
},
|
|
418
523
|
due: {
|
|
419
524
|
type: "string",
|
|
@@ -450,6 +555,29 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
450
555
|
required: ["nestId", "body"],
|
|
451
556
|
},
|
|
452
557
|
},
|
|
558
|
+
{
|
|
559
|
+
name: "nestr_update_comment",
|
|
560
|
+
description: "Update an existing comment's text.",
|
|
561
|
+
inputSchema: {
|
|
562
|
+
type: "object",
|
|
563
|
+
properties: {
|
|
564
|
+
commentId: { type: "string", description: "Comment ID to update" },
|
|
565
|
+
body: { type: "string", description: "Updated comment text (supports HTML and @mentions)" },
|
|
566
|
+
},
|
|
567
|
+
required: ["commentId", "body"],
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
name: "nestr_delete_comment",
|
|
572
|
+
description: "Delete a comment (soft delete).",
|
|
573
|
+
inputSchema: {
|
|
574
|
+
type: "object",
|
|
575
|
+
properties: {
|
|
576
|
+
commentId: { type: "string", description: "Comment ID to delete" },
|
|
577
|
+
},
|
|
578
|
+
required: ["commentId"],
|
|
579
|
+
},
|
|
580
|
+
},
|
|
453
581
|
{
|
|
454
582
|
name: "nestr_list_circles",
|
|
455
583
|
description: "List all circles (teams/departments) in a workspace. Response includes meta.total showing total matching count.",
|
|
@@ -586,6 +714,25 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
586
714
|
required: ["workspaceId", "userId"],
|
|
587
715
|
},
|
|
588
716
|
},
|
|
717
|
+
{
|
|
718
|
+
name: "nestr_add_workspace_user",
|
|
719
|
+
description: `Add a user to a workspace by email address. If the user already has a Nestr account, they are added to the workspace. If not, a new account is created and they receive an invitation email.
|
|
720
|
+
|
|
721
|
+
**Requirements:**
|
|
722
|
+
- Caller must be a workspace admin (user-scoped key) or use a workspace API key
|
|
723
|
+
- If the user does not yet have a Nestr account, the email domain must be associated with and verified for the workspace — otherwise provisioning will fail with a 405 error
|
|
724
|
+
- If the user already exists in Nestr, they can be added regardless of domain`,
|
|
725
|
+
inputSchema: {
|
|
726
|
+
type: "object",
|
|
727
|
+
properties: {
|
|
728
|
+
workspaceId: { type: "string", description: "Workspace ID" },
|
|
729
|
+
username: { type: "string", description: "Email address of the user to add" },
|
|
730
|
+
fullName: { type: "string", description: "Full name (for new accounts)" },
|
|
731
|
+
language: { type: "string", description: "Language preference (e.g., 'en', 'nl')" },
|
|
732
|
+
},
|
|
733
|
+
required: ["workspaceId", "username"],
|
|
734
|
+
},
|
|
735
|
+
},
|
|
589
736
|
{
|
|
590
737
|
name: "nestr_get_label",
|
|
591
738
|
description: "Get details of a specific label. Labels define what type a nest is (e.g., 'project', 'todo', 'role', 'circle', 'meeting').",
|
|
@@ -627,7 +774,7 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
627
774
|
// Inbox tools (require OAuth token - won't work with workspace API keys)
|
|
628
775
|
{
|
|
629
776
|
name: "nestr_list_inbox",
|
|
630
|
-
description: "List items in the user's inbox. The inbox
|
|
777
|
+
description: "List items in the user's personal inbox. The inbox holds unprocessed 'stuff' — sensed tensions, ideas, and captured items that haven't yet been differentiated into role work or personal projects. Spans all workspaces in scope. Requires OAuth token.",
|
|
631
778
|
inputSchema: {
|
|
632
779
|
type: "object",
|
|
633
780
|
properties: {
|
|
@@ -639,7 +786,7 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
639
786
|
},
|
|
640
787
|
{
|
|
641
788
|
name: "nestr_create_inbox_item",
|
|
642
|
-
description: "Quick capture: add an item to the user's inbox for later processing. Use for capturing
|
|
789
|
+
description: "Quick capture: add an item to the user's personal inbox for later processing. Use for capturing sensed tensions, thoughts, or ideas before deciding which workspace, role, or personal context they belong to. Requires OAuth token.",
|
|
643
790
|
inputSchema: {
|
|
644
791
|
type: "object",
|
|
645
792
|
properties: {
|
|
@@ -760,7 +907,7 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
760
907
|
// Daily plan (requires OAuth token)
|
|
761
908
|
{
|
|
762
909
|
name: "nestr_get_daily_plan",
|
|
763
|
-
description: "Get the user's daily plan - items marked for 'today'. Returns todos and projects
|
|
910
|
+
description: "Get the user's personal daily plan - items marked for 'today'. Returns todos and projects across all contexts: role work from any workspace, personal projects, errands, or anything else the user has chosen to focus on today. Spans all workspaces in scope. Note: Token scope may limit which workspaces are included. Requires OAuth token.",
|
|
764
911
|
inputSchema: {
|
|
765
912
|
type: "object",
|
|
766
913
|
properties: {
|
|
@@ -769,6 +916,221 @@ Requires user-scoped authentication (OAuth token or personal API key with user s
|
|
|
769
916
|
},
|
|
770
917
|
_meta: completableListUi,
|
|
771
918
|
},
|
|
919
|
+
// Current user identity
|
|
920
|
+
{
|
|
921
|
+
name: "nestr_get_me",
|
|
922
|
+
description: "Get the current authenticated identity and operating mode. Returns user info including `bot: true` if the agent energizes roles directly (role-filler mode) or absent/false if assisting a human who energizes roles. Returns `authMode: 'api-key'` when using a workspace API key (no user identity, no user-scoped features). Call at session start to determine how to behave. Requires OAuth token for full user info; gracefully handles API key auth.",
|
|
923
|
+
inputSchema: {
|
|
924
|
+
type: "object",
|
|
925
|
+
properties: {},
|
|
926
|
+
},
|
|
927
|
+
},
|
|
928
|
+
// User tension tools (requires OAuth token)
|
|
929
|
+
{
|
|
930
|
+
name: "nestr_list_my_tensions",
|
|
931
|
+
description: "List tensions created by or assigned to the current user. Tensions are the primary communication mechanism between roles — check at natural breakpoints: session start, after completing work, when user asks what to do next. Returns both authored and assigned tensions across all workspaces. Requires OAuth token.",
|
|
932
|
+
inputSchema: {
|
|
933
|
+
type: "object",
|
|
934
|
+
properties: {
|
|
935
|
+
context: { type: "string", description: "Optional context filter (e.g., workspace ID or circle ID)" },
|
|
936
|
+
},
|
|
937
|
+
},
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
name: "nestr_list_tensions_awaiting_consent",
|
|
941
|
+
description: "List tensions awaiting the current user's consent vote. Returns governance proposals and other tensions that need the user's input. Check proactively — unprocessed tensions block organizational progress. Requires OAuth token.",
|
|
942
|
+
inputSchema: {
|
|
943
|
+
type: "object",
|
|
944
|
+
properties: {
|
|
945
|
+
context: { type: "string", description: "Optional context filter (e.g., workspace ID or circle ID)" },
|
|
946
|
+
},
|
|
947
|
+
},
|
|
948
|
+
},
|
|
949
|
+
// Tension tools
|
|
950
|
+
{
|
|
951
|
+
name: "nestr_create_tension",
|
|
952
|
+
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). The parent nest must be a role, circle, or anchor-circle.",
|
|
953
|
+
inputSchema: {
|
|
954
|
+
type: "object",
|
|
955
|
+
properties: {
|
|
956
|
+
nestId: { type: "string", description: "ID of the circle or role to create the tension on" },
|
|
957
|
+
title: { type: "string", description: "The gap — what is the difference between current reality and desired state (plain text)" },
|
|
958
|
+
description: { type: "string", description: "The observable facts — what you see/hear/experience (supports HTML)" },
|
|
959
|
+
feeling: { type: "string", description: "The feeling this tension evokes — separated to keep the organizational response clean (plain text)" },
|
|
960
|
+
needs: { type: "string", description: "The need that is alive — what personal or organizational need is not being met (plain text)" },
|
|
961
|
+
},
|
|
962
|
+
required: ["nestId", "title"],
|
|
963
|
+
},
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
name: "nestr_get_tension",
|
|
967
|
+
description: "Get a single tension including its current status (draft/proposed/accepted/objected). Use nestr_get_tension_status for detailed per-user voting responses.",
|
|
968
|
+
inputSchema: {
|
|
969
|
+
type: "object",
|
|
970
|
+
properties: {
|
|
971
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
972
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
973
|
+
},
|
|
974
|
+
required: ["nestId", "tensionId"],
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
name: "nestr_list_tensions",
|
|
979
|
+
description: "List tensions for a circle or role. Supports search query filtering. Use to find existing governance proposals or pending decisions.",
|
|
980
|
+
inputSchema: {
|
|
981
|
+
type: "object",
|
|
982
|
+
properties: {
|
|
983
|
+
nestId: { type: "string", description: "ID of the circle or role to list tensions for" },
|
|
984
|
+
search: { type: "string", description: "Search query to filter tensions" },
|
|
985
|
+
limit: { type: "number", description: "Max results to return" },
|
|
986
|
+
order: { type: "string", description: "Sort order (e.g., 'createdAt', '-createdAt')" },
|
|
987
|
+
},
|
|
988
|
+
required: ["nestId"],
|
|
989
|
+
},
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
name: "nestr_update_tension",
|
|
993
|
+
description: "Update a tension's title, description, feeling, or needs. Use to refine the tension statement or add personal context before adding proposal parts.",
|
|
994
|
+
inputSchema: {
|
|
995
|
+
type: "object",
|
|
996
|
+
properties: {
|
|
997
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
998
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
999
|
+
title: { type: "string", description: "Updated title — the gap being sensed (plain text)" },
|
|
1000
|
+
description: { type: "string", description: "Updated description — the observable facts (supports HTML)" },
|
|
1001
|
+
feeling: { type: "string", description: "Updated feeling this tension evokes (plain text)" },
|
|
1002
|
+
needs: { type: "string", description: "Updated need that is alive (plain text)" },
|
|
1003
|
+
},
|
|
1004
|
+
required: ["nestId", "tensionId"],
|
|
1005
|
+
},
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
name: "nestr_delete_tension",
|
|
1009
|
+
description: "Delete a tension (soft delete). Use when a tension is no longer relevant or was created in error.",
|
|
1010
|
+
inputSchema: {
|
|
1011
|
+
type: "object",
|
|
1012
|
+
properties: {
|
|
1013
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1014
|
+
tensionId: { type: "string", description: "Tension ID to delete" },
|
|
1015
|
+
},
|
|
1016
|
+
required: ["nestId", "tensionId"],
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
name: "nestr_get_tension_parts",
|
|
1021
|
+
description: "Get all parts of a tension. Each part contains items representing proposed governance changes (with action: create/update/delete/role2circle/circle2role). Review parts to understand what a tension proposes before submitting.",
|
|
1022
|
+
inputSchema: {
|
|
1023
|
+
type: "object",
|
|
1024
|
+
properties: {
|
|
1025
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1026
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1027
|
+
},
|
|
1028
|
+
required: ["nestId", "tensionId"],
|
|
1029
|
+
},
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
name: "nestr_add_tension_part",
|
|
1033
|
+
description: `Add a governance change to a tension. Three modes based on input:
|
|
1034
|
+
|
|
1035
|
+
**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.
|
|
1036
|
+
|
|
1037
|
+
**Change existing item** (_id provided, no removeNest): 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.
|
|
1038
|
+
|
|
1039
|
+
**Remove existing item** (_id + removeNest: true): Propose removal of an existing governance item.`,
|
|
1040
|
+
inputSchema: {
|
|
1041
|
+
type: "object",
|
|
1042
|
+
properties: {
|
|
1043
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1044
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1045
|
+
_id: { type: "string", description: "ID of an existing governance item to change or remove. Omit to propose a new item." },
|
|
1046
|
+
title: { type: "string", description: "Title for the governance item" },
|
|
1047
|
+
labels: { type: "array", items: { type: "string" }, description: "Labels defining the item type (e.g., ['role'], ['circle'], ['policy'], ['accountability'], ['domain'])" },
|
|
1048
|
+
purpose: { type: "string", description: "Purpose of the item (supports HTML)" },
|
|
1049
|
+
description: { type: "string", description: "Description (supports HTML)" },
|
|
1050
|
+
parentId: { type: "string", description: "Parent ID — use to move/restructure items (e.g., move role to different circle)" },
|
|
1051
|
+
users: { type: "array", items: { type: "string" }, description: "User IDs to assign (e.g., for elections: assign elected user to the role)" },
|
|
1052
|
+
due: { type: "string", description: "Due date / re-election date (ISO format)" },
|
|
1053
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Accountability titles to set on a role (replaces existing)" },
|
|
1054
|
+
domains: { type: "array", items: { type: "string" }, description: "Domain titles to set on a role (replaces existing)" },
|
|
1055
|
+
removeNest: { type: "boolean", description: "Set to true with _id to propose removal of the existing governance item" },
|
|
1056
|
+
},
|
|
1057
|
+
required: ["nestId", "tensionId"],
|
|
1058
|
+
},
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
name: "nestr_modify_tension_part",
|
|
1062
|
+
description: "Modify an existing proposal part. Use to refine proposed values after initial creation — e.g., adjust a role's title or add accountabilities to a proposed role.",
|
|
1063
|
+
inputSchema: {
|
|
1064
|
+
type: "object",
|
|
1065
|
+
properties: {
|
|
1066
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1067
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1068
|
+
partId: { type: "string", description: "Part ID to modify" },
|
|
1069
|
+
title: { type: "string", description: "Updated title" },
|
|
1070
|
+
purpose: { type: "string", description: "Updated purpose (supports HTML)" },
|
|
1071
|
+
description: { type: "string", description: "Updated description (supports HTML)" },
|
|
1072
|
+
labels: { type: "array", items: { type: "string" }, description: "Updated labels" },
|
|
1073
|
+
parentId: { type: "string", description: "Updated parent ID" },
|
|
1074
|
+
users: { type: "array", items: { type: "string" }, description: "Updated user assignments" },
|
|
1075
|
+
due: { type: "string", description: "Updated due date (ISO format)" },
|
|
1076
|
+
removeNest: { type: "boolean", description: "Change removal flag" },
|
|
1077
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Updated accountabilities" },
|
|
1078
|
+
domains: { type: "array", items: { type: "string" }, description: "Updated domains" },
|
|
1079
|
+
},
|
|
1080
|
+
required: ["nestId", "tensionId", "partId"],
|
|
1081
|
+
},
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
name: "nestr_remove_tension_part",
|
|
1085
|
+
description: "Remove a part from the proposal entirely. This does NOT propose deletion of a governance item — it removes the proposal part itself. Use nestr_add_tension_part with removeNest:true to propose deleting a governance item.",
|
|
1086
|
+
inputSchema: {
|
|
1087
|
+
type: "object",
|
|
1088
|
+
properties: {
|
|
1089
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1090
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1091
|
+
partId: { type: "string", description: "Part ID to remove from the proposal" },
|
|
1092
|
+
},
|
|
1093
|
+
required: ["nestId", "tensionId", "partId"],
|
|
1094
|
+
},
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
name: "nestr_get_tension_changes",
|
|
1098
|
+
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.",
|
|
1099
|
+
inputSchema: {
|
|
1100
|
+
type: "object",
|
|
1101
|
+
properties: {
|
|
1102
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1103
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1104
|
+
partId: { type: "string", description: "Part ID to get changes for" },
|
|
1105
|
+
},
|
|
1106
|
+
required: ["nestId", "tensionId", "partId"],
|
|
1107
|
+
},
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
name: "nestr_get_tension_status",
|
|
1111
|
+
description: "Get detailed status of a tension including per-user voting responses. Returns status (draft/proposed/accepted/objected), individual responses with timestamps, and auto-approval date if set. Use this to check who has voted and the current decision state.",
|
|
1112
|
+
inputSchema: {
|
|
1113
|
+
type: "object",
|
|
1114
|
+
properties: {
|
|
1115
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1116
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1117
|
+
},
|
|
1118
|
+
required: ["nestId", "tensionId"],
|
|
1119
|
+
},
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
name: "nestr_update_tension_status",
|
|
1123
|
+
description: "Submit a tension for voting (set to 'proposed') or retract it back to draft. Submitting triggers the async consent/voting process — circle members are notified and can accept or object. Retracting returns it to draft for further editing.",
|
|
1124
|
+
inputSchema: {
|
|
1125
|
+
type: "object",
|
|
1126
|
+
properties: {
|
|
1127
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1128
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1129
|
+
status: { type: "string", enum: ["proposed", "draft"], description: "'proposed' to submit for voting, 'draft' to retract back to draft" },
|
|
1130
|
+
},
|
|
1131
|
+
required: ["nestId", "tensionId", "status"],
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
772
1134
|
];
|
|
773
1135
|
// Strip description fields from nest objects in response data
|
|
774
1136
|
function stripDescriptionFields(data) {
|
|
@@ -897,6 +1259,18 @@ async function _handleToolCall(client, name, args) {
|
|
|
897
1259
|
const post = await client.createPost(parsed.nestId, parsed.body);
|
|
898
1260
|
return formatResult({ message: "Comment added successfully", post });
|
|
899
1261
|
}
|
|
1262
|
+
case "nestr_update_comment": {
|
|
1263
|
+
const parsed = schemas.updateComment.parse(args);
|
|
1264
|
+
const updated = await client.updateNest(parsed.commentId, {
|
|
1265
|
+
title: parsed.body,
|
|
1266
|
+
});
|
|
1267
|
+
return formatResult({ message: "Comment updated successfully", comment: updated });
|
|
1268
|
+
}
|
|
1269
|
+
case "nestr_delete_comment": {
|
|
1270
|
+
const parsed = schemas.deleteComment.parse(args);
|
|
1271
|
+
await client.deleteNest(parsed.commentId);
|
|
1272
|
+
return formatResult({ message: `Comment ${parsed.commentId} deleted successfully` });
|
|
1273
|
+
}
|
|
900
1274
|
case "nestr_list_circles": {
|
|
901
1275
|
const parsed = schemas.listCircles.parse(args);
|
|
902
1276
|
const circles = await client.listCircles(parsed.workspaceId, {
|
|
@@ -971,6 +1345,15 @@ async function _handleToolCall(client, name, args) {
|
|
|
971
1345
|
const user = await client.getUser(parsed.workspaceId, parsed.userId);
|
|
972
1346
|
return formatResult(user);
|
|
973
1347
|
}
|
|
1348
|
+
case "nestr_add_workspace_user": {
|
|
1349
|
+
const parsed = schemas.addWorkspaceUser.parse(args);
|
|
1350
|
+
const user = await client.addWorkspaceUser(parsed.workspaceId, {
|
|
1351
|
+
username: parsed.username,
|
|
1352
|
+
fullName: parsed.fullName,
|
|
1353
|
+
language: parsed.language,
|
|
1354
|
+
});
|
|
1355
|
+
return formatResult({ message: "User added to workspace successfully", user });
|
|
1356
|
+
}
|
|
974
1357
|
case "nestr_get_label": {
|
|
975
1358
|
const parsed = schemas.getLabel.parse(args);
|
|
976
1359
|
const label = await client.getLabel(parsed.workspaceId, parsed.labelId);
|
|
@@ -1064,6 +1447,135 @@ async function _handleToolCall(client, name, args) {
|
|
|
1064
1447
|
const items = await client.getDailyPlan();
|
|
1065
1448
|
return formatResult(completableResponse(compactResponse(items), "daily-plan", "Daily Plan"));
|
|
1066
1449
|
}
|
|
1450
|
+
// Current user identity
|
|
1451
|
+
case "nestr_get_me": {
|
|
1452
|
+
schemas.getMe.parse(args);
|
|
1453
|
+
try {
|
|
1454
|
+
const user = await client.getCurrentUser();
|
|
1455
|
+
return formatResult({
|
|
1456
|
+
authMode: "oauth",
|
|
1457
|
+
user,
|
|
1458
|
+
mode: user.bot ? "role-filler" : "assistant",
|
|
1459
|
+
hint: user.bot
|
|
1460
|
+
? "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."
|
|
1461
|
+
: "You are assisting a human who energizes roles. Defer to them for decisions. Help them articulate tensions and navigate governance.",
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
catch {
|
|
1465
|
+
// getCurrentUser fails for workspace API keys — no user identity
|
|
1466
|
+
return formatResult({
|
|
1467
|
+
authMode: "api-key",
|
|
1468
|
+
user: null,
|
|
1469
|
+
mode: "workspace",
|
|
1470
|
+
hint: "Using a workspace API key. No user identity — user-scoped features (inbox, daily plan, personal labels, my tensions) are unavailable. You are managing the workspace directly.",
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
// User tension tools (requires OAuth token)
|
|
1475
|
+
case "nestr_list_my_tensions": {
|
|
1476
|
+
const parsed = schemas.listMyTensions.parse(args);
|
|
1477
|
+
const tensions = await client.listMyTensions({ context: parsed.context });
|
|
1478
|
+
return formatResult(compactResponse(tensions));
|
|
1479
|
+
}
|
|
1480
|
+
case "nestr_list_tensions_awaiting_consent": {
|
|
1481
|
+
const parsed = schemas.listTensionsAwaitingConsent.parse(args);
|
|
1482
|
+
const tensions = await client.listTensionsAwaitingConsent({ context: parsed.context });
|
|
1483
|
+
return formatResult(compactResponse(tensions));
|
|
1484
|
+
}
|
|
1485
|
+
// Tension tools
|
|
1486
|
+
case "nestr_create_tension": {
|
|
1487
|
+
const parsed = schemas.createTension.parse(args);
|
|
1488
|
+
const fields = {};
|
|
1489
|
+
if (parsed.feeling)
|
|
1490
|
+
fields["tension.feeling"] = parsed.feeling;
|
|
1491
|
+
if (parsed.needs)
|
|
1492
|
+
fields["tension.needs"] = parsed.needs;
|
|
1493
|
+
const tension = await client.createTension(parsed.nestId, {
|
|
1494
|
+
title: parsed.title,
|
|
1495
|
+
description: parsed.description,
|
|
1496
|
+
...(Object.keys(fields).length > 0 ? { fields } : {}),
|
|
1497
|
+
});
|
|
1498
|
+
return formatResult({ message: "Tension created successfully", tension });
|
|
1499
|
+
}
|
|
1500
|
+
case "nestr_get_tension": {
|
|
1501
|
+
const parsed = schemas.getTension.parse(args);
|
|
1502
|
+
const tension = await client.getTension(parsed.nestId, parsed.tensionId, { cleanText: true });
|
|
1503
|
+
return formatResult(tension);
|
|
1504
|
+
}
|
|
1505
|
+
case "nestr_list_tensions": {
|
|
1506
|
+
const parsed = schemas.listTensions.parse(args);
|
|
1507
|
+
const tensions = await client.listTensions(parsed.nestId, parsed.search, { limit: parsed.limit, order: parsed.order, cleanText: true });
|
|
1508
|
+
return formatResult(compactResponse(tensions));
|
|
1509
|
+
}
|
|
1510
|
+
case "nestr_update_tension": {
|
|
1511
|
+
const parsed = schemas.updateTension.parse(args);
|
|
1512
|
+
const fields = {};
|
|
1513
|
+
if (parsed.feeling !== undefined)
|
|
1514
|
+
fields["tension.feeling"] = parsed.feeling;
|
|
1515
|
+
if (parsed.needs !== undefined)
|
|
1516
|
+
fields["tension.needs"] = parsed.needs;
|
|
1517
|
+
const tension = await client.updateTension(parsed.nestId, parsed.tensionId, {
|
|
1518
|
+
title: parsed.title,
|
|
1519
|
+
description: parsed.description,
|
|
1520
|
+
...(Object.keys(fields).length > 0 ? { fields } : {}),
|
|
1521
|
+
});
|
|
1522
|
+
return formatResult({ message: "Tension updated successfully", tension });
|
|
1523
|
+
}
|
|
1524
|
+
case "nestr_delete_tension": {
|
|
1525
|
+
const parsed = schemas.deleteTension.parse(args);
|
|
1526
|
+
await client.deleteTension(parsed.nestId, parsed.tensionId);
|
|
1527
|
+
return formatResult({ message: `Tension ${parsed.tensionId} deleted successfully` });
|
|
1528
|
+
}
|
|
1529
|
+
case "nestr_get_tension_parts": {
|
|
1530
|
+
const parsed = schemas.getTensionParts.parse(args);
|
|
1531
|
+
const parts = await client.getTensionParts(parsed.nestId, parsed.tensionId, { cleanText: true });
|
|
1532
|
+
return formatResult(parts);
|
|
1533
|
+
}
|
|
1534
|
+
case "nestr_add_tension_part": {
|
|
1535
|
+
const parsed = schemas.addTensionPart.parse(args);
|
|
1536
|
+
const { nestId, tensionId, removeNest, ...body } = parsed;
|
|
1537
|
+
if (body._id && removeNest) {
|
|
1538
|
+
// Propose removal of existing item
|
|
1539
|
+
const part = await client.proposeTensionRemoval(nestId, tensionId, { _id: body._id });
|
|
1540
|
+
return formatResult({ message: "Removal proposal added successfully", part });
|
|
1541
|
+
}
|
|
1542
|
+
else if (body._id) {
|
|
1543
|
+
// Propose change to existing item
|
|
1544
|
+
const part = await client.proposeTensionChange(nestId, tensionId, body);
|
|
1545
|
+
return formatResult({ message: "Change proposal added successfully", part });
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
// Propose new item
|
|
1549
|
+
const part = await client.createTensionPart(nestId, tensionId, body);
|
|
1550
|
+
return formatResult({ message: "New item proposal added successfully", part });
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
case "nestr_modify_tension_part": {
|
|
1554
|
+
const parsed = schemas.modifyTensionPart.parse(args);
|
|
1555
|
+
const { nestId, tensionId, partId, ...data } = parsed;
|
|
1556
|
+
const part = await client.modifyTensionPart(nestId, tensionId, partId, data);
|
|
1557
|
+
return formatResult({ message: "Tension part modified successfully", part });
|
|
1558
|
+
}
|
|
1559
|
+
case "nestr_remove_tension_part": {
|
|
1560
|
+
const parsed = schemas.removeTensionPart.parse(args);
|
|
1561
|
+
await client.removeTensionPart(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
1562
|
+
return formatResult({ message: `Tension part ${parsed.partId} removed successfully` });
|
|
1563
|
+
}
|
|
1564
|
+
case "nestr_get_tension_changes": {
|
|
1565
|
+
const parsed = schemas.getTensionChanges.parse(args);
|
|
1566
|
+
const changes = await client.getTensionPartChanges(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
1567
|
+
return formatResult(changes);
|
|
1568
|
+
}
|
|
1569
|
+
case "nestr_get_tension_status": {
|
|
1570
|
+
const parsed = schemas.getTensionStatus.parse(args);
|
|
1571
|
+
const status = await client.getTensionStatus(parsed.nestId, parsed.tensionId);
|
|
1572
|
+
return formatResult(status);
|
|
1573
|
+
}
|
|
1574
|
+
case "nestr_update_tension_status": {
|
|
1575
|
+
const parsed = schemas.updateTensionStatus.parse(args);
|
|
1576
|
+
const status = await client.updateTensionStatus(parsed.nestId, parsed.tensionId, parsed.status);
|
|
1577
|
+
return formatResult({ message: `Tension status updated to '${parsed.status}'`, status });
|
|
1578
|
+
}
|
|
1067
1579
|
default:
|
|
1068
1580
|
return formatError({
|
|
1069
1581
|
error: true,
|