@nestr/mcp 0.1.44 → 0.1.46
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 +39 -4
- package/build/api/client.d.ts.map +1 -1
- package/build/api/client.js +89 -8
- 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 +127 -229
- 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 +1172 -64
- package/build/tools/index.d.ts.map +1 -1
- package/build/tools/index.js +284 -49
- 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAianB,CAAC;AAQF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmhC3B,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)."),
|
|
@@ -104,8 +104,8 @@ export const schemas = {
|
|
|
104
104
|
createNest: z.object({
|
|
105
105
|
parentId: z.string().describe("Parent nest ID (workspace, circle, or project)"),
|
|
106
106
|
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
|
|
107
|
+
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."),
|
|
108
|
+
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
109
|
labels: z.array(z.string()).optional().describe("Label IDs to apply"),
|
|
110
110
|
users: z.array(z.string()).optional().describe("User IDs to assign (required for tasks/projects to associate with a person)"),
|
|
111
111
|
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 +115,8 @@ export const schemas = {
|
|
|
115
115
|
updateNest: z.object({
|
|
116
116
|
nestId: z.string().describe("Nest ID to update"),
|
|
117
117
|
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
|
|
118
|
+
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."),
|
|
119
|
+
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
120
|
parentId: z.string().optional().describe("New parent ID (move nest to different location, e.g., move inbox item to a role or project)"),
|
|
121
121
|
labels: z.array(z.string()).optional().describe("Label IDs to set (e.g., ['project'] to convert an item into a project)"),
|
|
122
122
|
fields: z.record(z.unknown()).optional().describe("Field updates (e.g., { 'project.status': 'Current' })"),
|
|
@@ -274,7 +274,9 @@ export const schemas = {
|
|
|
274
274
|
// Daily plan (requires OAuth token)
|
|
275
275
|
getDailyPlan: z.object({}),
|
|
276
276
|
// Current user identity (requires OAuth token)
|
|
277
|
-
getMe: z.object({
|
|
277
|
+
getMe: z.object({
|
|
278
|
+
fullWorkspaces: z.boolean().optional().describe("Set true to include full workspace details (purpose, labels, governance type, user access roles). Recommended on first call to establish workspace context."),
|
|
279
|
+
}),
|
|
278
280
|
// User tension tools (requires OAuth token)
|
|
279
281
|
listMyTensions: z.object({
|
|
280
282
|
context: z.string().optional().describe("Optional context filter (e.g., workspace ID or circle ID)"),
|
|
@@ -282,9 +284,18 @@ export const schemas = {
|
|
|
282
284
|
listTensionsAwaitingConsent: z.object({
|
|
283
285
|
context: z.string().optional().describe("Optional context filter (e.g., workspace ID or circle ID)"),
|
|
284
286
|
}),
|
|
287
|
+
// Notification tools (requires OAuth token)
|
|
288
|
+
listNotifications: z.object({
|
|
289
|
+
type: z.enum(["all", "me", "relevant"]).optional().describe("Filter by type: 'all' (default), 'me' (direct — mentions, replies, reactions, DMs), 'relevant' (delayed — updates, governance)"),
|
|
290
|
+
limit: z.number().optional().describe("Max results to return (default 50, max 200)"),
|
|
291
|
+
skip: z.number().optional().describe("Number of results to skip (default 0)"),
|
|
292
|
+
showRead: z.boolean().optional().describe("Include already-read notifications (default false)"),
|
|
293
|
+
group: z.string().optional().describe("Filter by notification group (mentions, replies, direct_message, reactions, updates, governance)"),
|
|
294
|
+
}),
|
|
295
|
+
markNotificationsRead: z.object({}),
|
|
285
296
|
// Tension tools
|
|
286
297
|
createTension: z.object({
|
|
287
|
-
nestId: z.string().describe("ID of the
|
|
298
|
+
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."),
|
|
288
299
|
title: z.string().describe("The gap you're sensing — what is the difference between current reality and desired state (plain text)"),
|
|
289
300
|
description: z.string().optional().describe("The observable facts — what you see/hear/experience that creates this tension (supports HTML)"),
|
|
290
301
|
feeling: z.string().optional().describe("The feeling this tension evokes in you — separated from the facts to keep the organizational response clean (plain text)"),
|
|
@@ -322,35 +333,58 @@ export const schemas = {
|
|
|
322
333
|
_id: z.string().optional().describe("ID of an existing governance item to change or remove. Omit to propose a new item."),
|
|
323
334
|
title: z.string().optional().describe("Title for the governance item"),
|
|
324
335
|
labels: z.array(z.string()).optional().describe("Labels defining the item type (e.g., ['role'], ['circle'], ['policy'], ['accountability'], ['domain'])"),
|
|
325
|
-
purpose: z.string().optional().describe("Purpose
|
|
326
|
-
description: z.string().optional().describe("Description
|
|
336
|
+
purpose: z.string().optional().describe("Purpose — aspirational future state. Most important for roles/circles where it defines the north star. Supports HTML."),
|
|
337
|
+
description: z.string().optional().describe("Description — detailed information about the item. Supports HTML."),
|
|
327
338
|
parentId: z.string().optional().describe("Parent ID — use to move/restructure items (e.g., move role to different circle)"),
|
|
328
339
|
users: z.array(z.string()).optional().describe("User IDs to assign (e.g., for role elections: assign the elected user to the role)"),
|
|
329
340
|
due: z.string().optional().describe("Due date / re-election date (ISO format)"),
|
|
330
|
-
accountabilities: z.array(z.string()).optional().describe("Accountability titles to set on a role (replaces
|
|
331
|
-
domains: z.array(z.string()).optional().describe("Domain titles to set on a role (replaces
|
|
332
|
-
removeNest: z.boolean().optional().describe("Set to true with _id to propose removal of the existing governance item"),
|
|
341
|
+
accountabilities: z.array(z.string()).optional().describe("Accountability titles to set on a role (replaces all — use children endpoint for individual management)"),
|
|
342
|
+
domains: z.array(z.string()).optional().describe("Domain titles to set on a role (replaces all — use children endpoint for individual management)"),
|
|
333
343
|
}),
|
|
334
344
|
modifyTensionPart: z.object({
|
|
335
345
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
336
346
|
tensionId: z.string().describe("Tension ID"),
|
|
337
347
|
partId: z.string().describe("Part ID to modify"),
|
|
338
348
|
title: z.string().optional().describe("Updated title"),
|
|
339
|
-
purpose: z.string().optional().describe("Updated purpose
|
|
340
|
-
description: z.string().optional().describe("Updated description
|
|
349
|
+
purpose: z.string().optional().describe("Updated purpose — aspirational future state. Most important for roles/circles. Supports HTML."),
|
|
350
|
+
description: z.string().optional().describe("Updated description — detailed information. Supports HTML."),
|
|
341
351
|
labels: z.array(z.string()).optional().describe("Updated labels"),
|
|
342
352
|
parentId: z.string().optional().describe("Updated parent ID"),
|
|
343
353
|
users: z.array(z.string()).optional().describe("Updated user assignments"),
|
|
344
354
|
due: z.string().optional().describe("Updated due date (ISO format)"),
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
domains: z.array(z.string()).optional().describe("Updated domains"),
|
|
355
|
+
accountabilities: z.array(z.string()).optional().describe("Updated accountabilities (replaces all — use children endpoint for individual management)"),
|
|
356
|
+
domains: z.array(z.string()).optional().describe("Updated domains (replaces all — use children endpoint for individual management)"),
|
|
348
357
|
}),
|
|
349
358
|
removeTensionPart: z.object({
|
|
350
359
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
351
360
|
tensionId: z.string().describe("Tension ID"),
|
|
352
361
|
partId: z.string().describe("Part ID to remove from the proposal"),
|
|
353
362
|
}),
|
|
363
|
+
getTensionPartChildren: z.object({
|
|
364
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
365
|
+
tensionId: z.string().describe("Tension ID"),
|
|
366
|
+
partId: z.string().describe("Part ID"),
|
|
367
|
+
}),
|
|
368
|
+
createTensionPartChild: z.object({
|
|
369
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
370
|
+
tensionId: z.string().describe("Tension ID"),
|
|
371
|
+
partId: z.string().describe("Part ID"),
|
|
372
|
+
title: z.string().describe("Title for the new accountability or domain"),
|
|
373
|
+
labels: z.array(z.string()).describe("Labels defining the type: ['accountability'] or ['domain']"),
|
|
374
|
+
}),
|
|
375
|
+
updateTensionPartChild: z.object({
|
|
376
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
377
|
+
tensionId: z.string().describe("Tension ID"),
|
|
378
|
+
partId: z.string().describe("Part ID"),
|
|
379
|
+
childId: z.string().describe("Child ID to update"),
|
|
380
|
+
title: z.string().describe("Updated title"),
|
|
381
|
+
}),
|
|
382
|
+
deleteTensionPartChild: z.object({
|
|
383
|
+
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
384
|
+
tensionId: z.string().describe("Tension ID"),
|
|
385
|
+
partId: z.string().describe("Part ID"),
|
|
386
|
+
childId: z.string().describe("Child ID to soft-delete (will remove the original accountability/domain when enacted)"),
|
|
387
|
+
}),
|
|
354
388
|
getTensionChanges: z.object({
|
|
355
389
|
nestId: z.string().describe("ID of the circle or role the tension belongs to"),
|
|
356
390
|
tensionId: z.string().describe("Tension ID"),
|
|
@@ -365,6 +399,24 @@ export const schemas = {
|
|
|
365
399
|
tensionId: z.string().describe("Tension ID"),
|
|
366
400
|
status: z.enum(["proposed", "draft"]).describe("'proposed' to submit for voting, 'draft' to retract back to draft"),
|
|
367
401
|
}),
|
|
402
|
+
// Graph link tools
|
|
403
|
+
getGraphLinks: z.object({
|
|
404
|
+
nestId: z.string().describe("Nest ID to get graph links for"),
|
|
405
|
+
relation: z.string().describe("Relation name (e.g., 'meeting' for meeting agenda items)"),
|
|
406
|
+
direction: z.enum(["outgoing", "incoming"]).optional().describe("Link direction: 'outgoing' (default) = links FROM this nest, 'incoming' = links TO this nest"),
|
|
407
|
+
limit: z.number().optional().describe("Max results per page (default 50)"),
|
|
408
|
+
page: z.number().optional().describe("Page number for pagination"),
|
|
409
|
+
}),
|
|
410
|
+
addGraphLink: z.object({
|
|
411
|
+
nestId: z.string().describe("Source nest ID"),
|
|
412
|
+
relation: z.string().describe("Relation name (e.g., 'meeting' to link a tension to a meeting as an agenda item)"),
|
|
413
|
+
targetId: z.string().describe("Target nest ID to link to"),
|
|
414
|
+
}),
|
|
415
|
+
removeGraphLink: z.object({
|
|
416
|
+
nestId: z.string().describe("Source nest ID"),
|
|
417
|
+
relation: z.string().describe("Relation name (e.g., 'meeting')"),
|
|
418
|
+
targetId: z.string().describe("Target nest ID to unlink"),
|
|
419
|
+
}),
|
|
368
420
|
};
|
|
369
421
|
// Tool annotations for MCP - hints for clients on tool behavior
|
|
370
422
|
const readOnly = { annotations: { readOnlyHint: true, destructiveHint: false } };
|
|
@@ -374,7 +426,7 @@ const destructive = { annotations: { readOnlyHint: false, destructiveHint: true
|
|
|
374
426
|
export const toolDefinitions = [
|
|
375
427
|
{
|
|
376
428
|
name: "nestr_list_workspaces",
|
|
377
|
-
description: "List
|
|
429
|
+
description: "List and search Nestr workspaces. Use this to find a workspace by name when `nestr_get_me` workspaces cache doesn't have a match, or for paginated browsing. Prefer `nestr_get_me` with `fullWorkspaces: true` as the primary way to discover workspaces at session start. Response includes meta.total showing total count.",
|
|
378
430
|
inputSchema: {
|
|
379
431
|
type: "object",
|
|
380
432
|
properties: {
|
|
@@ -494,8 +546,8 @@ export const toolDefinitions = [
|
|
|
494
546
|
properties: {
|
|
495
547
|
parentId: { type: "string", description: "Parent nest ID (workspace, circle, or project)" },
|
|
496
548
|
title: { type: "string", description: "Title of the new nest (plain text, HTML tags stripped)" },
|
|
497
|
-
purpose: { type: "string", description: "Purpose
|
|
498
|
-
description: { type: "string", description: "Detailed description
|
|
549
|
+
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." },
|
|
550
|
+
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." },
|
|
499
551
|
labels: {
|
|
500
552
|
type: "array",
|
|
501
553
|
items: { type: "string" },
|
|
@@ -533,8 +585,8 @@ export const toolDefinitions = [
|
|
|
533
585
|
properties: {
|
|
534
586
|
nestId: { type: "string", description: "Nest ID to update" },
|
|
535
587
|
title: { type: "string", description: "New title (plain text, HTML tags stripped)" },
|
|
536
|
-
purpose: { type: "string", description: "New purpose
|
|
537
|
-
description: { type: "string", description: "New description
|
|
588
|
+
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." },
|
|
589
|
+
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." },
|
|
538
590
|
parentId: { type: "string", description: "New parent ID (move nest to different location)" },
|
|
539
591
|
labels: {
|
|
540
592
|
type: "array",
|
|
@@ -1053,13 +1105,15 @@ export const toolDefinitions = [
|
|
|
1053
1105
|
},
|
|
1054
1106
|
...mutating,
|
|
1055
1107
|
},
|
|
1056
|
-
// Current user identity
|
|
1108
|
+
// Current user identity and workspace context — primary entry point
|
|
1057
1109
|
{
|
|
1058
1110
|
name: "nestr_get_me",
|
|
1059
|
-
description: "
|
|
1111
|
+
description: "CALL THIS FIRST at session start. Returns your identity, operating mode, and accessible workspaces. With `fullWorkspaces: true`, includes full workspace details (purpose, governance type, user access roles) — use this to establish workspace context without a separate list_workspaces call. If only one workspace exists, it is the active workspace. For multiple workspaces, use names to identify the right one. Returns `authMode: 'api-key'` when using a workspace API key (workspace mode, no user identity).",
|
|
1060
1112
|
inputSchema: {
|
|
1061
1113
|
type: "object",
|
|
1062
|
-
properties: {
|
|
1114
|
+
properties: {
|
|
1115
|
+
fullWorkspaces: { type: "boolean", description: "Set true to include full workspace details. Recommended on first call." },
|
|
1116
|
+
},
|
|
1063
1117
|
},
|
|
1064
1118
|
...readOnly,
|
|
1065
1119
|
},
|
|
@@ -1086,14 +1140,39 @@ export const toolDefinitions = [
|
|
|
1086
1140
|
},
|
|
1087
1141
|
...readOnly,
|
|
1088
1142
|
},
|
|
1143
|
+
// Notification tools (requires OAuth token)
|
|
1144
|
+
{
|
|
1145
|
+
name: "nestr_list_notifications",
|
|
1146
|
+
description: "List in-app notifications for the current user. By default returns only unread notifications. Use 'type' to filter: 'all' (default), 'me' (direct — mentions, replies, reactions, DMs), 'relevant' (delayed — updates, governance). Each notification includes a rendered 'title' (e.g. 'Joost changed Project X in Developer') and optional 'details' array with change descriptions (e.g. 'Item was completed', 'Updated Project status from Backlog to Done'). Check at session start alongside tensions and inbox. Requires OAuth token.",
|
|
1147
|
+
inputSchema: {
|
|
1148
|
+
type: "object",
|
|
1149
|
+
properties: {
|
|
1150
|
+
type: { type: "string", enum: ["all", "me", "relevant"], description: "Filter by type: 'all' (default), 'me' (direct), 'relevant' (delayed)" },
|
|
1151
|
+
limit: { type: "number", description: "Max results (default 50, max 200)" },
|
|
1152
|
+
skip: { type: "number", description: "Number of results to skip (default 0)" },
|
|
1153
|
+
showRead: { type: "boolean", description: "Include already-read notifications (default false)" },
|
|
1154
|
+
group: { type: "string", description: "Filter by group (mentions, replies, direct_message, reactions, updates, governance)" },
|
|
1155
|
+
},
|
|
1156
|
+
},
|
|
1157
|
+
...readOnly,
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
name: "nestr_mark_notifications_read",
|
|
1161
|
+
description: "Mark all unread in-app notifications as read for the current user. Returns { status, data: { markedCount } }. Requires OAuth token.",
|
|
1162
|
+
inputSchema: {
|
|
1163
|
+
type: "object",
|
|
1164
|
+
properties: {},
|
|
1165
|
+
},
|
|
1166
|
+
...mutating,
|
|
1167
|
+
},
|
|
1089
1168
|
// Tension tools
|
|
1090
1169
|
{
|
|
1091
1170
|
name: "nestr_create_tension",
|
|
1092
|
-
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).
|
|
1171
|
+
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.",
|
|
1093
1172
|
inputSchema: {
|
|
1094
1173
|
type: "object",
|
|
1095
1174
|
properties: {
|
|
1096
|
-
nestId: { type: "string", description: "ID of the
|
|
1175
|
+
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)." },
|
|
1097
1176
|
title: { type: "string", description: "The gap — what is the difference between current reality and desired state (plain text)" },
|
|
1098
1177
|
description: { type: "string", description: "The observable facts — what you see/hear/experience (supports HTML)" },
|
|
1099
1178
|
feeling: { type: "string", description: "The feeling this tension evokes — separated to keep the organizational response clean (plain text)" },
|
|
@@ -1178,11 +1257,13 @@ export const toolDefinitions = [
|
|
|
1178
1257
|
name: "nestr_add_tension_part",
|
|
1179
1258
|
description: `Add a governance change to a tension. Three modes based on input:
|
|
1180
1259
|
|
|
1181
|
-
**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.
|
|
1260
|
+
**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.
|
|
1182
1261
|
|
|
1183
|
-
**Change existing item** (_id provided
|
|
1262
|
+
**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.
|
|
1184
1263
|
|
|
1185
|
-
**Remove existing item** (_id
|
|
1264
|
+
**Remove existing item** (_id only, no other fields): Use nestr_remove_tension_part after adding the part, or use DELETE /parts to propose removal.
|
|
1265
|
+
|
|
1266
|
+
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.`,
|
|
1186
1267
|
inputSchema: {
|
|
1187
1268
|
type: "object",
|
|
1188
1269
|
properties: {
|
|
@@ -1196,9 +1277,8 @@ export const toolDefinitions = [
|
|
|
1196
1277
|
parentId: { type: "string", description: "Parent ID — use to move/restructure items (e.g., move role to different circle)" },
|
|
1197
1278
|
users: { type: "array", items: { type: "string" }, description: "User IDs to assign (e.g., for elections: assign elected user to the role)" },
|
|
1198
1279
|
due: { type: "string", description: "Due date / re-election date (ISO format)" },
|
|
1199
|
-
accountabilities: { type: "array", items: { type: "string" }, description: "Accountability titles to set on a role (replaces
|
|
1200
|
-
domains: { type: "array", items: { type: "string" }, description: "Domain titles to set on a role (replaces
|
|
1201
|
-
removeNest: { type: "boolean", description: "Set to true with _id to propose removal of the existing governance item" },
|
|
1280
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Accountability titles to set on a role (replaces all — use children endpoint for individual management)" },
|
|
1281
|
+
domains: { type: "array", items: { type: "string" }, description: "Domain titles to set on a role (replaces all — use children endpoint for individual management)" },
|
|
1202
1282
|
},
|
|
1203
1283
|
required: ["nestId", "tensionId"],
|
|
1204
1284
|
},
|
|
@@ -1206,7 +1286,7 @@ export const toolDefinitions = [
|
|
|
1206
1286
|
},
|
|
1207
1287
|
{
|
|
1208
1288
|
name: "nestr_modify_tension_part",
|
|
1209
|
-
description: "Modify an existing proposal part. Use to refine proposed values after initial creation — e.g., adjust a role's title or
|
|
1289
|
+
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.).",
|
|
1210
1290
|
inputSchema: {
|
|
1211
1291
|
type: "object",
|
|
1212
1292
|
properties: {
|
|
@@ -1220,9 +1300,8 @@ export const toolDefinitions = [
|
|
|
1220
1300
|
parentId: { type: "string", description: "Updated parent ID" },
|
|
1221
1301
|
users: { type: "array", items: { type: "string" }, description: "Updated user assignments" },
|
|
1222
1302
|
due: { type: "string", description: "Updated due date (ISO format)" },
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
domains: { type: "array", items: { type: "string" }, description: "Updated domains" },
|
|
1303
|
+
accountabilities: { type: "array", items: { type: "string" }, description: "Updated accountabilities (replaces all — use children endpoint for individual management)" },
|
|
1304
|
+
domains: { type: "array", items: { type: "string" }, description: "Updated domains (replaces all — use children endpoint for individual management)" },
|
|
1226
1305
|
},
|
|
1227
1306
|
required: ["nestId", "tensionId", "partId"],
|
|
1228
1307
|
},
|
|
@@ -1230,7 +1309,7 @@ export const toolDefinitions = [
|
|
|
1230
1309
|
},
|
|
1231
1310
|
{
|
|
1232
1311
|
name: "nestr_remove_tension_part",
|
|
1233
|
-
description: "Remove a part from the proposal entirely
|
|
1312
|
+
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.",
|
|
1234
1313
|
inputSchema: {
|
|
1235
1314
|
type: "object",
|
|
1236
1315
|
properties: {
|
|
@@ -1242,6 +1321,63 @@ export const toolDefinitions = [
|
|
|
1242
1321
|
},
|
|
1243
1322
|
...destructive,
|
|
1244
1323
|
},
|
|
1324
|
+
{
|
|
1325
|
+
name: "nestr_get_tension_part_children",
|
|
1326
|
+
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.",
|
|
1327
|
+
inputSchema: {
|
|
1328
|
+
type: "object",
|
|
1329
|
+
properties: {
|
|
1330
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1331
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1332
|
+
partId: { type: "string", description: "Part ID" },
|
|
1333
|
+
},
|
|
1334
|
+
required: ["nestId", "tensionId", "partId"],
|
|
1335
|
+
},
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
name: "nestr_create_tension_part_child",
|
|
1339
|
+
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.",
|
|
1340
|
+
inputSchema: {
|
|
1341
|
+
type: "object",
|
|
1342
|
+
properties: {
|
|
1343
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1344
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1345
|
+
partId: { type: "string", description: "Part ID" },
|
|
1346
|
+
title: { type: "string", description: "Title for the new accountability or domain" },
|
|
1347
|
+
labels: { type: "array", items: { type: "string" }, description: "Labels defining the type: ['accountability'] or ['domain']" },
|
|
1348
|
+
},
|
|
1349
|
+
required: ["nestId", "tensionId", "partId", "title", "labels"],
|
|
1350
|
+
},
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
name: "nestr_update_tension_part_child",
|
|
1354
|
+
description: "Rename an accountability or domain within a proposal part. When the proposal is enacted, the original accountability/domain is updated.",
|
|
1355
|
+
inputSchema: {
|
|
1356
|
+
type: "object",
|
|
1357
|
+
properties: {
|
|
1358
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1359
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1360
|
+
partId: { type: "string", description: "Part ID" },
|
|
1361
|
+
childId: { type: "string", description: "Child ID to update" },
|
|
1362
|
+
title: { type: "string", description: "Updated title" },
|
|
1363
|
+
},
|
|
1364
|
+
required: ["nestId", "tensionId", "partId", "childId", "title"],
|
|
1365
|
+
},
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
name: "nestr_delete_tension_part_child",
|
|
1369
|
+
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.",
|
|
1370
|
+
inputSchema: {
|
|
1371
|
+
type: "object",
|
|
1372
|
+
properties: {
|
|
1373
|
+
nestId: { type: "string", description: "ID of the circle or role the tension belongs to" },
|
|
1374
|
+
tensionId: { type: "string", description: "Tension ID" },
|
|
1375
|
+
partId: { type: "string", description: "Part ID" },
|
|
1376
|
+
childId: { type: "string", description: "Child ID to soft-delete" },
|
|
1377
|
+
},
|
|
1378
|
+
required: ["nestId", "tensionId", "partId", "childId"],
|
|
1379
|
+
},
|
|
1380
|
+
},
|
|
1245
1381
|
{
|
|
1246
1382
|
name: "nestr_get_tension_changes",
|
|
1247
1383
|
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.",
|
|
@@ -1283,6 +1419,51 @@ export const toolDefinitions = [
|
|
|
1283
1419
|
},
|
|
1284
1420
|
...mutating,
|
|
1285
1421
|
},
|
|
1422
|
+
// Graph link tools
|
|
1423
|
+
{
|
|
1424
|
+
name: "nestr_get_graph_links",
|
|
1425
|
+
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.",
|
|
1426
|
+
inputSchema: {
|
|
1427
|
+
type: "object",
|
|
1428
|
+
properties: {
|
|
1429
|
+
nestId: { type: "string", description: "Nest ID to get graph links for" },
|
|
1430
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting' for meeting agenda items)" },
|
|
1431
|
+
direction: { type: "string", enum: ["outgoing", "incoming"], description: "Link direction: 'outgoing' (default) = links FROM this nest, 'incoming' = links TO this nest" },
|
|
1432
|
+
limit: { type: "number", description: "Max results per page (default 50)" },
|
|
1433
|
+
page: { type: "number", description: "Page number for pagination" },
|
|
1434
|
+
},
|
|
1435
|
+
required: ["nestId", "relation"],
|
|
1436
|
+
},
|
|
1437
|
+
...readOnly,
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
name: "nestr_add_graph_link",
|
|
1441
|
+
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.",
|
|
1442
|
+
inputSchema: {
|
|
1443
|
+
type: "object",
|
|
1444
|
+
properties: {
|
|
1445
|
+
nestId: { type: "string", description: "Source nest ID" },
|
|
1446
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting' to link a tension to a meeting)" },
|
|
1447
|
+
targetId: { type: "string", description: "Target nest ID to link to" },
|
|
1448
|
+
},
|
|
1449
|
+
required: ["nestId", "relation", "targetId"],
|
|
1450
|
+
},
|
|
1451
|
+
...mutating,
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
name: "nestr_remove_graph_link",
|
|
1455
|
+
description: "Remove a graph link between two nests. For example, remove a tension from a meeting's agenda by removing the 'meeting' relation.",
|
|
1456
|
+
inputSchema: {
|
|
1457
|
+
type: "object",
|
|
1458
|
+
properties: {
|
|
1459
|
+
nestId: { type: "string", description: "Source nest ID" },
|
|
1460
|
+
relation: { type: "string", description: "Relation name (e.g., 'meeting')" },
|
|
1461
|
+
targetId: { type: "string", description: "Target nest ID to unlink" },
|
|
1462
|
+
},
|
|
1463
|
+
required: ["nestId", "relation", "targetId"],
|
|
1464
|
+
},
|
|
1465
|
+
...destructive,
|
|
1466
|
+
},
|
|
1286
1467
|
];
|
|
1287
1468
|
// Strip description fields from nest objects in response data
|
|
1288
1469
|
function stripDescriptionFields(data) {
|
|
@@ -1675,11 +1856,13 @@ async function _handleToolCall(client, name, args) {
|
|
|
1675
1856
|
const items = await client.getDailyPlan();
|
|
1676
1857
|
return formatResult(completableResponse(compactResponse(items), "daily-plan", "Daily Plan"));
|
|
1677
1858
|
}
|
|
1678
|
-
// Current user identity
|
|
1859
|
+
// Current user identity and workspace context
|
|
1679
1860
|
case "nestr_get_me": {
|
|
1680
|
-
schemas.getMe.parse(args);
|
|
1861
|
+
const parsed = schemas.getMe.parse(args);
|
|
1681
1862
|
try {
|
|
1682
|
-
const user = await client.getCurrentUser(
|
|
1863
|
+
const user = await client.getCurrentUser({
|
|
1864
|
+
fullWorkspaces: parsed.fullWorkspaces,
|
|
1865
|
+
});
|
|
1683
1866
|
return formatResult({
|
|
1684
1867
|
authMode: "oauth",
|
|
1685
1868
|
user,
|
|
@@ -1716,6 +1899,23 @@ async function _handleToolCall(client, name, args) {
|
|
|
1716
1899
|
const tensions = await client.listTensionsAwaitingConsent({ context: parsed.context });
|
|
1717
1900
|
return formatResult(compactResponse(tensions));
|
|
1718
1901
|
}
|
|
1902
|
+
// Notification tools (requires OAuth token)
|
|
1903
|
+
case "nestr_list_notifications": {
|
|
1904
|
+
const parsed = schemas.listNotifications.parse(args);
|
|
1905
|
+
const notifications = await client.listNotifications({
|
|
1906
|
+
type: parsed.type,
|
|
1907
|
+
limit: parsed.limit,
|
|
1908
|
+
skip: parsed.skip,
|
|
1909
|
+
showRead: parsed.showRead,
|
|
1910
|
+
group: parsed.group,
|
|
1911
|
+
});
|
|
1912
|
+
return formatResult(notifications);
|
|
1913
|
+
}
|
|
1914
|
+
case "nestr_mark_notifications_read": {
|
|
1915
|
+
schemas.markNotificationsRead.parse(args);
|
|
1916
|
+
const result = await client.markNotificationsRead();
|
|
1917
|
+
return formatResult(result);
|
|
1918
|
+
}
|
|
1719
1919
|
// Tension tools
|
|
1720
1920
|
case "nestr_create_tension": {
|
|
1721
1921
|
const parsed = schemas.createTension.parse(args);
|
|
@@ -1767,14 +1967,9 @@ async function _handleToolCall(client, name, args) {
|
|
|
1767
1967
|
}
|
|
1768
1968
|
case "nestr_add_tension_part": {
|
|
1769
1969
|
const parsed = schemas.addTensionPart.parse(args);
|
|
1770
|
-
const { nestId, tensionId,
|
|
1771
|
-
if (body._id
|
|
1772
|
-
// Propose
|
|
1773
|
-
const part = await client.proposeTensionRemoval(nestId, tensionId, { _id: body._id });
|
|
1774
|
-
return formatResult({ message: "Removal proposal added successfully", part });
|
|
1775
|
-
}
|
|
1776
|
-
else if (body._id) {
|
|
1777
|
-
// Propose change to existing item
|
|
1970
|
+
const { nestId, tensionId, ...body } = parsed;
|
|
1971
|
+
if (body._id) {
|
|
1972
|
+
// Propose change to existing item (existing children auto-copied if accountabilities/domains not provided)
|
|
1778
1973
|
const part = await client.proposeTensionChange(nestId, tensionId, body);
|
|
1779
1974
|
return formatResult({ message: "Change proposal added successfully", part });
|
|
1780
1975
|
}
|
|
@@ -1795,6 +1990,26 @@ async function _handleToolCall(client, name, args) {
|
|
|
1795
1990
|
await client.removeTensionPart(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
1796
1991
|
return formatResult({ message: `Tension part ${parsed.partId} removed successfully` });
|
|
1797
1992
|
}
|
|
1993
|
+
case "nestr_get_tension_part_children": {
|
|
1994
|
+
const parsed = schemas.getTensionPartChildren.parse(args);
|
|
1995
|
+
const children = await client.getTensionPartChildren(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
1996
|
+
return formatResult(children);
|
|
1997
|
+
}
|
|
1998
|
+
case "nestr_create_tension_part_child": {
|
|
1999
|
+
const parsed = schemas.createTensionPartChild.parse(args);
|
|
2000
|
+
const child = await client.createTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, { title: parsed.title, labels: parsed.labels });
|
|
2001
|
+
return formatResult({ message: "Child created successfully", child });
|
|
2002
|
+
}
|
|
2003
|
+
case "nestr_update_tension_part_child": {
|
|
2004
|
+
const parsed = schemas.updateTensionPartChild.parse(args);
|
|
2005
|
+
const child = await client.updateTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, parsed.childId, { title: parsed.title });
|
|
2006
|
+
return formatResult({ message: "Child updated successfully", child });
|
|
2007
|
+
}
|
|
2008
|
+
case "nestr_delete_tension_part_child": {
|
|
2009
|
+
const parsed = schemas.deleteTensionPartChild.parse(args);
|
|
2010
|
+
await client.deleteTensionPartChild(parsed.nestId, parsed.tensionId, parsed.partId, parsed.childId);
|
|
2011
|
+
return formatResult({ message: `Child ${parsed.childId} soft-deleted successfully` });
|
|
2012
|
+
}
|
|
1798
2013
|
case "nestr_get_tension_changes": {
|
|
1799
2014
|
const parsed = schemas.getTensionChanges.parse(args);
|
|
1800
2015
|
const changes = await client.getTensionPartChanges(parsed.nestId, parsed.tensionId, parsed.partId);
|
|
@@ -1810,6 +2025,26 @@ async function _handleToolCall(client, name, args) {
|
|
|
1810
2025
|
const status = await client.updateTensionStatus(parsed.nestId, parsed.tensionId, parsed.status);
|
|
1811
2026
|
return formatResult({ message: `Tension status updated to '${parsed.status}'`, status });
|
|
1812
2027
|
}
|
|
2028
|
+
// Graph link tools
|
|
2029
|
+
case "nestr_get_graph_links": {
|
|
2030
|
+
const parsed = schemas.getGraphLinks.parse(args);
|
|
2031
|
+
const result = await client.getGraphLinks(parsed.nestId, parsed.relation, {
|
|
2032
|
+
direction: parsed.direction,
|
|
2033
|
+
limit: parsed.limit,
|
|
2034
|
+
page: parsed.page,
|
|
2035
|
+
});
|
|
2036
|
+
return formatResult(compactResponse(result));
|
|
2037
|
+
}
|
|
2038
|
+
case "nestr_add_graph_link": {
|
|
2039
|
+
const parsed = schemas.addGraphLink.parse(args);
|
|
2040
|
+
const result = await client.addGraphLink(parsed.nestId, parsed.relation, parsed.targetId);
|
|
2041
|
+
return formatResult(result);
|
|
2042
|
+
}
|
|
2043
|
+
case "nestr_remove_graph_link": {
|
|
2044
|
+
const parsed = schemas.removeGraphLink.parse(args);
|
|
2045
|
+
const result = await client.removeGraphLink(parsed.nestId, parsed.relation, parsed.targetId);
|
|
2046
|
+
return formatResult({ message: "Graph link removed" });
|
|
2047
|
+
}
|
|
1813
2048
|
default:
|
|
1814
2049
|
return formatError({
|
|
1815
2050
|
error: true,
|