@nimara-app/mcp 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,6 +29,7 @@ remove existing data, as opposed to only adding.
29
29
  | `create_validation_task` | Write | Create a validation/test task in a project. |
30
30
  | `create_work_item` | Write | Create a new work item in a project. |
31
31
  | `get_active_block` | Read | The project's active block: the committed, ordered set of work. Call before list_work_items when deciding what to do next; position 0 is next, and each item's lane says who owes it. |
32
+ | `heartbeat_work_item` | Write | Say you are still working on an item: renews its 15-minute "agent working" lease and nothing else. |
32
33
  | `get_work_items` | Read | Read specific work items by id or displayId (e.g. NIM-42) — far cheaper than listing a project when you already know which items you want. |
33
34
  | `list_ai_review_queue` | Read | List work items in a project that a human has flagged for AI review (aiReviewRequested). |
34
35
  | `list_documents` | Read | List PRD/FD markdown documents for a project, optionally filtered to one work item.. |
package/dist/index.js CHANGED
@@ -6,6 +6,76 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
6
6
  // src/server.ts
7
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
8
 
9
+ // package.json
10
+ var package_default = {
11
+ name: "@nimara-app/mcp",
12
+ version: "0.4.0",
13
+ private: false,
14
+ mcpName: "io.github.langskip-studios/nimara",
15
+ description: "Nimara MCP server \u2014 AI tool integration for Claude, Codex, and others",
16
+ license: "MIT",
17
+ type: "module",
18
+ main: "dist/index.js",
19
+ bin: {
20
+ "nimara-mcp": "dist/index.js"
21
+ },
22
+ files: [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ keywords: [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "nimara",
30
+ "claude",
31
+ "ai",
32
+ "convex"
33
+ ],
34
+ repository: {
35
+ type: "git",
36
+ url: "git+https://github.com/Langskip-Studios/Nimara.git",
37
+ directory: "packages/mcp"
38
+ },
39
+ homepage: "https://github.com/Langskip-Studios/Nimara/tree/master/packages/mcp#readme",
40
+ publishConfig: {
41
+ access: "public"
42
+ },
43
+ scripts: {
44
+ build: "node build.mjs",
45
+ dev: "node build.mjs",
46
+ start: "node dist/index.js",
47
+ typecheck: "tsc --noEmit",
48
+ prepublishOnly: "npm run typecheck && npm run build"
49
+ },
50
+ dependencies: {
51
+ "@modelcontextprotocol/sdk": "^1.0.0",
52
+ convex: "^1.18.0",
53
+ zod: "^3.23.0"
54
+ },
55
+ devDependencies: {
56
+ "@nimara/convex": "workspace:*",
57
+ "@types/node": "^20.0.0",
58
+ esbuild: "^0.23.0",
59
+ typescript: "^5.0.0"
60
+ },
61
+ engines: {
62
+ node: ">=20"
63
+ }
64
+ };
65
+
66
+ // src/instructions.ts
67
+ var INSTRUCTIONS = `Nimara is the team's work tracker. Work items have a type (epic > feature > task > subtask), a status from the project's own workflow, and a displayId like NIM-T42 that people read and type.
68
+
69
+ Start with list_orgs \u2192 list_projects \u2192 get_active_block (the committed work; position 0 is next) and list_ai_review_queue (what a person has asked an agent to do; read \`answer\` first). Use get_work_items / search_work_items for items you already know of; list_work_items only to survey.
70
+
71
+ Titles are plain language a teammate understands at a glance: what is wrong or what changes for a person, not the file, function or mechanism. No em dashes, no "Area: thing, thing" shapes. Descriptions carry the why, acceptance criteria and file paths; a spec, design or long report goes in a document (create_document) linked from the item.
72
+
73
+ A status must be one of the project's \`statuses\` from list_projects, spelled exactly; never invent one. Labels come from list_labels; do not invent those either.
74
+
75
+ When you pick up an item: update_work_item { status: <in-progress status>, agentWorking: true }. That lights its row for 15 minutes; any write or read of the item renews it, and on a long stretch with no Nimara calls, heartbeat_work_item every few minutes keeps it lit. Post a comment at real milestones. If you stop early, agentWorking: false. Moving to the last status clears it.
76
+
77
+ Mention a person in a comment as [@Name](user:<userId>) and they are notified. Append agent research to a description under the exact heading "## Research (auto)", never editing the human text above it. When you open a PR, put the displayId in its title.`;
78
+
9
79
  // ../convex/convex/_generated/api.js
10
80
  import { anyApi, componentsGeneric } from "convex/server";
11
81
  var api = anyApi;
@@ -436,7 +506,7 @@ function registerUpdateWorkItem(server) {
436
506
  "The human\u2192AI review flag. Set false to clear it after you have reviewed/enriched an item from list_ai_review_queue."
437
507
  ),
438
508
  agentWorking: z9.boolean().optional().describe(
439
- "Set true when you start working on this item: the app lights its row so the person can see it is in flight. It is a 15-minute lease that every later MCP write on the item (updates, comments) renews, so you only need to set it once at the start; set false when you stop without finishing, and moving the item to the last status clears it for you."
509
+ "Set true when you start working on this item: the app lights its row so the person can see it is in flight. It is a 15-minute lease renewed by any later MCP write on the item (updates, comments), by reading it (get_work_items, list_work_item_comments), or by heartbeat_work_item \u2014 call that every few minutes on a long task with no other Nimara calls, or the row goes quiet while you are still at it. Set false when you stop without finishing; moving the item to the last status clears it for you."
440
510
  )
441
511
  },
442
512
  annotations: {
@@ -721,18 +791,47 @@ function registerResolveScratchNote(server) {
721
791
  );
722
792
  }
723
793
 
724
- // src/tools/add-work-item-image.ts
794
+ // src/tools/heartbeat-work-item.ts
725
795
  import { z as z18 } from "zod";
796
+ function registerHeartbeatWorkItem(server) {
797
+ server.registerTool(
798
+ "heartbeat_work_item",
799
+ {
800
+ description: 'Say you are still working on an item. Renews (or starts) its 15-minute "agent working" lease and does nothing else: no comment, no activity event, no change to the item. The app lights the row while the lease is live, so on a long task call this every few minutes or every handful of tool calls \u2014 otherwise the row goes quiet while you are still at it. Reads of the item (get_work_items, list_work_item_comments) also renew a live lease, and any update or comment does; this is for the stretches where you do none of those. Cheap and idempotent.',
801
+ inputSchema: {
802
+ workItemId: z18.string().describe("workItemId of the item you are working on")
803
+ },
804
+ annotations: {
805
+ readOnlyHint: false,
806
+ destructiveHint: false,
807
+ idempotentHint: true,
808
+ openWorldHint: false
809
+ }
810
+ },
811
+ async ({ workItemId }) => {
812
+ const result = await getConvexClient().action(api.mcp.heartbeatWorkItem, {
813
+ token: getToken(),
814
+ workItemId
815
+ });
816
+ return {
817
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
818
+ };
819
+ }
820
+ );
821
+ }
822
+
823
+ // src/tools/add-work-item-image.ts
824
+ import { z as z19 } from "zod";
726
825
  function registerAddWorkItemImage(server) {
727
826
  server.registerTool(
728
827
  "add_work_item_image",
729
828
  {
730
829
  description: "Attach an externally hosted image URL to a work item. Use this when an MCP client has a screenshot, mockup, or generated image URL to preserve with the task.",
731
830
  inputSchema: {
732
- workItemId: z18.string().describe("workItemId from list_work_items"),
733
- imageUrl: z18.string().url().describe("Public or otherwise fetchable http(s) image URL"),
734
- filename: z18.string().optional().describe("Optional display filename"),
735
- altText: z18.string().optional().describe("Optional description/caption for the image")
831
+ workItemId: z19.string().describe("workItemId from list_work_items"),
832
+ imageUrl: z19.string().url().describe("Public or otherwise fetchable http(s) image URL"),
833
+ filename: z19.string().optional().describe("Optional display filename"),
834
+ altText: z19.string().optional().describe("Optional description/caption for the image")
736
835
  },
737
836
  annotations: {
738
837
  readOnlyHint: false,
@@ -754,14 +853,14 @@ function registerAddWorkItemImage(server) {
754
853
  }
755
854
 
756
855
  // src/tools/list-work-item-images.ts
757
- import { z as z19 } from "zod";
856
+ import { z as z20 } from "zod";
758
857
  function registerListWorkItemImages(server) {
759
858
  server.registerTool(
760
859
  "list_work_item_images",
761
860
  {
762
861
  description: "List image attachments for a work item, including uploaded images and externally attached MCP images. Call list_work_items first to find the workItemId.",
763
862
  inputSchema: {
764
- workItemId: z19.string().describe("workItemId from list_work_items")
863
+ workItemId: z20.string().describe("workItemId from list_work_items")
765
864
  },
766
865
  annotations: {
767
866
  readOnlyHint: true,
@@ -784,16 +883,18 @@ function registerListWorkItemImages(server) {
784
883
  }
785
884
 
786
885
  // src/tools/add-work-item-comment.ts
787
- import { z as z20 } from "zod";
886
+ import { z as z21 } from "zod";
788
887
  function registerAddWorkItemComment(server) {
789
888
  server.registerTool(
790
889
  "add_work_item_comment",
791
890
  {
792
891
  description: "Add a timestamped comment to a work item. Use this to record notes, updates, or an 'AI touched' entry instead of editing the description. Comments are stamped with the current time automatically and never overwrite each other.",
793
892
  inputSchema: {
794
- workItemId: z20.string().describe("workItemId from list_work_items"),
795
- body: z20.string().min(1).describe("Comment text (markdown supported)"),
796
- source: z20.enum(["user", "ai"]).optional().describe('Who authored it; defaults to "ai" for MCP callers')
893
+ workItemId: z21.string().describe("workItemId from list_work_items"),
894
+ body: z21.string().min(1).describe(
895
+ "Comment text (markdown supported). To pull a person into the thread, mention them as [@Name](user:<userId>) \u2014 they are notified and the app renders it as a chip. userIds come from an item's assigneeId/reviewerId; there is no member lookup tool yet, so only mention ids you have seen."
896
+ ),
897
+ source: z21.enum(["user", "ai"]).optional().describe('Who authored it; defaults to "ai" for MCP callers')
797
898
  },
798
899
  annotations: {
799
900
  readOnlyHint: false,
@@ -818,14 +919,14 @@ function registerAddWorkItemComment(server) {
818
919
  }
819
920
 
820
921
  // src/tools/list-work-item-comments.ts
821
- import { z as z21 } from "zod";
922
+ import { z as z22 } from "zod";
822
923
  function registerListWorkItemComments(server) {
823
924
  server.registerTool(
824
925
  "list_work_item_comments",
825
926
  {
826
927
  description: "List the timestamped comments on a work item, oldest first. Use this to check whether the item was already touched/commented before adding a new comment.",
827
928
  inputSchema: {
828
- workItemId: z21.string().describe("workItemId from list_work_items")
929
+ workItemId: z22.string().describe("workItemId from list_work_items")
829
930
  },
830
931
  annotations: {
831
932
  readOnlyHint: true,
@@ -848,14 +949,14 @@ function registerListWorkItemComments(server) {
848
949
  }
849
950
 
850
951
  // src/tools/list-validations.ts
851
- import { z as z22 } from "zod";
952
+ import { z as z23 } from "zod";
852
953
  function registerListValidations(server) {
853
954
  server.registerTool(
854
955
  "list_validations",
855
956
  {
856
957
  description: "List a project's validation graph: core systems and validation/test tasks with their DERIVED state (passing, failing, stale, unvalidated). A task is 'stale' when a system it covers changed since it was last validated, or an upstream dependency is no longer passing. Call list_projects first to find the projectId.",
857
958
  inputSchema: {
858
- projectId: z22.string().describe("projectId from list_projects")
959
+ projectId: z23.string().describe("projectId from list_projects")
859
960
  },
860
961
  annotations: {
861
962
  readOnlyHint: true,
@@ -876,15 +977,15 @@ function registerListValidations(server) {
876
977
  }
877
978
 
878
979
  // src/tools/record-validation.ts
879
- import { z as z23 } from "zod";
980
+ import { z as z24 } from "zod";
880
981
  function registerRecordValidation(server) {
881
982
  server.registerTool(
882
983
  "record_validation",
883
984
  {
884
985
  description: "Check off a validation task by recording a pass or fail. Stamps the task as validated 'now', clearing any stale flag until a covered system changes or an upstream dependency moves again. Get validationTaskId from list_validations.",
885
986
  inputSchema: {
886
- validationTaskId: z23.string().describe("validationTaskId from list_validations"),
887
- result: z23.enum(["pass", "fail"]).describe("Outcome of running the test")
987
+ validationTaskId: z24.string().describe("validationTaskId from list_validations"),
988
+ result: z24.enum(["pass", "fail"]).describe("Outcome of running the test")
888
989
  },
889
990
  annotations: {
890
991
  readOnlyHint: false,
@@ -908,14 +1009,14 @@ function registerRecordValidation(server) {
908
1009
  }
909
1010
 
910
1011
  // src/tools/mark-system-changed.ts
911
- import { z as z24 } from "zod";
1012
+ import { z as z25 } from "zod";
912
1013
  function registerMarkSystemChanged(server) {
913
1014
  server.registerTool(
914
1015
  "mark_system_changed",
915
1016
  {
916
1017
  description: "Mark a core system as changed. This is the single action that invalidates testing: every validation task that covers this system (and everything transitively depending on those tasks) immediately becomes 'stale' and needs revalidation. Get systemId from list_validations.",
917
1018
  inputSchema: {
918
- systemId: z24.string().describe("systemId from list_validations")
1019
+ systemId: z25.string().describe("systemId from list_validations")
919
1020
  },
920
1021
  annotations: {
921
1022
  readOnlyHint: false,
@@ -938,16 +1039,16 @@ function registerMarkSystemChanged(server) {
938
1039
  }
939
1040
 
940
1041
  // src/tools/create-system.ts
941
- import { z as z25 } from "zod";
1042
+ import { z as z26 } from "zod";
942
1043
  function registerCreateSystem(server) {
943
1044
  server.registerTool(
944
1045
  "create_system",
945
1046
  {
946
1047
  description: "Create a core system in a project \u2014 a subsystem (e.g. Auth, Payments, Sync) whose change should invalidate the validation tasks that cover it. Returns the new systemId.",
947
1048
  inputSchema: {
948
- projectId: z25.string().describe("projectId from list_projects"),
949
- name: z25.string().min(1).describe("Short system name, e.g. 'Auth'"),
950
- description: z25.string().optional().describe("Optional details")
1049
+ projectId: z26.string().describe("projectId from list_projects"),
1050
+ name: z26.string().min(1).describe("Short system name, e.g. 'Auth'"),
1051
+ description: z26.string().optional().describe("Optional details")
951
1052
  },
952
1053
  annotations: {
953
1054
  readOnlyHint: false,
@@ -970,20 +1071,20 @@ function registerCreateSystem(server) {
970
1071
  }
971
1072
 
972
1073
  // src/tools/create-validation-task.ts
973
- import { z as z26 } from "zod";
1074
+ import { z as z27 } from "zod";
974
1075
  function registerCreateValidationTask(server) {
975
1076
  server.registerTool(
976
1077
  "create_validation_task",
977
1078
  {
978
1079
  description: "Create a validation/test task in a project. After creating it, use add_system_to_task to declare which systems it exercises (so it goes stale when they change) and add_validation_dependency to order it after other tasks. Returns the new validationTaskId.",
979
1080
  inputSchema: {
980
- projectId: z26.string().describe("projectId from list_projects"),
981
- title: z26.string().min(1).describe("What this test validates"),
982
- description: z26.string().optional().describe("Optional steps / details"),
983
- kind: z26.enum(["auto", "manual"]).optional().describe(
1081
+ projectId: z27.string().describe("projectId from list_projects"),
1082
+ title: z27.string().min(1).describe("What this test validates"),
1083
+ description: z27.string().optional().describe("Optional steps / details"),
1084
+ kind: z27.enum(["auto", "manual"]).optional().describe(
984
1085
  "'auto' if runnable by a test runner, 'manual' if a human checks it. Defaults to manual."
985
1086
  ),
986
- workItemId: z26.string().optional().describe(
1087
+ workItemId: z27.string().optional().describe(
987
1088
  "Optional workItemId to link this test to a feature for traceability"
988
1089
  )
989
1090
  },
@@ -1008,15 +1109,15 @@ function registerCreateValidationTask(server) {
1008
1109
  }
1009
1110
 
1010
1111
  // src/tools/add-system-to-task.ts
1011
- import { z as z27 } from "zod";
1112
+ import { z as z28 } from "zod";
1012
1113
  function registerAddSystemToTask(server) {
1013
1114
  server.registerTool(
1014
1115
  "add_system_to_task",
1015
1116
  {
1016
1117
  description: "Declare that a validation task COVERS (exercises) a system. Once linked, the task becomes 'stale' whenever that system is marked changed. Idempotent. Both IDs come from list_validations and must be in the same project.",
1017
1118
  inputSchema: {
1018
- validationTaskId: z27.string().describe("validationTaskId from list_validations"),
1019
- systemId: z27.string().describe("systemId from list_validations")
1119
+ validationTaskId: z28.string().describe("validationTaskId from list_validations"),
1120
+ systemId: z28.string().describe("systemId from list_validations")
1020
1121
  },
1021
1122
  annotations: {
1022
1123
  readOnlyHint: false,
@@ -1040,15 +1141,15 @@ function registerAddSystemToTask(server) {
1040
1141
  }
1041
1142
 
1042
1143
  // src/tools/add-validation-dependency.ts
1043
- import { z as z28 } from "zod";
1144
+ import { z as z29 } from "zod";
1044
1145
  function registerAddValidationDependency(server) {
1045
1146
  server.registerTool(
1046
1147
  "add_validation_dependency",
1047
1148
  {
1048
1149
  description: "Make one validation task depend on another (validationTaskId depends on dependsOnTaskId). The dependent goes 'stale' whenever the upstream task is not passing or gets revalidated. Cycles and self-dependencies are rejected. Idempotent. Both IDs come from list_validations and must be in the same project.",
1049
1150
  inputSchema: {
1050
- validationTaskId: z28.string().describe("The dependent (downstream) task"),
1051
- dependsOnTaskId: z28.string().describe("The dependency (upstream) task it relies on")
1151
+ validationTaskId: z29.string().describe("The dependent (downstream) task"),
1152
+ dependsOnTaskId: z29.string().describe("The dependency (upstream) task it relies on")
1052
1153
  },
1053
1154
  annotations: {
1054
1155
  readOnlyHint: false,
@@ -1072,14 +1173,14 @@ function registerAddValidationDependency(server) {
1072
1173
  }
1073
1174
 
1074
1175
  // src/tools/list-labels.ts
1075
- import { z as z29 } from "zod";
1176
+ import { z as z30 } from "zod";
1076
1177
  function registerListLabels(server) {
1077
1178
  server.registerTool(
1078
1179
  "list_labels",
1079
1180
  {
1080
1181
  description: "List all labels defined in a project. Returns each label's id, name, and color. Use the labelId with add_label_to_work_item / remove_label_from_work_item.",
1081
1182
  inputSchema: {
1082
- projectId: z29.string().describe("projectId from list_projects")
1183
+ projectId: z30.string().describe("projectId from list_projects")
1083
1184
  },
1084
1185
  annotations: {
1085
1186
  readOnlyHint: true,
@@ -1099,16 +1200,16 @@ function registerListLabels(server) {
1099
1200
  }
1100
1201
 
1101
1202
  // src/tools/create-label.ts
1102
- import { z as z30 } from "zod";
1203
+ import { z as z31 } from "zod";
1103
1204
  function registerCreateLabel(server) {
1104
1205
  server.registerTool(
1105
1206
  "create_label",
1106
1207
  {
1107
1208
  description: "Apply-or-seed a label. Returns the existing label if the name is already taken (idempotent), and otherwise creates it ONLY if the name is one of the curated ones. Any other new name is REFUSED \u2014 the reply carries `refused: true`, the reason, and `available`, the project's existing labels. Agents apply labels; they do not invent them, because a near-duplicate of an existing label splits the vocabulary silently. Prefer list_labels first. Colors are ignored for curated names so the vocabulary looks the same in every project.",
1108
1209
  inputSchema: {
1109
- projectId: z30.string().describe("projectId from list_projects"),
1110
- name: z30.string().min(1).describe("Label name, unique within the project"),
1111
- color: z30.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("Hex color like #2563eb. Defaults to a neutral slate.")
1210
+ projectId: z31.string().describe("projectId from list_projects"),
1211
+ name: z31.string().min(1).describe("Label name, unique within the project"),
1212
+ color: z31.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("Hex color like #2563eb. Defaults to a neutral slate.")
1112
1213
  },
1113
1214
  annotations: {
1114
1215
  readOnlyHint: false,
@@ -1130,15 +1231,15 @@ function registerCreateLabel(server) {
1130
1231
  }
1131
1232
 
1132
1233
  // src/tools/add-label-to-work-item.ts
1133
- import { z as z31 } from "zod";
1234
+ import { z as z32 } from "zod";
1134
1235
  function registerAddLabelToWorkItem(server) {
1135
1236
  server.registerTool(
1136
1237
  "add_label_to_work_item",
1137
1238
  {
1138
1239
  description: "Attach a label to a work item (idempotent). The label and work item must be in the same project. Get labelIds from list_labels / create_label.",
1139
1240
  inputSchema: {
1140
- workItemId: z31.string().describe("workItemId from list_work_items"),
1141
- labelId: z31.string().describe("labelId from list_labels or create_label")
1241
+ workItemId: z32.string().describe("workItemId from list_work_items"),
1242
+ labelId: z32.string().describe("labelId from list_labels or create_label")
1142
1243
  },
1143
1244
  annotations: {
1144
1245
  readOnlyHint: false,
@@ -1161,15 +1262,15 @@ function registerAddLabelToWorkItem(server) {
1161
1262
  }
1162
1263
 
1163
1264
  // src/tools/remove-label-from-work-item.ts
1164
- import { z as z32 } from "zod";
1265
+ import { z as z33 } from "zod";
1165
1266
  function registerRemoveLabelFromWorkItem(server) {
1166
1267
  server.registerTool(
1167
1268
  "remove_label_from_work_item",
1168
1269
  {
1169
1270
  description: "Remove a label from a work item (idempotent \u2014 a no-op if it wasn't attached).",
1170
1271
  inputSchema: {
1171
- workItemId: z32.string().describe("workItemId from list_work_items"),
1172
- labelId: z32.string().describe("labelId from list_labels")
1272
+ workItemId: z33.string().describe("workItemId from list_work_items"),
1273
+ labelId: z33.string().describe("labelId from list_labels")
1173
1274
  },
1174
1275
  annotations: {
1175
1276
  readOnlyHint: false,
@@ -1192,14 +1293,14 @@ function registerRemoveLabelFromWorkItem(server) {
1192
1293
  }
1193
1294
 
1194
1295
  // src/tools/list-milestones.ts
1195
- import { z as z33 } from "zod";
1296
+ import { z as z34 } from "zod";
1196
1297
  function registerListMilestones(server) {
1197
1298
  server.registerTool(
1198
1299
  "list_milestones",
1199
1300
  {
1200
1301
  description: "List all milestones in a project. Returns each milestone's id, name, description, dueDate (unix ms), and status. Use the milestoneId with add_item_to_milestone / remove_item_from_milestone.",
1201
1302
  inputSchema: {
1202
- projectId: z33.string().describe("projectId from list_projects")
1303
+ projectId: z34.string().describe("projectId from list_projects")
1203
1304
  },
1204
1305
  annotations: {
1205
1306
  readOnlyHint: true,
@@ -1219,17 +1320,17 @@ function registerListMilestones(server) {
1219
1320
  }
1220
1321
 
1221
1322
  // src/tools/create-milestone.ts
1222
- import { z as z34 } from "zod";
1323
+ import { z as z35 } from "zod";
1223
1324
  function registerCreateMilestone(server) {
1224
1325
  server.registerTool(
1225
1326
  "create_milestone",
1226
1327
  {
1227
1328
  description: "Create a milestone in a project. Returns the milestoneId. Good for grouping work into phases (e.g. 'Phase 1 \u2014 Web', 'Phase 2 \u2014 Native').",
1228
1329
  inputSchema: {
1229
- projectId: z34.string().describe("projectId from list_projects"),
1230
- name: z34.string().min(1).describe("Milestone name"),
1231
- description: z34.string().optional().describe("Optional markdown description"),
1232
- dueDate: z34.number().optional().describe("Optional due date as a unix timestamp in milliseconds")
1330
+ projectId: z35.string().describe("projectId from list_projects"),
1331
+ name: z35.string().min(1).describe("Milestone name"),
1332
+ description: z35.string().optional().describe("Optional markdown description"),
1333
+ dueDate: z35.number().optional().describe("Optional due date as a unix timestamp in milliseconds")
1233
1334
  },
1234
1335
  annotations: {
1235
1336
  readOnlyHint: false,
@@ -1251,15 +1352,15 @@ function registerCreateMilestone(server) {
1251
1352
  }
1252
1353
 
1253
1354
  // src/tools/add-item-to-milestone.ts
1254
- import { z as z35 } from "zod";
1355
+ import { z as z36 } from "zod";
1255
1356
  function registerAddItemToMilestone(server) {
1256
1357
  server.registerTool(
1257
1358
  "add_item_to_milestone",
1258
1359
  {
1259
1360
  description: "Associate a work item with a milestone (idempotent). Both must be in the same project.",
1260
1361
  inputSchema: {
1261
- milestoneId: z35.string().describe("milestoneId from list_milestones or create_milestone"),
1262
- workItemId: z35.string().describe("workItemId from list_work_items")
1362
+ milestoneId: z36.string().describe("milestoneId from list_milestones or create_milestone"),
1363
+ workItemId: z36.string().describe("workItemId from list_work_items")
1263
1364
  },
1264
1365
  annotations: {
1265
1366
  readOnlyHint: false,
@@ -1285,15 +1386,15 @@ function registerAddItemToMilestone(server) {
1285
1386
  }
1286
1387
 
1287
1388
  // src/tools/remove-item-from-milestone.ts
1288
- import { z as z36 } from "zod";
1389
+ import { z as z37 } from "zod";
1289
1390
  function registerRemoveItemFromMilestone(server) {
1290
1391
  server.registerTool(
1291
1392
  "remove_item_from_milestone",
1292
1393
  {
1293
1394
  description: "Remove a work item's association with a milestone (idempotent \u2014 a no-op if it wasn't associated).",
1294
1395
  inputSchema: {
1295
- milestoneId: z36.string().describe("milestoneId from list_milestones"),
1296
- workItemId: z36.string().describe("workItemId from list_work_items")
1396
+ milestoneId: z37.string().describe("milestoneId from list_milestones"),
1397
+ workItemId: z37.string().describe("workItemId from list_work_items")
1297
1398
  },
1298
1399
  annotations: {
1299
1400
  readOnlyHint: false,
@@ -1320,10 +1421,14 @@ function registerRemoveItemFromMilestone(server) {
1320
1421
 
1321
1422
  // src/server.ts
1322
1423
  function createServer() {
1323
- const server = new McpServer({
1324
- name: "nimara",
1325
- version: "0.1.0"
1326
- });
1424
+ const server = new McpServer(
1425
+ {
1426
+ name: "nimara",
1427
+ version: package_default.version
1428
+ },
1429
+ // Sent at connect time, before any tool is read (NIM-T189).
1430
+ { instructions: INSTRUCTIONS }
1431
+ );
1327
1432
  registerListOrgs(server);
1328
1433
  registerListProjects(server);
1329
1434
  registerListWorkItems(server);
@@ -1342,6 +1447,7 @@ function createServer() {
1342
1447
  registerListProjectLinks(server);
1343
1448
  registerListScratchNotes(server);
1344
1449
  registerResolveScratchNote(server);
1450
+ registerHeartbeatWorkItem(server);
1345
1451
  registerAddWorkItemImage(server);
1346
1452
  registerListWorkItemImages(server);
1347
1453
  registerAddWorkItemComment(server);
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/server.ts", "../../convex/convex/_generated/api.js", "../src/convex.ts", "../src/tools/list-orgs.ts", "../src/tools/list-projects.ts", "../src/tools/list-work-items.ts", "../src/tools/get-work-items.ts", "../src/tools/search-work-items.ts", "../src/tools/list-ai-review-queue.ts", "../src/tools/get-active-block.ts", "../src/tools/create-work-item.ts", "../src/tools/titleGuidance.ts", "../src/tools/statusGuidance.ts", "../../convex/convex/lib/descriptionLimits.ts", "../src/tools/descriptionGuidance.ts", "../src/tools/create-project.ts", "../src/tools/update-work-item.ts", "../src/tools/researchFormat.ts", "../src/tools/move-work-item.ts", "../src/tools/create-document.ts", "../src/tools/update-document.ts", "../src/tools/list-documents.ts", "../src/tools/create-project-link.ts", "../src/tools/list-project-links.ts", "../src/tools/list-scratch-notes.ts", "../src/tools/resolve-scratch-note.ts", "../src/tools/add-work-item-image.ts", "../src/tools/list-work-item-images.ts", "../src/tools/add-work-item-comment.ts", "../src/tools/list-work-item-comments.ts", "../src/tools/list-validations.ts", "../src/tools/record-validation.ts", "../src/tools/mark-system-changed.ts", "../src/tools/create-system.ts", "../src/tools/create-validation-task.ts", "../src/tools/add-system-to-task.ts", "../src/tools/add-validation-dependency.ts", "../src/tools/list-labels.ts", "../src/tools/create-label.ts", "../src/tools/add-label-to-work-item.ts", "../src/tools/remove-label-from-work-item.ts", "../src/tools/list-milestones.ts", "../src/tools/create-milestone.ts", "../src/tools/add-item-to-milestone.ts", "../src/tools/remove-item-from-milestone.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n// MCP stdio transport reserves stdout for JSON-RPC frames. Any library that\n// writes to stdout (e.g. the Convex client's `[CONVEX A(uth)]` info logs)\n// corrupts the stream. Redirect console.* to stderr before anything else loads.\nfor (const m of [\"log\", \"info\", \"warn\", \"debug\"] as const) {\n console[m] = (...args: unknown[]) => console.error(...args);\n}\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\n\nasync function main() {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // Server runs until stdin closes; nothing else to do here.\n}\n\nmain().catch((err) => {\n console.error(\"nimara-mcp: fatal error\", err);\n process.exit(1);\n});\n", "import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerListOrgs } from \"./tools/list-orgs.js\";\nimport { registerListProjects } from \"./tools/list-projects.js\";\nimport { registerListWorkItems } from \"./tools/list-work-items.js\";\nimport { registerGetWorkItems } from \"./tools/get-work-items.js\";\nimport { registerSearchWorkItems } from \"./tools/search-work-items.js\";\nimport { registerListAiReviewQueue } from \"./tools/list-ai-review-queue.js\";\nimport { registerGetActiveBlock } from \"./tools/get-active-block.js\";\nimport { registerCreateWorkItem } from \"./tools/create-work-item.js\";\nimport { registerCreateProject } from \"./tools/create-project.js\";\nimport { registerUpdateWorkItem } from \"./tools/update-work-item.js\";\nimport { registerMoveWorkItem } from \"./tools/move-work-item.js\";\nimport { registerCreateDocument } from \"./tools/create-document.js\";\nimport { registerUpdateDocument } from \"./tools/update-document.js\";\nimport { registerListDocuments } from \"./tools/list-documents.js\";\nimport { registerCreateProjectLink } from \"./tools/create-project-link.js\";\nimport { registerListProjectLinks } from \"./tools/list-project-links.js\";\nimport { registerListScratchNotes } from \"./tools/list-scratch-notes.js\";\nimport { registerResolveScratchNote } from \"./tools/resolve-scratch-note.js\";\nimport { registerAddWorkItemImage } from \"./tools/add-work-item-image.js\";\nimport { registerListWorkItemImages } from \"./tools/list-work-item-images.js\";\nimport { registerAddWorkItemComment } from \"./tools/add-work-item-comment.js\";\nimport { registerListWorkItemComments } from \"./tools/list-work-item-comments.js\";\nimport { registerListValidations } from \"./tools/list-validations.js\";\nimport { registerRecordValidation } from \"./tools/record-validation.js\";\nimport { registerMarkSystemChanged } from \"./tools/mark-system-changed.js\";\nimport { registerCreateSystem } from \"./tools/create-system.js\";\nimport { registerCreateValidationTask } from \"./tools/create-validation-task.js\";\nimport { registerAddSystemToTask } from \"./tools/add-system-to-task.js\";\nimport { registerAddValidationDependency } from \"./tools/add-validation-dependency.js\";\nimport { registerListLabels } from \"./tools/list-labels.js\";\nimport { registerCreateLabel } from \"./tools/create-label.js\";\nimport { registerAddLabelToWorkItem } from \"./tools/add-label-to-work-item.js\";\nimport { registerRemoveLabelFromWorkItem } from \"./tools/remove-label-from-work-item.js\";\nimport { registerListMilestones } from \"./tools/list-milestones.js\";\nimport { registerCreateMilestone } from \"./tools/create-milestone.js\";\nimport { registerAddItemToMilestone } from \"./tools/add-item-to-milestone.js\";\nimport { registerRemoveItemFromMilestone } from \"./tools/remove-item-from-milestone.js\";\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: \"nimara\",\n version: \"0.1.0\",\n });\n\n registerListOrgs(server);\n registerListProjects(server);\n registerListWorkItems(server);\n registerGetWorkItems(server);\n registerSearchWorkItems(server);\n registerListAiReviewQueue(server);\n registerGetActiveBlock(server);\n registerCreateProject(server);\n registerCreateWorkItem(server);\n registerUpdateWorkItem(server);\n registerMoveWorkItem(server);\n registerCreateDocument(server);\n registerUpdateDocument(server);\n registerListDocuments(server);\n registerCreateProjectLink(server);\n registerListProjectLinks(server);\n registerListScratchNotes(server);\n registerResolveScratchNote(server);\n registerAddWorkItemImage(server);\n registerListWorkItemImages(server);\n registerAddWorkItemComment(server);\n registerListWorkItemComments(server);\n\n // Validation / test-dependency framework\n registerListValidations(server);\n registerRecordValidation(server);\n registerMarkSystemChanged(server);\n registerCreateSystem(server);\n registerCreateValidationTask(server);\n registerAddSystemToTask(server);\n registerAddValidationDependency(server);\n\n // Labels & milestones\n registerListLabels(server);\n registerCreateLabel(server);\n registerAddLabelToWorkItem(server);\n registerRemoveLabelFromWorkItem(server);\n registerListMilestones(server);\n registerCreateMilestone(server);\n registerAddItemToMilestone(server);\n registerRemoveItemFromMilestone(server);\n\n return server;\n}\n", "/* eslint-disable */\n/**\n * Generated `api` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\n/**\n * A utility for referencing Convex functions in your app's API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = api.myModule.myFunction;\n * ```\n */\nexport const api = anyApi;\nexport const internal = anyApi;\nexport const components = componentsGeneric();\n", "import { ConvexHttpClient } from \"convex/browser\";\n\nlet cachedClient: ConvexHttpClient | null = null;\n\nexport function getConvexClient(): ConvexHttpClient {\n if (cachedClient) return cachedClient;\n\n const url = process.env.NIMARA_CONVEX_URL;\n if (!url) {\n throw new Error(\n \"NIMARA_CONVEX_URL is not set. Add it to your MCP client config (e.g. Claude Desktop's mcpServers env block).\"\n );\n }\n\n cachedClient = new ConvexHttpClient(url);\n return cachedClient;\n}\n\nexport function getToken(): string {\n const token = process.env.NIMARA_TOKEN;\n if (!token) {\n throw new Error(\n \"NIMARA_TOKEN is not set. Generate a personal access token from Nimara \u2192 Settings \u2192 Personal Access Tokens, then add it to your MCP client config.\"\n );\n }\n return token;\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListOrgs(server: McpServer): void {\n server.registerTool(\n \"list_orgs\",\n {\n description:\n \"List all organizations (and the personal workspace) the authenticated user belongs to. Use this first to discover org IDs needed by other tools.\",\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async () => {\n const client = getConvexClient();\n const orgs = await client.action(api.mcp.listOrgs, { token: getToken() });\n return {\n content: [{ type: \"text\", text: JSON.stringify(orgs, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListProjects(server: McpServer): void {\n server.registerTool(\n \"list_projects\",\n {\n description:\n \"List projects in a given organization. Call list_orgs first to find \" +\n \"the orgId. Each project includes `statuses` \u2014 its workflow in board \" +\n \"order. Read that before setting a status on any item: those names are \" +\n \"the only accepted values, and anything else is rejected.\",\n inputSchema: { orgId: z.string().describe(\"orgId from list_orgs\") },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ orgId }) => {\n const client = getConvexClient();\n const projects = await client.action(api.mcp.listProjects, {\n token: getToken(),\n orgId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(projects, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItems(server: McpServer): void {\n server.registerTool(\n \"list_work_items\",\n {\n // The description is the only place a model learns paging exists, so it\n // states the shape of the response and what to do when hasMore is true.\n description:\n \"List non-archived work items in a project, oldest-created first. Returns \" +\n \"{ items, nextCursor, hasMore }. Long descriptions are previewed \u2014 an \" +\n \"item with descriptionTruncated: true has more text, readable via \" +\n \"fullDescriptions. When hasMore is true, call again with cursor set to \" +\n \"nextCursor to get the next page \u2014 the FIRST page is the OLDEST items, so \" +\n \"recently created ones are on the LAST page and you have not seen the \" +\n \"project until hasMore is false. Narrow with status/type/parentId/\" +\n \"needsReview rather than paging and filtering yourself. If you already \" +\n \"know which items you want, use get_work_items instead \u2014 it takes \" +\n \"displayIds like NIM-T75 and costs a fraction of a list. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n status: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n \"Only items in these statuses. Names come from the project's \" +\n \"statusOrder (e.g. 'In Progress'). One name or a list.\",\n ),\n type: z\n .union([\n z.enum([\"epic\", \"feature\", \"task\", \"subtask\"]),\n z.array(z.enum([\"epic\", \"feature\", \"task\", \"subtask\"])),\n ])\n .optional()\n .describe(\"Only items of these types. One type or a list.\"),\n parentId: z\n .string()\n .optional()\n .describe(\n \"Only direct children of this workItemId. One level, not the whole subtree.\",\n ),\n needsReview: z\n .boolean()\n .optional()\n .describe(\n \"true returns only items flagged needsReview; false only unflagged ones. \" +\n \"Omit for both.\",\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe(\"Items per page (default 50, max 200).\"),\n cursor: z\n .number()\n .optional()\n .describe(\n \"nextCursor from the previous page. Omit for the first page.\",\n ),\n fullDescriptions: z\n .boolean()\n .optional()\n .describe(\n \"Return descriptions in full instead of previewed. Costly on large \" +\n \"projects \u2014 prefer paging, or read one item at a time.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({\n projectId,\n limit,\n cursor,\n fullDescriptions,\n status,\n type,\n parentId,\n needsReview,\n }) => {\n const page = await getConvexClient().action(api.mcp.listWorkItems, {\n token: getToken(),\n projectId,\n limit,\n cursor,\n fullDescriptions,\n // Accepting a bare string as well as a list is what keeps a model from\n // failing validation on the overwhelmingly common single-value case.\n status:\n status === undefined\n ? undefined\n : Array.isArray(status)\n ? status\n : [status],\n type:\n type === undefined ? undefined : Array.isArray(type) ? type : [type],\n parentId,\n needsReview,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(page, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerGetWorkItems(server: McpServer): void {\n server.registerTool(\n \"get_work_items\",\n {\n // Written to be chosen *over* list_work_items whenever the caller already\n // knows which items it wants \u2014 that is the whole point of the tool, and\n // the description is the only place a model learns it.\n description:\n \"Read specific work items by id \u2014 the cheap way to re-read items you \" +\n \"already know about. Prefer this over list_work_items whenever you have \" +\n \"a displayId (e.g. NIM-T75) or a workItemId: listing a project returns \" +\n \"every item and its description, which is orders of magnitude more data. \" +\n \"Accepts up to 50 ids per call and always returns descriptions in full. \" +\n \"Returns { items, notFound }; ids in notFound either do not exist or are \" +\n \"not readable by this token. displayIds require projectId (they are \" +\n \"unique per project, not globally); workItemIds do not.\",\n inputSchema: {\n displayIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Human-facing ids like ['NIM-T75', 'NIM-F27']. Case-insensitive. \" +\n \"Requires projectId.\",\n ),\n workItemIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Raw workItemIds, as returned by create_work_item or list_work_items.\",\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n \"projectId from list_projects. Required only when passing displayIds.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ displayIds, workItemIds, projectId }) => {\n const result = await getConvexClient().action(api.mcp.getWorkItems, {\n token: getToken(),\n displayIds,\n workItemIds,\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerSearchWorkItems(server: McpServer): void {\n server.registerTool(\n \"search_work_items\",\n {\n // The point of this description is to stop a model reaching for\n // list_work_items when it is looking for something by name. Listing a\n // project to find one item is the expensive mistake this tool exists to\n // prevent.\n description:\n \"Find work items in a project by title. Use this to answer 'does an \" +\n \"item for X already exist?' \u2014 listing the whole project and filtering \" +\n \"yourself is far more expensive and, because the first page is the \" +\n \"OLDEST items, easy to get wrong. Matches TITLES only, not \" +\n \"descriptions. Returns { items, query } with descriptions previewed; \" +\n \"once you know which item you want, get_work_items returns it in full. \" +\n \"Capped at 25 results \u2014 narrow the query rather than paging. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n q: z\n .string()\n .min(1)\n .describe(\n \"Words to match against item titles, e.g. 'mobile modal' or \" +\n \"'shortcut'. Matching is full-text, so word order does not matter.\",\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(25)\n .optional()\n .describe(\"Maximum results (default and maximum 25).\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ projectId, q, limit }) => {\n const result = await getConvexClient().action(api.mcp.searchWorkItems, {\n token: getToken(),\n projectId,\n q,\n limit,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListAiReviewQueue(server: McpServer): void {\n server.registerTool(\n \"list_ai_review_queue\",\n {\n description:\n \"List work items in a project that a human has flagged for AI review \" +\n \"(aiReviewRequested). Descriptions come back in full here, since \" +\n \"enrichment needs the whole text. Each item also carries recentComments \" +\n \"(the last few, oldest first) and, when a person has written one, \" +\n \"`answer`: the newest human comment. READ `answer` FIRST. When you \" +\n \"flagged an item with a question and it is back in this queue, `answer` \" +\n \"is the person's reply to that question; act on it rather than asking \" +\n \"again. Returns { items, nextCursor, hasMore } \u2014 when hasMore is true, \" +\n \"call again with cursor set to nextCursor. Process each item, then clear \" +\n \"its flag by calling update_work_item with aiReviewRequested: false. \" +\n \"Call list_projects first to find the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe(\"Items per page (default 50, max 200).\"),\n cursor: z\n .number()\n .optional()\n .describe(\n \"nextCursor from the previous page. Omit for the first page.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId, limit, cursor }) => {\n const page = await getConvexClient().action(api.mcp.listAiReviewQueue, {\n token: getToken(),\n projectId,\n limit,\n cursor,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(page, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerGetActiveBlock(server: McpServer): void {\n server.registerTool(\n \"get_active_block\",\n {\n description:\n \"The project's ACTIVE BLOCK: the small, ordered set of work a person has \" +\n \"committed to right now. Call this BEFORE list_work_items when deciding what \" +\n \"to work on \u2014 position 0 is the next thing to do, and the wider backlog is \" +\n \"not on the table until the block is empty. Each item carries a lane: \" +\n \"'person' means a human owes it (flagged for review, or parked in a Review \" +\n \"status) and you should not touch it; 'agent' means a human asked an agent \" +\n \"to act on it, so it is yours first, and it carries recentComments and \" +\n \"`answer` (the newest human comment: read it before anything else); \" +\n \"'open' is uncommitted-to-anyone work in \" +\n \"priority order; 'done' is finished. Returns null when the project has no \" +\n \"active block, in which case fall back to list_work_items. Descriptions are \" +\n \"previewed; use get_work_items for the full text of an item you pick up. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId }) => {\n const block = await getConvexClient().action(api.mcp.getActiveBlock, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(block, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\nimport { TITLE_GUIDANCE } from \"./titleGuidance.js\";\nimport { STATUS_GUIDANCE } from \"./statusGuidance.js\";\nimport { DESCRIPTION_GUIDANCE, DESCRIPTION_MAX } from \"./descriptionGuidance.js\";\n\nexport function registerCreateWorkItem(server: McpServer): void {\n server.registerTool(\n \"create_work_item\",\n {\n description:\n \"Create a new work item in a project. Hierarchy rules: epics live at the root; features go under epics; tasks go under epics or features (or root); subtasks must go under a task. Returns the new workItemId and its display ID (e.g. NIM-42).\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n type: z\n .enum([\"epic\", \"feature\", \"task\", \"subtask\"])\n .describe(\"Item type \u2014 drives hierarchy validation\"),\n title: z.string().min(1).describe(TITLE_GUIDANCE),\n description: z.string().max(DESCRIPTION_MAX).optional().describe(DESCRIPTION_GUIDANCE),\n parentId: z\n .string()\n .optional()\n .describe(\n \"workItemId of the parent. Required for subtask, optional otherwise.\",\n ),\n status: z\n .string()\n .optional()\n .describe(\n STATUS_GUIDANCE,\n ),\n priority: z\n .enum([\"p0\", \"p1\", \"p2\", \"p3\"])\n .optional()\n .describe(\"p0 highest, p3 lowest. Defaults to p2.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const result = await client.action(api.mcp.createWorkItem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "/**\n * What a work-item title should read like, stated once.\n *\n * This exists because \"Short, descriptive title\" \u2014 the previous guidance on\n * `create_work_item` \u2014 is satisfied by \"Fix hasChildren computation in\n * list.tsx\". That is short and it does describe something, and it is unreadable\n * to anyone who has not just been in that file. Titles are what a board shows;\n * a board full of symbol names cannot be scanned.\n *\n * The em-dash and verbosity rules come from NIM-T117, which Jordan filed\n * before this and which asked for exactly that: \"Remove the em dash and\n * other verbose title that make it hard to read.\"\n *\n * Shared by `create_work_item` and `update_work_item` so the rule cannot hold\n * on one path and not the other \u2014 retitling is the same act as titling, and\n * `update_work_item` previously carried no guidance at all.\n */\nexport const TITLE_GUIDANCE =\n \"A title a teammate can understand at a glance, without opening the item or \" +\n \"knowing the codebase. Say what is wrong or what changes FOR A PERSON, in \" +\n \"plain words \u2014 not the mechanism, the file, or the symbol. \" +\n 'Good: \"Sorted list shows an expand arrow that does nothing\". ' +\n 'Bad: \"Fix hasChildren computation in list.tsx\". ' +\n 'Good: \"Long titles wrap to three lines and are hard to read\". ' +\n 'Bad: \"Adjust COLUMNS.title min-width constant\". ' +\n \"Prefer ordinary words over internal abbreviations, and only name a file, \" +\n \"function or identifier when it genuinely is the clearest way to say it \" +\n \"(a tool or endpoint the user calls by name, for instance). No ticket \" +\n \"prefixes or status markers \u2014 the board renders those already. Root cause, \" +\n \"file paths, and reproduction steps belong in the description, which has \" +\n \"room for them. \" +\n \"Keep it to one plain clause. Do NOT use an em dash, and do not use the \" +\n '\"Area: thing, other thing\" shape \u2014 both are ways of stapling a second ' +\n \"title on and they are what makes these hard to read. \" +\n 'Bad: \"Gantt: tighten row density, match app typography, stop the chart ' +\n 'falling short of its container\". ' +\n 'Good: \"Gantt chart looks nothing like the rest of the app\". ' +\n \"If the title needs a comma-spliced list to be accurate, that is a sign the \" +\n \"item is really several items, not a sign it needs a longer title.\";\n", "/**\n * How to choose a status, stated once.\n *\n * The rule the tools already stated \u2014 \"a status name from the project's\n * statusOrder\" \u2014 referred to data no tool returned. An agent could not read a\n * project's workflow, so it guessed a plausible-sounding name, and the guess\n * was frequently \"In Review\" on boards whose workflow only ever had \"Review\".\n * `list_projects` now returns `statuses`, which is what makes this instruction\n * followable rather than aspirational.\n *\n * The second half matters as much as the first. A status is POSITIONAL \u2014 it is\n * the board column \u2014 so inventing one is not a labelling choice, it reshapes\n * the board and every status chart that aggregates across projects. Anything\n * that describes an item without saying where it sits in the flow is a label:\n * `list_labels`, `create_label` and `add_label_to_work_item` exist for exactly\n * that, and cost nothing to add. This is NIM-T49's decision, held to.\n *\n * Shared by `create_work_item` and `update_work_item`. `update_work_item.status`\n * previously carried no guidance at all, which is the path most likely to move\n * an item to an invented status.\n */\nexport const STATUS_GUIDANCE =\n \"Must be one of the names in the project's `statuses`, returned by \" +\n \"list_projects. Read it rather than guessing \u2014 a status is the board \" +\n \"column, so a name the workflow does not have is rejected, and before that \" +\n \"check existed such items rendered in the first column while claiming \" +\n \"otherwise. Match the existing name exactly, including its wording: if the \" +\n \"workflow says \\\"Review\\\", do not write \\\"In Review\\\". \" +\n \"Do NOT invent a status to capture something about an item. Statuses are \" +\n \"shared across the whole project and aggregated on the dashboard, so each \" +\n \"new one is a permanent extra band there. Anything that describes an item \" +\n \"rather than locating it in the flow belongs in a LABEL \u2014 see create_label \" +\n \"and add_label_to_work_item. Defaults to the first status when omitted.\";\n", "/**\n * The two sizes a work item description is measured against. Kept free of\n * Convex imports so the web app and the MCP package can share the numbers.\n *\n * PREVIEW is what the row carries so lists never join the body\n * (lib/workItemBody.ts). MAX is a sanity cap, not a product decision: no\n * task written by hand comes near it, but an agent pasting a log or a whole\n * research report into a description would \u2014 and that belongs in a document.\n * Descriptions averaged 14 KB when the cap was chosen; 32 KB is roughly\n * 5,000 words, eight pages.\n */\nexport const DESCRIPTION_PREVIEW_CHARS = 500;\nexport const DESCRIPTION_MAX_CHARS = 32_000;\n\n/** Where a description's length stands, for an error or a counter. */\nexport const DESCRIPTION_TOO_LONG =\n `A description can be at most ${DESCRIPTION_MAX_CHARS.toLocaleString(\"en-US\")} characters. ` +\n \"Put specs, research and long reports in a document and link it to the item.\";\n", "import { DESCRIPTION_MAX_CHARS } from \"@nimara/convex/convex/lib/descriptionLimits.js\";\n\n/**\n * What a description is for, and how big it may be, stated once and shared\n * by `create_work_item` and `update_work_item` the way TITLE_GUIDANCE is.\n *\n * The cap is enforced server-side in writeDescription; the zod max here\n * only means an agent hears about it before the round-trip. The guidance is\n * the real lever: descriptions averaged 14 KB because agents used them as\n * the place to put everything, and the row split (lib/workItemBody.ts) made\n * that cheap but not right \u2014 a document is what other items can link to.\n */\nexport const DESCRIPTION_MAX = DESCRIPTION_MAX_CHARS;\n\nexport const DESCRIPTION_GUIDANCE =\n \"Markdown. The what and the why: the problem, acceptance criteria, \" +\n \"reproduction steps, file paths, root cause. Keep it to what someone \" +\n \"picking the item up needs. A spec, a design, research, or a long report \" +\n \"goes in a document (create_document) linked from here, not inline. \" +\n `At most ${DESCRIPTION_MAX_CHARS.toLocaleString(\"en-US\")} characters.`;\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateProject(server: McpServer): void {\n server.registerTool(\n \"create_project\",\n {\n description:\n \"Create a new project in an org. Prefix must be unique within the org and is uppercased (e.g. 'NIM' yields work items NIM-1, NIM-2\u2026). Caller becomes the project admin. Returns the new projectId.\",\n inputSchema: {\n orgId: z.string().describe(\"orgId from list_orgs\"),\n name: z.string().min(1).describe(\"Project name\"),\n prefix: z\n .string()\n .min(1)\n .max(8)\n .describe(\n \"Short uppercase prefix for work item IDs (e.g. 'NIM'). Unique per org.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\"Optional markdown description\"),\n isPrivate: z\n .boolean()\n .optional()\n .describe(\n \"If true, only explicitly added members see it. Defaults to false.\",\n ),\n workflowTemplate: z\n .enum([\"default\", \"simple\", \"kanban\", \"bug\"])\n .optional()\n .describe(\n \"Status workflow. Defaults to 'default' (Backlog/Todo/In Progress/Review/Done).\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const result = await client.action(api.mcp.createProject, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\nimport { TITLE_GUIDANCE } from \"./titleGuidance.js\";\nimport { STATUS_GUIDANCE } from \"./statusGuidance.js\";\nimport { DESCRIPTION_GUIDANCE, DESCRIPTION_MAX } from \"./descriptionGuidance.js\";\nimport { RESEARCH_FORMAT } from \"./researchFormat.js\";\n\nexport function registerUpdateWorkItem(server: McpServer): void {\n server.registerTool(\n \"update_work_item\",\n {\n description:\n \"Update an existing work item: title, description, status, priority, parent, or review flags. Any update also stamps the item as AI-touched.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n title: z.string().min(1).optional().describe(TITLE_GUIDANCE),\n description: z\n .string()\n .max(DESCRIPTION_MAX)\n .optional()\n .describe(\n \"Full markdown body, replacing what is there. \" +\n DESCRIPTION_GUIDANCE +\n \" \" +\n RESEARCH_FORMAT,\n ),\n status: z.string().optional().describe(STATUS_GUIDANCE),\n priority: z.enum([\"p0\", \"p1\", \"p2\", \"p3\"]).optional(),\n parentId: z\n .string()\n .nullable()\n .optional()\n .describe(\"New parent workItemId, null to move to root.\"),\n needsReview: z\n .boolean()\n .optional()\n .describe(\n \"Flag the item for manual human review \u2014 set true when your enrichment was thin or uncertain.\",\n ),\n reviewReason: z\n .string()\n .optional()\n .describe(\n \"Short reason the item needs manual review (shown to the human).\",\n ),\n aiReviewRequested: z\n .boolean()\n .optional()\n .describe(\n \"The human\u2192AI review flag. Set false to clear it after you have reviewed/enriched an item from list_ai_review_queue.\",\n ),\n agentWorking: z\n .boolean()\n .optional()\n .describe(\n \"Set true when you start working on this item: the app lights its row so the person can see it is in flight. It is a 15-minute lease that every later MCP write on the item (updates, comments) renews, so you only need to set it once at the start; set false when you stop without finishing, and moving the item to the last status clears it for you.\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.updateWorkItem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "/**\n * The shape of the automated research block an enrichment agent appends to a\n * work item's description.\n *\n * Two reasons this is stated here rather than left to each agent's own taste.\n *\n * The web app parses this block out of the description and renders it in its\n * own tab on the item (NIM-T125). The anchor heading is therefore a contract,\n * not a style choice: change its wording and the tab stops appearing, with the\n * text still sitting in the description and nothing failing loudly.\n *\n * And the existing blocks are decorated with emoji section markers \u2014 \uD83D\uDD0E, \uD83D\uDD17,\n * \uD83E\uDDED, \uD83C\uDF9A. They read as noise in a panel that is already labelled \"Research\",\n * they carry no information the heading does not, and they are the first thing\n * Jordan asked to remove. The parser accepts the old emoji heading so the 20\n * items already enriched keep working; nothing new should write one.\n *\n * Deliberately NOT permitted: raw HTML. The app renders this with\n * `react-markdown` and no `rehype-raw`, so HTML is stripped rather than shown \u2014\n * and turning that on would render agent-authored markup whose inputs include\n * untrusted work-item text. Mermaid fences cover the diagram case without\n * opening that door.\n */\nexport const RESEARCH_FORMAT = `When appending automated research to a description, use EXACTLY this format, \\\nafter the human-written text:\n\n---\n## Research (auto)\n\n### Findings\n- One bullet per verified fact, each naming what you checked.\n\n### Dependencies\n- Items this blocks or is blocked by, by displayId. Omit the section if none.\n\n### Duplicates\n- Existing items covering the same work, by displayId. Omit if none.\n\n### Suggested priority\nOne line. Say \"No change\" when it is already right.\n\nRules:\n- The \"## Research (auto)\" heading is EXACT and is what the app keys on to show \\\nthis in its own tab. Do not reword it, renumber its level, or translate it.\n- NO EMOJI anywhere in the block, in headings or in bullets. Older items carry \\\nemoji headings; do not copy them.\n- Omit a section rather than writing \"None found\" in it. An empty section is \\\nnoise the reader still has to read.\n- Never edit or delete the human-written text above the rule. Append only.\n- Markdown only. GFM tables are supported and are the right choice for \\\ncomparisons. Raw HTML is NOT rendered by the app and must not be used.\n- For a workflow, sequence or state machine, use a \\\\\\`\\\\\\`\\\\\\`mermaid fenced block. \\\nThat is the supported way to draw one.\n- Say what you verified and how. \"Confirmed X still returns Y (file:line)\" is \\\nworth more than a conclusion with no trail.`;\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerMoveWorkItem(server: McpServer): void {\n server.registerTool(\n \"move_work_item\",\n {\n // Everything a model needs to predict the damage has to be stated here \u2014\n // the description is the only channel it has. The consequences that are\n // NOT obvious from the name are the ones worth the tokens: the display ID\n // changes, and labels/milestones do not survive.\n description:\n \"Move a work item to a different project, taking its whole subtree \" +\n \"with it \u2014 children and grandchildren move too, and the hierarchy is \" +\n \"preserved. Both projects must be in the same organization, and you \" +\n \"need write access to both. \" +\n \"Not reversible by calling this again: the item is renumbered in the \" +\n \"destination, so NIM-T44 might become SKA-T18 and the old ID stops \" +\n \"resolving. Labels and milestone assignments are dropped, because both \" +\n \"belong to the project being left; a status the destination doesn't \" +\n \"define falls back to its first status. The response reports every \" +\n \"old \u2192 new ID plus everything that was dropped or remapped. \" +\n \"Comments, images, attached documents, PR links and history all follow \" +\n \"the item. Call list_projects first for the target projectId.\",\n inputSchema: {\n workItemId: z\n .string()\n .describe(\"workItemId from list_work_items \u2014 the item to move.\"),\n targetProjectId: z\n .string()\n .describe(\n \"projectId from list_projects \u2014 the destination. Must be in the \" +\n \"same org as the item's current project.\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n // Renumbering display IDs and deleting label/milestone links are\n // overwrites, not additions \u2014 this belongs with the tools a client\n // should prompt on rather than auto-approve.\n destructiveHint: true,\n // Calling it twice does not land in the same place: the second call\n // either errors as already-there or moves the item on again.\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async ({ workItemId, targetProjectId }) => {\n const result = await getConvexClient().action(\n api.mcp.moveWorkItemToProject,\n { token: getToken(), workItemId, targetProjectId },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateDocument(server: McpServer): void {\n server.registerTool(\n \"create_document\",\n {\n description:\n \"Create a markdown project document. Use type 'prd' for project docs or 'fd' for feature/work-item documents.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1),\n type: z\n .enum([\"prd\", \"fd\"])\n .describe(\n \"Document type. 'fd' is stored as the app's feature document type.\",\n ),\n workItemId: z\n .string()\n .optional()\n .describe(\"Required for fd documents; omitted for prd.\"),\n content: z\n .string()\n .optional()\n .describe(\"Optional initial markdown content.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createDocument, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerUpdateDocument(server: McpServer): void {\n server.registerTool(\n \"update_document\",\n {\n description:\n \"Update an existing document's markdown content and/or title. Use this to fill in or revise a document created earlier (e.g. backfill content into an empty doc). documentId comes from list_documents. Provided content fully replaces the existing content.\",\n inputSchema: {\n documentId: z.string().describe(\"documentId from list_documents\"),\n content: z\n .string()\n .optional()\n .describe(\n \"New markdown content. Replaces the document's existing content.\",\n ),\n title: z.string().min(1).optional().describe(\"New title (optional).\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.updateDocument, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListDocuments(server: McpServer): void {\n server.registerTool(\n \"list_documents\",\n {\n description:\n \"List PRD/FD markdown documents for a project, optionally filtered to one work item.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n workItemId: z\n .string()\n .optional()\n .describe(\"Optional workItemId to list linked FD documents.\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listDocuments, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nconst projectLinkCategory = z.enum([\n \"api\",\n \"dashboard\",\n \"documentation\",\n \"repository\",\n \"service\",\n \"other\",\n]);\n\nexport function registerCreateProjectLink(server: McpServer): void {\n server.registerTool(\n \"create_project_link\",\n {\n description:\n \"Save a link on a project for resources like APIs, dashboards, documentation, repositories, or services.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1).max(120),\n url: z.string().url().describe(\"http(s) URL to save\"),\n description: z.string().max(500).optional(),\n category: projectLinkCategory.optional().describe(\"Defaults to other.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createProjectLink, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListProjectLinks(server: McpServer): void {\n server.registerTool(\n \"list_project_links\",\n {\n description:\n \"List saved links for a project, such as APIs, dashboards, docs, repositories, and services.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ projectId }) => {\n const result = await getConvexClient().action(api.mcp.listProjectLinks, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListScratchNotes(server: McpServer): void {\n server.registerTool(\n \"list_scratch_notes\",\n {\n description:\n \"The token owner's OPEN scratch notes: thoughts and ideas they captured \" +\n \"in the app with the `s` shortcut before deciding what to do with them. \" +\n \"Returns the notes that belong with this project (tagged with it, or \" +\n \"tagged with nothing), oldest first, each with noteId, body, projectId \" +\n \"and createdAt. These are raw: a note may be one line or a paragraph, \" +\n \"may describe one task or three, and may not be a task at all. Read \" +\n \"each, decide what it should become (usually one or more work items \" +\n \"via create_work_item, sometimes a comment on an existing item, \" +\n \"sometimes nothing), do that, then call resolve_scratch_note with the \" +\n \"noteId and the workItemId it became so the person sees where their \" +\n \"note went. Ask in a comment rather than guess when a note is too \" +\n \"thin to act on. Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId }) => {\n const notes = await getConvexClient().action(api.mcp.listScratchNotes, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(notes, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerResolveScratchNote(server: McpServer): void {\n server.registerTool(\n \"resolve_scratch_note\",\n {\n description:\n \"Mark a scratch note as used, recording the work item it became. Call \" +\n \"this after acting on a note from list_scratch_notes: pass the noteId \" +\n \"and the workItemId you created or updated from it (omit workItemId \" +\n \"only when the note needed no item). The note leaves the person's open \" +\n \"list and shows where it went. Only the token owner's own notes.\",\n inputSchema: {\n noteId: z.string().describe(\"noteId from list_scratch_notes\"),\n workItemId: z\n .string()\n .optional()\n .describe(\"The workItemId the note became, from create_work_item or list_work_items.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ noteId, workItemId }) => {\n const result = await getConvexClient().action(api.mcp.resolveScratchNote, {\n token: getToken(),\n noteId,\n workItemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddWorkItemImage(server: McpServer): void {\n server.registerTool(\n \"add_work_item_image\",\n {\n description:\n \"Attach an externally hosted image URL to a work item. Use this when an MCP client has a screenshot, mockup, or generated image URL to preserve with the task.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n imageUrl: z\n .string()\n .url()\n .describe(\"Public or otherwise fetchable http(s) image URL\"),\n filename: z.string().optional().describe(\"Optional display filename\"),\n altText: z\n .string()\n .optional()\n .describe(\"Optional description/caption for the image\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.addWorkItemImage, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItemImages(server: McpServer): void {\n server.registerTool(\n \"list_work_item_images\",\n {\n description:\n \"List image attachments for a work item, including uploaded images and externally attached MCP images. Call list_work_items first to find the workItemId.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ workItemId }) => {\n const result = await getConvexClient().action(\n api.mcp.listWorkItemImages,\n {\n token: getToken(),\n workItemId,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddWorkItemComment(server: McpServer): void {\n server.registerTool(\n \"add_work_item_comment\",\n {\n description:\n \"Add a timestamped comment to a work item. Use this to record notes, updates, \" +\n \"or an 'AI touched' entry instead of editing the description. Comments are \" +\n \"stamped with the current time automatically and never overwrite each other.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n body: z.string().min(1).describe(\"Comment text (markdown supported)\"),\n source: z\n .enum([\"user\", \"ai\"])\n .optional()\n .describe('Who authored it; defaults to \"ai\" for MCP callers'),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.addWorkItemComment,\n {\n token: getToken(),\n ...args,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItemComments(server: McpServer): void {\n server.registerTool(\n \"list_work_item_comments\",\n {\n description:\n \"List the timestamped comments on a work item, oldest first. Use this to check \" +\n \"whether the item was already touched/commented before adding a new comment.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.listWorkItemComments,\n {\n token: getToken(),\n ...args,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListValidations(server: McpServer): void {\n server.registerTool(\n \"list_validations\",\n {\n description:\n \"List a project's validation graph: core systems and validation/test tasks with their DERIVED state (passing, failing, stale, unvalidated). A task is 'stale' when a system it covers changed since it was last validated, or an upstream dependency is no longer passing. Call list_projects first to find the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ projectId }) => {\n const client = getConvexClient();\n const graph = await client.action(api.mcp.listValidations, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRecordValidation(server: McpServer): void {\n server.registerTool(\n \"record_validation\",\n {\n description:\n \"Check off a validation task by recording a pass or fail. Stamps the task as validated 'now', clearing any stale flag until a covered system changes or an upstream dependency moves again. Get validationTaskId from list_validations.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"validationTaskId from list_validations\"),\n result: z\n .enum([\"pass\", \"fail\"])\n .describe(\"Outcome of running the test\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, result }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.recordValidation, {\n token: getToken(),\n validationTaskId,\n result,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerMarkSystemChanged(server: McpServer): void {\n server.registerTool(\n \"mark_system_changed\",\n {\n description:\n \"Mark a core system as changed. This is the single action that invalidates testing: every validation task that covers this system (and everything transitively depending on those tasks) immediately becomes 'stale' and needs revalidation. Get systemId from list_validations.\",\n inputSchema: {\n systemId: z.string().describe(\"systemId from list_validations\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async ({ systemId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.markSystemChanged, {\n token: getToken(),\n systemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateSystem(server: McpServer): void {\n server.registerTool(\n \"create_system\",\n {\n description:\n \"Create a core system in a project \u2014 a subsystem (e.g. Auth, Payments, Sync) whose change should invalidate the validation tasks that cover it. Returns the new systemId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z.string().min(1).describe(\"Short system name, e.g. 'Auth'\"),\n description: z.string().optional().describe(\"Optional details\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.createSystem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateValidationTask(server: McpServer): void {\n server.registerTool(\n \"create_validation_task\",\n {\n description:\n \"Create a validation/test task in a project. After creating it, use add_system_to_task to declare which systems it exercises (so it goes stale when they change) and add_validation_dependency to order it after other tasks. Returns the new validationTaskId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1).describe(\"What this test validates\"),\n description: z.string().optional().describe(\"Optional steps / details\"),\n kind: z\n .enum([\"auto\", \"manual\"])\n .optional()\n .describe(\n \"'auto' if runnable by a test runner, 'manual' if a human checks it. Defaults to manual.\",\n ),\n workItemId: z\n .string()\n .optional()\n .describe(\n \"Optional workItemId to link this test to a feature for traceability\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.createValidationTask, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddSystemToTask(server: McpServer): void {\n server.registerTool(\n \"add_system_to_task\",\n {\n description:\n \"Declare that a validation task COVERS (exercises) a system. Once linked, the task becomes 'stale' whenever that system is marked changed. Idempotent. Both IDs come from list_validations and must be in the same project.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"validationTaskId from list_validations\"),\n systemId: z.string().describe(\"systemId from list_validations\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, systemId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.addSystemToTask, {\n token: getToken(),\n validationTaskId,\n systemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddValidationDependency(server: McpServer): void {\n server.registerTool(\n \"add_validation_dependency\",\n {\n description:\n \"Make one validation task depend on another (validationTaskId depends on dependsOnTaskId). The dependent goes 'stale' whenever the upstream task is not passing or gets revalidated. Cycles and self-dependencies are rejected. Idempotent. Both IDs come from list_validations and must be in the same project.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"The dependent (downstream) task\"),\n dependsOnTaskId: z\n .string()\n .describe(\"The dependency (upstream) task it relies on\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, dependsOnTaskId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.addValidationDependency, {\n token: getToken(),\n validationTaskId,\n dependsOnTaskId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListLabels(server: McpServer): void {\n server.registerTool(\n \"list_labels\",\n {\n description:\n \"List all labels defined in a project. Returns each label's id, name, and color. Use the labelId with add_label_to_work_item / remove_label_from_work_item.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listLabels, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateLabel(server: McpServer): void {\n server.registerTool(\n \"create_label\",\n {\n description:\n \"Apply-or-seed a label. Returns the existing label if the name is \" +\n \"already taken (idempotent), and otherwise creates it ONLY if the name \" +\n \"is one of the curated ones. Any other new name is REFUSED \u2014 the reply \" +\n \"carries `refused: true`, the reason, and `available`, the project's \" +\n \"existing labels. Agents apply labels; they do not invent them, because \" +\n \"a near-duplicate of an existing label splits the vocabulary silently. \" +\n \"Prefer list_labels first. Colors are ignored for curated names so the \" +\n \"vocabulary looks the same in every project.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z\n .string()\n .min(1)\n .describe(\"Label name, unique within the project\"),\n color: z\n .string()\n .regex(/^#[0-9a-fA-F]{6}$/)\n .optional()\n .describe(\"Hex color like #2563eb. Defaults to a neutral slate.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createLabel, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddLabelToWorkItem(server: McpServer): void {\n server.registerTool(\n \"add_label_to_work_item\",\n {\n description:\n \"Attach a label to a work item (idempotent). The label and work item must be in the same project. Get labelIds from list_labels / create_label.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n labelId: z\n .string()\n .describe(\"labelId from list_labels or create_label\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.setWorkItemLabel, {\n token: getToken(),\n ...args,\n attached: true,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRemoveLabelFromWorkItem(server: McpServer): void {\n server.registerTool(\n \"remove_label_from_work_item\",\n {\n description:\n \"Remove a label from a work item (idempotent \u2014 a no-op if it wasn't attached).\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n labelId: z.string().describe(\"labelId from list_labels\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.setWorkItemLabel, {\n token: getToken(),\n ...args,\n attached: false,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListMilestones(server: McpServer): void {\n server.registerTool(\n \"list_milestones\",\n {\n description:\n \"List all milestones in a project. Returns each milestone's id, name, description, dueDate (unix ms), and status. Use the milestoneId with add_item_to_milestone / remove_item_from_milestone.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listMilestones, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateMilestone(server: McpServer): void {\n server.registerTool(\n \"create_milestone\",\n {\n description:\n \"Create a milestone in a project. Returns the milestoneId. Good for grouping work into phases (e.g. 'Phase 1 \u2014 Web', 'Phase 2 \u2014 Native').\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z.string().min(1).describe(\"Milestone name\"),\n description: z\n .string()\n .optional()\n .describe(\"Optional markdown description\"),\n dueDate: z\n .number()\n .optional()\n .describe(\"Optional due date as a unix timestamp in milliseconds\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createMilestone, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddItemToMilestone(server: McpServer): void {\n server.registerTool(\n \"add_item_to_milestone\",\n {\n description:\n \"Associate a work item with a milestone (idempotent). Both must be in the same project.\",\n inputSchema: {\n milestoneId: z\n .string()\n .describe(\"milestoneId from list_milestones or create_milestone\"),\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.setWorkItemMilestone,\n {\n token: getToken(),\n ...args,\n attached: true,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRemoveItemFromMilestone(server: McpServer): void {\n server.registerTool(\n \"remove_item_from_milestone\",\n {\n description:\n \"Remove a work item's association with a milestone (idempotent \u2014 a no-op if it wasn't associated).\",\n inputSchema: {\n milestoneId: z.string().describe(\"milestoneId from list_milestones\"),\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.setWorkItemMilestone,\n {\n token: getToken(),\n ...args,\n attached: false,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n"],
5
- "mappings": "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",
6
- "names": ["z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z"]
3
+ "sources": ["../src/index.ts", "../src/server.ts", "../package.json", "../src/instructions.ts", "../../convex/convex/_generated/api.js", "../src/convex.ts", "../src/tools/list-orgs.ts", "../src/tools/list-projects.ts", "../src/tools/list-work-items.ts", "../src/tools/get-work-items.ts", "../src/tools/search-work-items.ts", "../src/tools/list-ai-review-queue.ts", "../src/tools/get-active-block.ts", "../src/tools/create-work-item.ts", "../src/tools/titleGuidance.ts", "../src/tools/statusGuidance.ts", "../../convex/convex/lib/descriptionLimits.ts", "../src/tools/descriptionGuidance.ts", "../src/tools/create-project.ts", "../src/tools/update-work-item.ts", "../src/tools/researchFormat.ts", "../src/tools/move-work-item.ts", "../src/tools/create-document.ts", "../src/tools/update-document.ts", "../src/tools/list-documents.ts", "../src/tools/create-project-link.ts", "../src/tools/list-project-links.ts", "../src/tools/list-scratch-notes.ts", "../src/tools/resolve-scratch-note.ts", "../src/tools/heartbeat-work-item.ts", "../src/tools/add-work-item-image.ts", "../src/tools/list-work-item-images.ts", "../src/tools/add-work-item-comment.ts", "../src/tools/list-work-item-comments.ts", "../src/tools/list-validations.ts", "../src/tools/record-validation.ts", "../src/tools/mark-system-changed.ts", "../src/tools/create-system.ts", "../src/tools/create-validation-task.ts", "../src/tools/add-system-to-task.ts", "../src/tools/add-validation-dependency.ts", "../src/tools/list-labels.ts", "../src/tools/create-label.ts", "../src/tools/add-label-to-work-item.ts", "../src/tools/remove-label-from-work-item.ts", "../src/tools/list-milestones.ts", "../src/tools/create-milestone.ts", "../src/tools/add-item-to-milestone.ts", "../src/tools/remove-item-from-milestone.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n// MCP stdio transport reserves stdout for JSON-RPC frames. Any library that\n// writes to stdout (e.g. the Convex client's `[CONVEX A(uth)]` info logs)\n// corrupts the stream. Redirect console.* to stderr before anything else loads.\nfor (const m of [\"log\", \"info\", \"warn\", \"debug\"] as const) {\n console[m] = (...args: unknown[]) => console.error(...args);\n}\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\n\nasync function main() {\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // Server runs until stdin closes; nothing else to do here.\n}\n\nmain().catch((err) => {\n console.error(\"nimara-mcp: fatal error\", err);\n process.exit(1);\n});\n", "import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { INSTRUCTIONS } from \"./instructions.js\";\nimport { registerListOrgs } from \"./tools/list-orgs.js\";\nimport { registerListProjects } from \"./tools/list-projects.js\";\nimport { registerListWorkItems } from \"./tools/list-work-items.js\";\nimport { registerGetWorkItems } from \"./tools/get-work-items.js\";\nimport { registerSearchWorkItems } from \"./tools/search-work-items.js\";\nimport { registerListAiReviewQueue } from \"./tools/list-ai-review-queue.js\";\nimport { registerGetActiveBlock } from \"./tools/get-active-block.js\";\nimport { registerCreateWorkItem } from \"./tools/create-work-item.js\";\nimport { registerCreateProject } from \"./tools/create-project.js\";\nimport { registerUpdateWorkItem } from \"./tools/update-work-item.js\";\nimport { registerMoveWorkItem } from \"./tools/move-work-item.js\";\nimport { registerCreateDocument } from \"./tools/create-document.js\";\nimport { registerUpdateDocument } from \"./tools/update-document.js\";\nimport { registerListDocuments } from \"./tools/list-documents.js\";\nimport { registerCreateProjectLink } from \"./tools/create-project-link.js\";\nimport { registerListProjectLinks } from \"./tools/list-project-links.js\";\nimport { registerListScratchNotes } from \"./tools/list-scratch-notes.js\";\nimport { registerResolveScratchNote } from \"./tools/resolve-scratch-note.js\";\nimport { registerHeartbeatWorkItem } from \"./tools/heartbeat-work-item.js\";\nimport { registerAddWorkItemImage } from \"./tools/add-work-item-image.js\";\nimport { registerListWorkItemImages } from \"./tools/list-work-item-images.js\";\nimport { registerAddWorkItemComment } from \"./tools/add-work-item-comment.js\";\nimport { registerListWorkItemComments } from \"./tools/list-work-item-comments.js\";\nimport { registerListValidations } from \"./tools/list-validations.js\";\nimport { registerRecordValidation } from \"./tools/record-validation.js\";\nimport { registerMarkSystemChanged } from \"./tools/mark-system-changed.js\";\nimport { registerCreateSystem } from \"./tools/create-system.js\";\nimport { registerCreateValidationTask } from \"./tools/create-validation-task.js\";\nimport { registerAddSystemToTask } from \"./tools/add-system-to-task.js\";\nimport { registerAddValidationDependency } from \"./tools/add-validation-dependency.js\";\nimport { registerListLabels } from \"./tools/list-labels.js\";\nimport { registerCreateLabel } from \"./tools/create-label.js\";\nimport { registerAddLabelToWorkItem } from \"./tools/add-label-to-work-item.js\";\nimport { registerRemoveLabelFromWorkItem } from \"./tools/remove-label-from-work-item.js\";\nimport { registerListMilestones } from \"./tools/list-milestones.js\";\nimport { registerCreateMilestone } from \"./tools/create-milestone.js\";\nimport { registerAddItemToMilestone } from \"./tools/add-item-to-milestone.js\";\nimport { registerRemoveItemFromMilestone } from \"./tools/remove-item-from-milestone.js\";\n\nexport function createServer(): McpServer {\n const server = new McpServer(\n {\n name: \"nimara\",\n version: pkg.version,\n },\n // Sent at connect time, before any tool is read (NIM-T189).\n { instructions: INSTRUCTIONS },\n );\n\n registerListOrgs(server);\n registerListProjects(server);\n registerListWorkItems(server);\n registerGetWorkItems(server);\n registerSearchWorkItems(server);\n registerListAiReviewQueue(server);\n registerGetActiveBlock(server);\n registerCreateProject(server);\n registerCreateWorkItem(server);\n registerUpdateWorkItem(server);\n registerMoveWorkItem(server);\n registerCreateDocument(server);\n registerUpdateDocument(server);\n registerListDocuments(server);\n registerCreateProjectLink(server);\n registerListProjectLinks(server);\n registerListScratchNotes(server);\n registerResolveScratchNote(server);\n registerHeartbeatWorkItem(server);\n registerAddWorkItemImage(server);\n registerListWorkItemImages(server);\n registerAddWorkItemComment(server);\n registerListWorkItemComments(server);\n\n // Validation / test-dependency framework\n registerListValidations(server);\n registerRecordValidation(server);\n registerMarkSystemChanged(server);\n registerCreateSystem(server);\n registerCreateValidationTask(server);\n registerAddSystemToTask(server);\n registerAddValidationDependency(server);\n\n // Labels & milestones\n registerListLabels(server);\n registerCreateLabel(server);\n registerAddLabelToWorkItem(server);\n registerRemoveLabelFromWorkItem(server);\n registerListMilestones(server);\n registerCreateMilestone(server);\n registerAddItemToMilestone(server);\n registerRemoveItemFromMilestone(server);\n\n return server;\n}\n", "{\n \"name\": \"@nimara-app/mcp\",\n \"version\": \"0.4.0\",\n \"private\": false,\n \"mcpName\": \"io.github.langskip-studios/nimara\",\n \"description\": \"Nimara MCP server \u2014 AI tool integration for Claude, Codex, and others\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"nimara-mcp\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"nimara\",\n \"claude\",\n \"ai\",\n \"convex\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Langskip-Studios/Nimara.git\",\n \"directory\": \"packages/mcp\"\n },\n \"homepage\": \"https://github.com/Langskip-Studios/Nimara/tree/master/packages/mcp#readme\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"node build.mjs\",\n \"dev\": \"node build.mjs\",\n \"start\": \"node dist/index.js\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run typecheck && npm run build\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.0.0\",\n \"convex\": \"^1.18.0\",\n \"zod\": \"^3.23.0\"\n },\n \"devDependencies\": {\n \"@nimara/convex\": \"workspace:*\",\n \"@types/node\": \"^20.0.0\",\n \"esbuild\": \"^0.23.0\",\n \"typescript\": \"^5.0.0\"\n },\n \"engines\": {\n \"node\": \">=20\"\n }\n}\n", "/**\n * What every MCP client is told at connect time, before any tool is read.\n *\n * The rules that span tools \u2014 titles, statuses, the lease, mentions \u2014 each\n * live in one tool's parameter description, so a model that never loads that\n * tool never hears them. This is the map; the tool descriptions stay the\n * detailed reference. Kept short on purpose: it sits in the model's context\n * for the whole session.\n */\nexport const INSTRUCTIONS = `Nimara is the team's work tracker. Work items have a type (epic > feature > task > subtask), a status from the project's own workflow, and a displayId like NIM-T42 that people read and type.\n\nStart with list_orgs \u2192 list_projects \u2192 get_active_block (the committed work; position 0 is next) and list_ai_review_queue (what a person has asked an agent to do; read \\`answer\\` first). Use get_work_items / search_work_items for items you already know of; list_work_items only to survey.\n\nTitles are plain language a teammate understands at a glance: what is wrong or what changes for a person, not the file, function or mechanism. No em dashes, no \"Area: thing, thing\" shapes. Descriptions carry the why, acceptance criteria and file paths; a spec, design or long report goes in a document (create_document) linked from the item.\n\nA status must be one of the project's \\`statuses\\` from list_projects, spelled exactly; never invent one. Labels come from list_labels; do not invent those either.\n\nWhen you pick up an item: update_work_item { status: <in-progress status>, agentWorking: true }. That lights its row for 15 minutes; any write or read of the item renews it, and on a long stretch with no Nimara calls, heartbeat_work_item every few minutes keeps it lit. Post a comment at real milestones. If you stop early, agentWorking: false. Moving to the last status clears it.\n\nMention a person in a comment as [@Name](user:<userId>) and they are notified. Append agent research to a description under the exact heading \"## Research (auto)\", never editing the human text above it. When you open a PR, put the displayId in its title.`;\n", "/* eslint-disable */\n/**\n * Generated `api` utility.\n *\n * THIS CODE IS AUTOMATICALLY GENERATED.\n *\n * To regenerate, run `npx convex dev`.\n * @module\n */\n\nimport { anyApi, componentsGeneric } from \"convex/server\";\n\n/**\n * A utility for referencing Convex functions in your app's API.\n *\n * Usage:\n * ```js\n * const myFunctionReference = api.myModule.myFunction;\n * ```\n */\nexport const api = anyApi;\nexport const internal = anyApi;\nexport const components = componentsGeneric();\n", "import { ConvexHttpClient } from \"convex/browser\";\n\nlet cachedClient: ConvexHttpClient | null = null;\n\nexport function getConvexClient(): ConvexHttpClient {\n if (cachedClient) return cachedClient;\n\n const url = process.env.NIMARA_CONVEX_URL;\n if (!url) {\n throw new Error(\n \"NIMARA_CONVEX_URL is not set. Add it to your MCP client config (e.g. Claude Desktop's mcpServers env block).\"\n );\n }\n\n cachedClient = new ConvexHttpClient(url);\n return cachedClient;\n}\n\nexport function getToken(): string {\n const token = process.env.NIMARA_TOKEN;\n if (!token) {\n throw new Error(\n \"NIMARA_TOKEN is not set. Generate a personal access token from Nimara \u2192 Settings \u2192 Personal Access Tokens, then add it to your MCP client config.\"\n );\n }\n return token;\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListOrgs(server: McpServer): void {\n server.registerTool(\n \"list_orgs\",\n {\n description:\n \"List all organizations (and the personal workspace) the authenticated user belongs to. Use this first to discover org IDs needed by other tools.\",\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async () => {\n const client = getConvexClient();\n const orgs = await client.action(api.mcp.listOrgs, { token: getToken() });\n return {\n content: [{ type: \"text\", text: JSON.stringify(orgs, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListProjects(server: McpServer): void {\n server.registerTool(\n \"list_projects\",\n {\n description:\n \"List projects in a given organization. Call list_orgs first to find \" +\n \"the orgId. Each project includes `statuses` \u2014 its workflow in board \" +\n \"order. Read that before setting a status on any item: those names are \" +\n \"the only accepted values, and anything else is rejected.\",\n inputSchema: { orgId: z.string().describe(\"orgId from list_orgs\") },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ orgId }) => {\n const client = getConvexClient();\n const projects = await client.action(api.mcp.listProjects, {\n token: getToken(),\n orgId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(projects, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItems(server: McpServer): void {\n server.registerTool(\n \"list_work_items\",\n {\n // The description is the only place a model learns paging exists, so it\n // states the shape of the response and what to do when hasMore is true.\n description:\n \"List non-archived work items in a project, oldest-created first. Returns \" +\n \"{ items, nextCursor, hasMore }. Long descriptions are previewed \u2014 an \" +\n \"item with descriptionTruncated: true has more text, readable via \" +\n \"fullDescriptions. When hasMore is true, call again with cursor set to \" +\n \"nextCursor to get the next page \u2014 the FIRST page is the OLDEST items, so \" +\n \"recently created ones are on the LAST page and you have not seen the \" +\n \"project until hasMore is false. Narrow with status/type/parentId/\" +\n \"needsReview rather than paging and filtering yourself. If you already \" +\n \"know which items you want, use get_work_items instead \u2014 it takes \" +\n \"displayIds like NIM-T75 and costs a fraction of a list. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n status: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n \"Only items in these statuses. Names come from the project's \" +\n \"statusOrder (e.g. 'In Progress'). One name or a list.\",\n ),\n type: z\n .union([\n z.enum([\"epic\", \"feature\", \"task\", \"subtask\"]),\n z.array(z.enum([\"epic\", \"feature\", \"task\", \"subtask\"])),\n ])\n .optional()\n .describe(\"Only items of these types. One type or a list.\"),\n parentId: z\n .string()\n .optional()\n .describe(\n \"Only direct children of this workItemId. One level, not the whole subtree.\",\n ),\n needsReview: z\n .boolean()\n .optional()\n .describe(\n \"true returns only items flagged needsReview; false only unflagged ones. \" +\n \"Omit for both.\",\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe(\"Items per page (default 50, max 200).\"),\n cursor: z\n .number()\n .optional()\n .describe(\n \"nextCursor from the previous page. Omit for the first page.\",\n ),\n fullDescriptions: z\n .boolean()\n .optional()\n .describe(\n \"Return descriptions in full instead of previewed. Costly on large \" +\n \"projects \u2014 prefer paging, or read one item at a time.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({\n projectId,\n limit,\n cursor,\n fullDescriptions,\n status,\n type,\n parentId,\n needsReview,\n }) => {\n const page = await getConvexClient().action(api.mcp.listWorkItems, {\n token: getToken(),\n projectId,\n limit,\n cursor,\n fullDescriptions,\n // Accepting a bare string as well as a list is what keeps a model from\n // failing validation on the overwhelmingly common single-value case.\n status:\n status === undefined\n ? undefined\n : Array.isArray(status)\n ? status\n : [status],\n type:\n type === undefined ? undefined : Array.isArray(type) ? type : [type],\n parentId,\n needsReview,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(page, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerGetWorkItems(server: McpServer): void {\n server.registerTool(\n \"get_work_items\",\n {\n // Written to be chosen *over* list_work_items whenever the caller already\n // knows which items it wants \u2014 that is the whole point of the tool, and\n // the description is the only place a model learns it.\n description:\n \"Read specific work items by id \u2014 the cheap way to re-read items you \" +\n \"already know about. Prefer this over list_work_items whenever you have \" +\n \"a displayId (e.g. NIM-T75) or a workItemId: listing a project returns \" +\n \"every item and its description, which is orders of magnitude more data. \" +\n \"Accepts up to 50 ids per call and always returns descriptions in full. \" +\n \"Returns { items, notFound }; ids in notFound either do not exist or are \" +\n \"not readable by this token. displayIds require projectId (they are \" +\n \"unique per project, not globally); workItemIds do not.\",\n inputSchema: {\n displayIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Human-facing ids like ['NIM-T75', 'NIM-F27']. Case-insensitive. \" +\n \"Requires projectId.\",\n ),\n workItemIds: z\n .array(z.string())\n .optional()\n .describe(\n \"Raw workItemIds, as returned by create_work_item or list_work_items.\",\n ),\n projectId: z\n .string()\n .optional()\n .describe(\n \"projectId from list_projects. Required only when passing displayIds.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ displayIds, workItemIds, projectId }) => {\n const result = await getConvexClient().action(api.mcp.getWorkItems, {\n token: getToken(),\n displayIds,\n workItemIds,\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerSearchWorkItems(server: McpServer): void {\n server.registerTool(\n \"search_work_items\",\n {\n // The point of this description is to stop a model reaching for\n // list_work_items when it is looking for something by name. Listing a\n // project to find one item is the expensive mistake this tool exists to\n // prevent.\n description:\n \"Find work items in a project by title. Use this to answer 'does an \" +\n \"item for X already exist?' \u2014 listing the whole project and filtering \" +\n \"yourself is far more expensive and, because the first page is the \" +\n \"OLDEST items, easy to get wrong. Matches TITLES only, not \" +\n \"descriptions. Returns { items, query } with descriptions previewed; \" +\n \"once you know which item you want, get_work_items returns it in full. \" +\n \"Capped at 25 results \u2014 narrow the query rather than paging. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n q: z\n .string()\n .min(1)\n .describe(\n \"Words to match against item titles, e.g. 'mobile modal' or \" +\n \"'shortcut'. Matching is full-text, so word order does not matter.\",\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(25)\n .optional()\n .describe(\"Maximum results (default and maximum 25).\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ projectId, q, limit }) => {\n const result = await getConvexClient().action(api.mcp.searchWorkItems, {\n token: getToken(),\n projectId,\n q,\n limit,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListAiReviewQueue(server: McpServer): void {\n server.registerTool(\n \"list_ai_review_queue\",\n {\n description:\n \"List work items in a project that a human has flagged for AI review \" +\n \"(aiReviewRequested). Descriptions come back in full here, since \" +\n \"enrichment needs the whole text. Each item also carries recentComments \" +\n \"(the last few, oldest first) and, when a person has written one, \" +\n \"`answer`: the newest human comment. READ `answer` FIRST. When you \" +\n \"flagged an item with a question and it is back in this queue, `answer` \" +\n \"is the person's reply to that question; act on it rather than asking \" +\n \"again. Returns { items, nextCursor, hasMore } \u2014 when hasMore is true, \" +\n \"call again with cursor set to nextCursor. Process each item, then clear \" +\n \"its flag by calling update_work_item with aiReviewRequested: false. \" +\n \"Call list_projects first to find the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n limit: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe(\"Items per page (default 50, max 200).\"),\n cursor: z\n .number()\n .optional()\n .describe(\n \"nextCursor from the previous page. Omit for the first page.\",\n ),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId, limit, cursor }) => {\n const page = await getConvexClient().action(api.mcp.listAiReviewQueue, {\n token: getToken(),\n projectId,\n limit,\n cursor,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(page, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerGetActiveBlock(server: McpServer): void {\n server.registerTool(\n \"get_active_block\",\n {\n description:\n \"The project's ACTIVE BLOCK: the small, ordered set of work a person has \" +\n \"committed to right now. Call this BEFORE list_work_items when deciding what \" +\n \"to work on \u2014 position 0 is the next thing to do, and the wider backlog is \" +\n \"not on the table until the block is empty. Each item carries a lane: \" +\n \"'person' means a human owes it (flagged for review, or parked in a Review \" +\n \"status) and you should not touch it; 'agent' means a human asked an agent \" +\n \"to act on it, so it is yours first, and it carries recentComments and \" +\n \"`answer` (the newest human comment: read it before anything else); \" +\n \"'open' is uncommitted-to-anyone work in \" +\n \"priority order; 'done' is finished. Returns null when the project has no \" +\n \"active block, in which case fall back to list_work_items. Descriptions are \" +\n \"previewed; use get_work_items for the full text of an item you pick up. \" +\n \"Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId }) => {\n const block = await getConvexClient().action(api.mcp.getActiveBlock, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(block, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\nimport { TITLE_GUIDANCE } from \"./titleGuidance.js\";\nimport { STATUS_GUIDANCE } from \"./statusGuidance.js\";\nimport { DESCRIPTION_GUIDANCE, DESCRIPTION_MAX } from \"./descriptionGuidance.js\";\n\nexport function registerCreateWorkItem(server: McpServer): void {\n server.registerTool(\n \"create_work_item\",\n {\n description:\n \"Create a new work item in a project. Hierarchy rules: epics live at the root; features go under epics; tasks go under epics or features (or root); subtasks must go under a task. Returns the new workItemId and its display ID (e.g. NIM-42).\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n type: z\n .enum([\"epic\", \"feature\", \"task\", \"subtask\"])\n .describe(\"Item type \u2014 drives hierarchy validation\"),\n title: z.string().min(1).describe(TITLE_GUIDANCE),\n description: z.string().max(DESCRIPTION_MAX).optional().describe(DESCRIPTION_GUIDANCE),\n parentId: z\n .string()\n .optional()\n .describe(\n \"workItemId of the parent. Required for subtask, optional otherwise.\",\n ),\n status: z\n .string()\n .optional()\n .describe(\n STATUS_GUIDANCE,\n ),\n priority: z\n .enum([\"p0\", \"p1\", \"p2\", \"p3\"])\n .optional()\n .describe(\"p0 highest, p3 lowest. Defaults to p2.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const result = await client.action(api.mcp.createWorkItem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "/**\n * What a work-item title should read like, stated once.\n *\n * This exists because \"Short, descriptive title\" \u2014 the previous guidance on\n * `create_work_item` \u2014 is satisfied by \"Fix hasChildren computation in\n * list.tsx\". That is short and it does describe something, and it is unreadable\n * to anyone who has not just been in that file. Titles are what a board shows;\n * a board full of symbol names cannot be scanned.\n *\n * The em-dash and verbosity rules come from NIM-T117, which Jordan filed\n * before this and which asked for exactly that: \"Remove the em dash and\n * other verbose title that make it hard to read.\"\n *\n * Shared by `create_work_item` and `update_work_item` so the rule cannot hold\n * on one path and not the other \u2014 retitling is the same act as titling, and\n * `update_work_item` previously carried no guidance at all.\n */\nexport const TITLE_GUIDANCE =\n \"A title a teammate can understand at a glance, without opening the item or \" +\n \"knowing the codebase. Say what is wrong or what changes FOR A PERSON, in \" +\n \"plain words \u2014 not the mechanism, the file, or the symbol. \" +\n 'Good: \"Sorted list shows an expand arrow that does nothing\". ' +\n 'Bad: \"Fix hasChildren computation in list.tsx\". ' +\n 'Good: \"Long titles wrap to three lines and are hard to read\". ' +\n 'Bad: \"Adjust COLUMNS.title min-width constant\". ' +\n \"Prefer ordinary words over internal abbreviations, and only name a file, \" +\n \"function or identifier when it genuinely is the clearest way to say it \" +\n \"(a tool or endpoint the user calls by name, for instance). No ticket \" +\n \"prefixes or status markers \u2014 the board renders those already. Root cause, \" +\n \"file paths, and reproduction steps belong in the description, which has \" +\n \"room for them. \" +\n \"Keep it to one plain clause. Do NOT use an em dash, and do not use the \" +\n '\"Area: thing, other thing\" shape \u2014 both are ways of stapling a second ' +\n \"title on and they are what makes these hard to read. \" +\n 'Bad: \"Gantt: tighten row density, match app typography, stop the chart ' +\n 'falling short of its container\". ' +\n 'Good: \"Gantt chart looks nothing like the rest of the app\". ' +\n \"If the title needs a comma-spliced list to be accurate, that is a sign the \" +\n \"item is really several items, not a sign it needs a longer title.\";\n", "/**\n * How to choose a status, stated once.\n *\n * The rule the tools already stated \u2014 \"a status name from the project's\n * statusOrder\" \u2014 referred to data no tool returned. An agent could not read a\n * project's workflow, so it guessed a plausible-sounding name, and the guess\n * was frequently \"In Review\" on boards whose workflow only ever had \"Review\".\n * `list_projects` now returns `statuses`, which is what makes this instruction\n * followable rather than aspirational.\n *\n * The second half matters as much as the first. A status is POSITIONAL \u2014 it is\n * the board column \u2014 so inventing one is not a labelling choice, it reshapes\n * the board and every status chart that aggregates across projects. Anything\n * that describes an item without saying where it sits in the flow is a label:\n * `list_labels`, `create_label` and `add_label_to_work_item` exist for exactly\n * that, and cost nothing to add. This is NIM-T49's decision, held to.\n *\n * Shared by `create_work_item` and `update_work_item`. `update_work_item.status`\n * previously carried no guidance at all, which is the path most likely to move\n * an item to an invented status.\n */\nexport const STATUS_GUIDANCE =\n \"Must be one of the names in the project's `statuses`, returned by \" +\n \"list_projects. Read it rather than guessing \u2014 a status is the board \" +\n \"column, so a name the workflow does not have is rejected, and before that \" +\n \"check existed such items rendered in the first column while claiming \" +\n \"otherwise. Match the existing name exactly, including its wording: if the \" +\n \"workflow says \\\"Review\\\", do not write \\\"In Review\\\". \" +\n \"Do NOT invent a status to capture something about an item. Statuses are \" +\n \"shared across the whole project and aggregated on the dashboard, so each \" +\n \"new one is a permanent extra band there. Anything that describes an item \" +\n \"rather than locating it in the flow belongs in a LABEL \u2014 see create_label \" +\n \"and add_label_to_work_item. Defaults to the first status when omitted.\";\n", "/**\n * The two sizes a work item description is measured against. Kept free of\n * Convex imports so the web app and the MCP package can share the numbers.\n *\n * PREVIEW is what the row carries so lists never join the body\n * (lib/workItemBody.ts). MAX is a sanity cap, not a product decision: no\n * task written by hand comes near it, but an agent pasting a log or a whole\n * research report into a description would \u2014 and that belongs in a document.\n * Descriptions averaged 14 KB when the cap was chosen; 32 KB is roughly\n * 5,000 words, eight pages.\n */\nexport const DESCRIPTION_PREVIEW_CHARS = 500;\nexport const DESCRIPTION_MAX_CHARS = 32_000;\n\n/** Where a description's length stands, for an error or a counter. */\nexport const DESCRIPTION_TOO_LONG =\n `A description can be at most ${DESCRIPTION_MAX_CHARS.toLocaleString(\"en-US\")} characters. ` +\n \"Put specs, research and long reports in a document and link it to the item.\";\n", "import { DESCRIPTION_MAX_CHARS } from \"@nimara/convex/convex/lib/descriptionLimits.js\";\n\n/**\n * What a description is for, and how big it may be, stated once and shared\n * by `create_work_item` and `update_work_item` the way TITLE_GUIDANCE is.\n *\n * The cap is enforced server-side in writeDescription; the zod max here\n * only means an agent hears about it before the round-trip. The guidance is\n * the real lever: descriptions averaged 14 KB because agents used them as\n * the place to put everything, and the row split (lib/workItemBody.ts) made\n * that cheap but not right \u2014 a document is what other items can link to.\n */\nexport const DESCRIPTION_MAX = DESCRIPTION_MAX_CHARS;\n\nexport const DESCRIPTION_GUIDANCE =\n \"Markdown. The what and the why: the problem, acceptance criteria, \" +\n \"reproduction steps, file paths, root cause. Keep it to what someone \" +\n \"picking the item up needs. A spec, a design, research, or a long report \" +\n \"goes in a document (create_document) linked from here, not inline. \" +\n `At most ${DESCRIPTION_MAX_CHARS.toLocaleString(\"en-US\")} characters.`;\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateProject(server: McpServer): void {\n server.registerTool(\n \"create_project\",\n {\n description:\n \"Create a new project in an org. Prefix must be unique within the org and is uppercased (e.g. 'NIM' yields work items NIM-1, NIM-2\u2026). Caller becomes the project admin. Returns the new projectId.\",\n inputSchema: {\n orgId: z.string().describe(\"orgId from list_orgs\"),\n name: z.string().min(1).describe(\"Project name\"),\n prefix: z\n .string()\n .min(1)\n .max(8)\n .describe(\n \"Short uppercase prefix for work item IDs (e.g. 'NIM'). Unique per org.\",\n ),\n description: z\n .string()\n .optional()\n .describe(\"Optional markdown description\"),\n isPrivate: z\n .boolean()\n .optional()\n .describe(\n \"If true, only explicitly added members see it. Defaults to false.\",\n ),\n workflowTemplate: z\n .enum([\"default\", \"simple\", \"kanban\", \"bug\"])\n .optional()\n .describe(\n \"Status workflow. Defaults to 'default' (Backlog/Todo/In Progress/Review/Done).\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const result = await client.action(api.mcp.createProject, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\nimport { TITLE_GUIDANCE } from \"./titleGuidance.js\";\nimport { STATUS_GUIDANCE } from \"./statusGuidance.js\";\nimport { DESCRIPTION_GUIDANCE, DESCRIPTION_MAX } from \"./descriptionGuidance.js\";\nimport { RESEARCH_FORMAT } from \"./researchFormat.js\";\n\nexport function registerUpdateWorkItem(server: McpServer): void {\n server.registerTool(\n \"update_work_item\",\n {\n description:\n \"Update an existing work item: title, description, status, priority, parent, or review flags. Any update also stamps the item as AI-touched.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n title: z.string().min(1).optional().describe(TITLE_GUIDANCE),\n description: z\n .string()\n .max(DESCRIPTION_MAX)\n .optional()\n .describe(\n \"Full markdown body, replacing what is there. \" +\n DESCRIPTION_GUIDANCE +\n \" \" +\n RESEARCH_FORMAT,\n ),\n status: z.string().optional().describe(STATUS_GUIDANCE),\n priority: z.enum([\"p0\", \"p1\", \"p2\", \"p3\"]).optional(),\n parentId: z\n .string()\n .nullable()\n .optional()\n .describe(\"New parent workItemId, null to move to root.\"),\n needsReview: z\n .boolean()\n .optional()\n .describe(\n \"Flag the item for manual human review \u2014 set true when your enrichment was thin or uncertain.\",\n ),\n reviewReason: z\n .string()\n .optional()\n .describe(\n \"Short reason the item needs manual review (shown to the human).\",\n ),\n aiReviewRequested: z\n .boolean()\n .optional()\n .describe(\n \"The human\u2192AI review flag. Set false to clear it after you have reviewed/enriched an item from list_ai_review_queue.\",\n ),\n agentWorking: z\n .boolean()\n .optional()\n .describe(\n \"Set true when you start working on this item: the app lights its row so the person can see it is in flight. It is a 15-minute lease renewed by any later MCP write on the item (updates, comments), by reading it (get_work_items, list_work_item_comments), or by heartbeat_work_item \u2014 call that every few minutes on a long task with no other Nimara calls, or the row goes quiet while you are still at it. Set false when you stop without finishing; moving the item to the last status clears it for you.\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.updateWorkItem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "/**\n * The shape of the automated research block an enrichment agent appends to a\n * work item's description.\n *\n * Two reasons this is stated here rather than left to each agent's own taste.\n *\n * The web app parses this block out of the description and renders it in its\n * own tab on the item (NIM-T125). The anchor heading is therefore a contract,\n * not a style choice: change its wording and the tab stops appearing, with the\n * text still sitting in the description and nothing failing loudly.\n *\n * And the existing blocks are decorated with emoji section markers \u2014 \uD83D\uDD0E, \uD83D\uDD17,\n * \uD83E\uDDED, \uD83C\uDF9A. They read as noise in a panel that is already labelled \"Research\",\n * they carry no information the heading does not, and they are the first thing\n * Jordan asked to remove. The parser accepts the old emoji heading so the 20\n * items already enriched keep working; nothing new should write one.\n *\n * Deliberately NOT permitted: raw HTML. The app renders this with\n * `react-markdown` and no `rehype-raw`, so HTML is stripped rather than shown \u2014\n * and turning that on would render agent-authored markup whose inputs include\n * untrusted work-item text. Mermaid fences cover the diagram case without\n * opening that door.\n */\nexport const RESEARCH_FORMAT = `When appending automated research to a description, use EXACTLY this format, \\\nafter the human-written text:\n\n---\n## Research (auto)\n\n### Findings\n- One bullet per verified fact, each naming what you checked.\n\n### Dependencies\n- Items this blocks or is blocked by, by displayId. Omit the section if none.\n\n### Duplicates\n- Existing items covering the same work, by displayId. Omit if none.\n\n### Suggested priority\nOne line. Say \"No change\" when it is already right.\n\nRules:\n- The \"## Research (auto)\" heading is EXACT and is what the app keys on to show \\\nthis in its own tab. Do not reword it, renumber its level, or translate it.\n- NO EMOJI anywhere in the block, in headings or in bullets. Older items carry \\\nemoji headings; do not copy them.\n- Omit a section rather than writing \"None found\" in it. An empty section is \\\nnoise the reader still has to read.\n- Never edit or delete the human-written text above the rule. Append only.\n- Markdown only. GFM tables are supported and are the right choice for \\\ncomparisons. Raw HTML is NOT rendered by the app and must not be used.\n- For a workflow, sequence or state machine, use a \\\\\\`\\\\\\`\\\\\\`mermaid fenced block. \\\nThat is the supported way to draw one.\n- Say what you verified and how. \"Confirmed X still returns Y (file:line)\" is \\\nworth more than a conclusion with no trail.`;\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerMoveWorkItem(server: McpServer): void {\n server.registerTool(\n \"move_work_item\",\n {\n // Everything a model needs to predict the damage has to be stated here \u2014\n // the description is the only channel it has. The consequences that are\n // NOT obvious from the name are the ones worth the tokens: the display ID\n // changes, and labels/milestones do not survive.\n description:\n \"Move a work item to a different project, taking its whole subtree \" +\n \"with it \u2014 children and grandchildren move too, and the hierarchy is \" +\n \"preserved. Both projects must be in the same organization, and you \" +\n \"need write access to both. \" +\n \"Not reversible by calling this again: the item is renumbered in the \" +\n \"destination, so NIM-T44 might become SKA-T18 and the old ID stops \" +\n \"resolving. Labels and milestone assignments are dropped, because both \" +\n \"belong to the project being left; a status the destination doesn't \" +\n \"define falls back to its first status. The response reports every \" +\n \"old \u2192 new ID plus everything that was dropped or remapped. \" +\n \"Comments, images, attached documents, PR links and history all follow \" +\n \"the item. Call list_projects first for the target projectId.\",\n inputSchema: {\n workItemId: z\n .string()\n .describe(\"workItemId from list_work_items \u2014 the item to move.\"),\n targetProjectId: z\n .string()\n .describe(\n \"projectId from list_projects \u2014 the destination. Must be in the \" +\n \"same org as the item's current project.\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n // Renumbering display IDs and deleting label/milestone links are\n // overwrites, not additions \u2014 this belongs with the tools a client\n // should prompt on rather than auto-approve.\n destructiveHint: true,\n // Calling it twice does not land in the same place: the second call\n // either errors as already-there or moves the item on again.\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async ({ workItemId, targetProjectId }) => {\n const result = await getConvexClient().action(\n api.mcp.moveWorkItemToProject,\n { token: getToken(), workItemId, targetProjectId },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateDocument(server: McpServer): void {\n server.registerTool(\n \"create_document\",\n {\n description:\n \"Create a markdown project document. Use type 'prd' for project docs or 'fd' for feature/work-item documents.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1),\n type: z\n .enum([\"prd\", \"fd\"])\n .describe(\n \"Document type. 'fd' is stored as the app's feature document type.\",\n ),\n workItemId: z\n .string()\n .optional()\n .describe(\"Required for fd documents; omitted for prd.\"),\n content: z\n .string()\n .optional()\n .describe(\"Optional initial markdown content.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createDocument, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerUpdateDocument(server: McpServer): void {\n server.registerTool(\n \"update_document\",\n {\n description:\n \"Update an existing document's markdown content and/or title. Use this to fill in or revise a document created earlier (e.g. backfill content into an empty doc). documentId comes from list_documents. Provided content fully replaces the existing content.\",\n inputSchema: {\n documentId: z.string().describe(\"documentId from list_documents\"),\n content: z\n .string()\n .optional()\n .describe(\n \"New markdown content. Replaces the document's existing content.\",\n ),\n title: z.string().min(1).optional().describe(\"New title (optional).\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.updateDocument, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListDocuments(server: McpServer): void {\n server.registerTool(\n \"list_documents\",\n {\n description:\n \"List PRD/FD markdown documents for a project, optionally filtered to one work item.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n workItemId: z\n .string()\n .optional()\n .describe(\"Optional workItemId to list linked FD documents.\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listDocuments, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nconst projectLinkCategory = z.enum([\n \"api\",\n \"dashboard\",\n \"documentation\",\n \"repository\",\n \"service\",\n \"other\",\n]);\n\nexport function registerCreateProjectLink(server: McpServer): void {\n server.registerTool(\n \"create_project_link\",\n {\n description:\n \"Save a link on a project for resources like APIs, dashboards, documentation, repositories, or services.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1).max(120),\n url: z.string().url().describe(\"http(s) URL to save\"),\n description: z.string().max(500).optional(),\n category: projectLinkCategory.optional().describe(\"Defaults to other.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createProjectLink, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListProjectLinks(server: McpServer): void {\n server.registerTool(\n \"list_project_links\",\n {\n description:\n \"List saved links for a project, such as APIs, dashboards, docs, repositories, and services.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ projectId }) => {\n const result = await getConvexClient().action(api.mcp.listProjectLinks, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListScratchNotes(server: McpServer): void {\n server.registerTool(\n \"list_scratch_notes\",\n {\n description:\n \"The token owner's OPEN scratch notes: thoughts and ideas they captured \" +\n \"in the app with the `s` shortcut before deciding what to do with them. \" +\n \"Returns the notes that belong with this project (tagged with it, or \" +\n \"tagged with nothing), oldest first, each with noteId, body, projectId \" +\n \"and createdAt. These are raw: a note may be one line or a paragraph, \" +\n \"may describe one task or three, and may not be a task at all. Read \" +\n \"each, decide what it should become (usually one or more work items \" +\n \"via create_work_item, sometimes a comment on an existing item, \" +\n \"sometimes nothing), do that, then call resolve_scratch_note with the \" +\n \"noteId and the workItemId it became so the person sees where their \" +\n \"note went. Ask in a comment rather than guess when a note is too \" +\n \"thin to act on. Call list_projects first for the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n async ({ projectId }) => {\n const notes = await getConvexClient().action(api.mcp.listScratchNotes, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(notes, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerResolveScratchNote(server: McpServer): void {\n server.registerTool(\n \"resolve_scratch_note\",\n {\n description:\n \"Mark a scratch note as used, recording the work item it became. Call \" +\n \"this after acting on a note from list_scratch_notes: pass the noteId \" +\n \"and the workItemId you created or updated from it (omit workItemId \" +\n \"only when the note needed no item). The note leaves the person's open \" +\n \"list and shows where it went. Only the token owner's own notes.\",\n inputSchema: {\n noteId: z.string().describe(\"noteId from list_scratch_notes\"),\n workItemId: z\n .string()\n .optional()\n .describe(\"The workItemId the note became, from create_work_item or list_work_items.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ noteId, workItemId }) => {\n const result = await getConvexClient().action(api.mcp.resolveScratchNote, {\n token: getToken(),\n noteId,\n workItemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerHeartbeatWorkItem(server: McpServer): void {\n server.registerTool(\n \"heartbeat_work_item\",\n {\n description:\n \"Say you are still working on an item. Renews (or starts) its 15-minute \" +\n \"\\\"agent working\\\" lease and does nothing else: no comment, no activity \" +\n \"event, no change to the item. The app lights the row while the lease is \" +\n \"live, so on a long task call this every few minutes or every handful of \" +\n \"tool calls \u2014 otherwise the row goes quiet while you are still at it. \" +\n \"Reads of the item (get_work_items, list_work_item_comments) also renew a \" +\n \"live lease, and any update or comment does; this is for the stretches \" +\n \"where you do none of those. Cheap and idempotent.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId of the item you are working on\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ workItemId }) => {\n const result = await getConvexClient().action(api.mcp.heartbeatWorkItem, {\n token: getToken(),\n workItemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddWorkItemImage(server: McpServer): void {\n server.registerTool(\n \"add_work_item_image\",\n {\n description:\n \"Attach an externally hosted image URL to a work item. Use this when an MCP client has a screenshot, mockup, or generated image URL to preserve with the task.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n imageUrl: z\n .string()\n .url()\n .describe(\"Public or otherwise fetchable http(s) image URL\"),\n filename: z.string().optional().describe(\"Optional display filename\"),\n altText: z\n .string()\n .optional()\n .describe(\"Optional description/caption for the image\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.addWorkItemImage, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItemImages(server: McpServer): void {\n server.registerTool(\n \"list_work_item_images\",\n {\n description:\n \"List image attachments for a work item, including uploaded images and externally attached MCP images. Call list_work_items first to find the workItemId.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ workItemId }) => {\n const result = await getConvexClient().action(\n api.mcp.listWorkItemImages,\n {\n token: getToken(),\n workItemId,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddWorkItemComment(server: McpServer): void {\n server.registerTool(\n \"add_work_item_comment\",\n {\n description:\n \"Add a timestamped comment to a work item. Use this to record notes, updates, \" +\n \"or an 'AI touched' entry instead of editing the description. Comments are \" +\n \"stamped with the current time automatically and never overwrite each other.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n body: z\n .string()\n .min(1)\n .describe(\n \"Comment text (markdown supported). To pull a person into the thread, mention them as [@Name](user:<userId>) \u2014 they are notified and the app renders it as a chip. userIds come from an item's assigneeId/reviewerId; there is no member lookup tool yet, so only mention ids you have seen.\",\n ),\n source: z\n .enum([\"user\", \"ai\"])\n .optional()\n .describe('Who authored it; defaults to \"ai\" for MCP callers'),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.addWorkItemComment,\n {\n token: getToken(),\n ...args,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListWorkItemComments(server: McpServer): void {\n server.registerTool(\n \"list_work_item_comments\",\n {\n description:\n \"List the timestamped comments on a work item, oldest first. Use this to check \" +\n \"whether the item was already touched/commented before adding a new comment.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.listWorkItemComments,\n {\n token: getToken(),\n ...args,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListValidations(server: McpServer): void {\n server.registerTool(\n \"list_validations\",\n {\n description:\n \"List a project's validation graph: core systems and validation/test tasks with their DERIVED state (passing, failing, stale, unvalidated). A task is 'stale' when a system it covers changed since it was last validated, or an upstream dependency is no longer passing. Call list_projects first to find the projectId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ projectId }) => {\n const client = getConvexClient();\n const graph = await client.action(api.mcp.listValidations, {\n token: getToken(),\n projectId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(graph, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRecordValidation(server: McpServer): void {\n server.registerTool(\n \"record_validation\",\n {\n description:\n \"Check off a validation task by recording a pass or fail. Stamps the task as validated 'now', clearing any stale flag until a covered system changes or an upstream dependency moves again. Get validationTaskId from list_validations.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"validationTaskId from list_validations\"),\n result: z\n .enum([\"pass\", \"fail\"])\n .describe(\"Outcome of running the test\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, result }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.recordValidation, {\n token: getToken(),\n validationTaskId,\n result,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerMarkSystemChanged(server: McpServer): void {\n server.registerTool(\n \"mark_system_changed\",\n {\n description:\n \"Mark a core system as changed. This is the single action that invalidates testing: every validation task that covers this system (and everything transitively depending on those tasks) immediately becomes 'stale' and needs revalidation. Get systemId from list_validations.\",\n inputSchema: {\n systemId: z.string().describe(\"systemId from list_validations\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async ({ systemId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.markSystemChanged, {\n token: getToken(),\n systemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateSystem(server: McpServer): void {\n server.registerTool(\n \"create_system\",\n {\n description:\n \"Create a core system in a project \u2014 a subsystem (e.g. Auth, Payments, Sync) whose change should invalidate the validation tasks that cover it. Returns the new systemId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z.string().min(1).describe(\"Short system name, e.g. 'Auth'\"),\n description: z.string().optional().describe(\"Optional details\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.createSystem, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateValidationTask(server: McpServer): void {\n server.registerTool(\n \"create_validation_task\",\n {\n description:\n \"Create a validation/test task in a project. After creating it, use add_system_to_task to declare which systems it exercises (so it goes stale when they change) and add_validation_dependency to order it after other tasks. Returns the new validationTaskId.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n title: z.string().min(1).describe(\"What this test validates\"),\n description: z.string().optional().describe(\"Optional steps / details\"),\n kind: z\n .enum([\"auto\", \"manual\"])\n .optional()\n .describe(\n \"'auto' if runnable by a test runner, 'manual' if a human checks it. Defaults to manual.\",\n ),\n workItemId: z\n .string()\n .optional()\n .describe(\n \"Optional workItemId to link this test to a feature for traceability\",\n ),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.createValidationTask, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddSystemToTask(server: McpServer): void {\n server.registerTool(\n \"add_system_to_task\",\n {\n description:\n \"Declare that a validation task COVERS (exercises) a system. Once linked, the task becomes 'stale' whenever that system is marked changed. Idempotent. Both IDs come from list_validations and must be in the same project.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"validationTaskId from list_validations\"),\n systemId: z.string().describe(\"systemId from list_validations\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, systemId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.addSystemToTask, {\n token: getToken(),\n validationTaskId,\n systemId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddValidationDependency(server: McpServer): void {\n server.registerTool(\n \"add_validation_dependency\",\n {\n description:\n \"Make one validation task depend on another (validationTaskId depends on dependsOnTaskId). The dependent goes 'stale' whenever the upstream task is not passing or gets revalidated. Cycles and self-dependencies are rejected. Idempotent. Both IDs come from list_validations and must be in the same project.\",\n inputSchema: {\n validationTaskId: z\n .string()\n .describe(\"The dependent (downstream) task\"),\n dependsOnTaskId: z\n .string()\n .describe(\"The dependency (upstream) task it relies on\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ validationTaskId, dependsOnTaskId }) => {\n const client = getConvexClient();\n const res = await client.action(api.mcp.addValidationDependency, {\n token: getToken(),\n validationTaskId,\n dependsOnTaskId,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(res, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListLabels(server: McpServer): void {\n server.registerTool(\n \"list_labels\",\n {\n description:\n \"List all labels defined in a project. Returns each label's id, name, and color. Use the labelId with add_label_to_work_item / remove_label_from_work_item.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listLabels, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateLabel(server: McpServer): void {\n server.registerTool(\n \"create_label\",\n {\n description:\n \"Apply-or-seed a label. Returns the existing label if the name is \" +\n \"already taken (idempotent), and otherwise creates it ONLY if the name \" +\n \"is one of the curated ones. Any other new name is REFUSED \u2014 the reply \" +\n \"carries `refused: true`, the reason, and `available`, the project's \" +\n \"existing labels. Agents apply labels; they do not invent them, because \" +\n \"a near-duplicate of an existing label splits the vocabulary silently. \" +\n \"Prefer list_labels first. Colors are ignored for curated names so the \" +\n \"vocabulary looks the same in every project.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z\n .string()\n .min(1)\n .describe(\"Label name, unique within the project\"),\n color: z\n .string()\n .regex(/^#[0-9a-fA-F]{6}$/)\n .optional()\n .describe(\"Hex color like #2563eb. Defaults to a neutral slate.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createLabel, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddLabelToWorkItem(server: McpServer): void {\n server.registerTool(\n \"add_label_to_work_item\",\n {\n description:\n \"Attach a label to a work item (idempotent). The label and work item must be in the same project. Get labelIds from list_labels / create_label.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n labelId: z\n .string()\n .describe(\"labelId from list_labels or create_label\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.setWorkItemLabel, {\n token: getToken(),\n ...args,\n attached: true,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRemoveLabelFromWorkItem(server: McpServer): void {\n server.registerTool(\n \"remove_label_from_work_item\",\n {\n description:\n \"Remove a label from a work item (idempotent \u2014 a no-op if it wasn't attached).\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n labelId: z.string().describe(\"labelId from list_labels\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.setWorkItemLabel, {\n token: getToken(),\n ...args,\n attached: false,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerListMilestones(server: McpServer): void {\n server.registerTool(\n \"list_milestones\",\n {\n description:\n \"List all milestones in a project. Returns each milestone's id, name, description, dueDate (unix ms), and status. Use the milestoneId with add_item_to_milestone / remove_item_from_milestone.\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n },\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.listMilestones, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerCreateMilestone(server: McpServer): void {\n server.registerTool(\n \"create_milestone\",\n {\n description:\n \"Create a milestone in a project. Returns the milestoneId. Good for grouping work into phases (e.g. 'Phase 1 \u2014 Web', 'Phase 2 \u2014 Native').\",\n inputSchema: {\n projectId: z.string().describe(\"projectId from list_projects\"),\n name: z.string().min(1).describe(\"Milestone name\"),\n description: z\n .string()\n .optional()\n .describe(\"Optional markdown description\"),\n dueDate: z\n .number()\n .optional()\n .describe(\"Optional due date as a unix timestamp in milliseconds\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(api.mcp.createMilestone, {\n token: getToken(),\n ...args,\n });\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerAddItemToMilestone(server: McpServer): void {\n server.registerTool(\n \"add_item_to_milestone\",\n {\n description:\n \"Associate a work item with a milestone (idempotent). Both must be in the same project.\",\n inputSchema: {\n milestoneId: z\n .string()\n .describe(\"milestoneId from list_milestones or create_milestone\"),\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.setWorkItemMilestone,\n {\n token: getToken(),\n ...args,\n attached: true,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n", "import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { api } from \"@nimara/convex/convex/_generated/api.js\";\nimport { getConvexClient, getToken } from \"../convex.js\";\n\nexport function registerRemoveItemFromMilestone(server: McpServer): void {\n server.registerTool(\n \"remove_item_from_milestone\",\n {\n description:\n \"Remove a work item's association with a milestone (idempotent \u2014 a no-op if it wasn't associated).\",\n inputSchema: {\n milestoneId: z.string().describe(\"milestoneId from list_milestones\"),\n workItemId: z.string().describe(\"workItemId from list_work_items\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async (args) => {\n const result = await getConvexClient().action(\n api.mcp.setWorkItemMilestone,\n {\n token: getToken(),\n ...args,\n attached: false,\n },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n };\n },\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimara-app/mcp",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "mcpName": "io.github.langskip-studios/nimara",
6
6
  "description": "Nimara MCP server — AI tool integration for Claude, Codex, and others",