@nimara-app/mcp 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,7 @@ remove existing data, as opposed to only adding.
37
37
  | `list_milestones` | Read | List all milestones in a project. |
38
38
  | `list_orgs` | Read | List all organizations (and the personal workspace) the authenticated user belongs to. |
39
39
  | `list_scratch_notes` | Read | The token owner's open scratch notes that belong with a project: raw ideas captured with `s` in the app, to turn into work items and then resolve. |
40
+ | `list_project_members` | Read | Everyone who can open a project, with userId, name, email and role — the ids that `assigneeId`, `reviewerId` and mentions take. |
40
41
  | `list_project_links` | Read | List saved links for a project, such as APIs, dashboards, docs, repositories, and services.. |
41
42
  | `list_projects` | Read | List projects in a given organization. |
42
43
  | `list_validations` | Read | List a project's validation graph: core systems and validation/test tasks with their DERIVED state (passing, f. |
@@ -50,8 +51,10 @@ remove existing data, as opposed to only adding.
50
51
  | `remove_item_from_milestone` | **Write ⚠** | Remove a work item's association with a milestone (idempotent — a no-op if it wasn't associated).. |
51
52
  | `remove_label_from_work_item` | **Write ⚠** | Remove a label from a work item (idempotent — a no-op if it wasn't attached).. |
52
53
  | `search_work_items` | Read | Find work items in a project by title — the cheap way to check whether something is already tracked. |
54
+ | `watch_work_item` | Write | Put the token owner on (or off) an item's watch list: they are told when it changes status, gets a comment or reviewer, is archived or moved. |
55
+ | `unlink_pr` | **Write ⚠** | Take a pull request off a work item; a PR that named the wrong display id links itself, this undoes it. |
53
56
  | `update_document` | **Write ⚠** | Update an existing document's markdown content and/or title. |
54
- | `update_work_item` | **Write ⚠** | Update an existing work item: title, description, status, priority, parent, or review flags. |
57
+ | `update_work_item` | **Write ⚠** | Update an existing work item: title, description, status, priority, parent, assignee, reviewer, or review flags. |
55
58
 
56
59
  ## Security
57
60
 
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "@nimara-app/mcp",
12
- version: "0.5.0",
12
+ version: "0.7.0",
13
13
  private: false,
14
14
  mcpName: "io.github.langskip-studios/nimara",
15
15
  description: "Nimara MCP server \u2014 AI tool integration for Claude, Codex, and others",
@@ -74,7 +74,7 @@ A status must be one of the project's \`statuses\` from list_projects, spelled e
74
74
 
75
75
  When you pick up an item: update_work_item { status: <in-progress status>, agentWorking: true, model: <the model you run as> }. That lights its row for 15 minutes and lets the app say whose agent, and which, is on it; 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
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.`;
77
+ People are userIds from list_project_members: mention one in a comment as [@Name](user:<userId>), or hand them the item with update_work_item's assigneeId / reviewerId; each notifies them. 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 and it links itself; unlink_pr removes a PR that landed on the wrong item.`;
78
78
 
79
79
  // src/convex.ts
80
80
  import { ConvexHttpClient } from "convex/browser";
@@ -495,7 +495,7 @@ function registerUpdateWorkItem(server) {
495
495
  server.registerTool(
496
496
  "update_work_item",
497
497
  {
498
- description: "Update an existing work item: title, description, status, priority, parent, or review flags. Any update also stamps the item as AI-touched.",
498
+ description: "Update an existing work item: title, description, status, priority, parent, assignee, reviewer, or review flags. Any update also stamps the item as AI-touched.",
499
499
  inputSchema: {
500
500
  workItemId: z9.string().describe("workItemId from list_work_items"),
501
501
  title: z9.string().min(1).optional().describe(TITLE_GUIDANCE),
@@ -505,6 +505,12 @@ function registerUpdateWorkItem(server) {
505
505
  status: z9.string().optional().describe(STATUS_GUIDANCE),
506
506
  priority: z9.enum(["p0", "p1", "p2", "p3"]).optional(),
507
507
  parentId: z9.string().nullable().optional().describe("New parent workItemId, null to move to root."),
508
+ assigneeId: z9.string().nullable().optional().describe(
509
+ "userId of the person to assign, from list_project_members; null to unassign. The person is notified. Must be someone on the project."
510
+ ),
511
+ reviewerId: z9.string().nullable().optional().describe(
512
+ "userId of the person to ask for review, from list_project_members; null to clear. The person is notified. Pair it with the Review status when you hand work over. Moving an item back up the workflow clears the reviewer unless the same call names one."
513
+ ),
508
514
  needsReview: z9.boolean().optional().describe(
509
515
  "Flag the item for manual human review \u2014 set true when your enrichment was thin or uncertain."
510
516
  ),
@@ -744,15 +750,73 @@ function registerListProjectLinks(server) {
744
750
  );
745
751
  }
746
752
 
747
- // src/tools/list-scratch-notes.ts
753
+ // src/tools/list-project-members.ts
748
754
  import { z as z16 } from "zod";
755
+ function registerListProjectMembers(server) {
756
+ server.registerTool(
757
+ "list_project_members",
758
+ {
759
+ description: "Who can open a project: userId, name, email and role for everyone with access, the same list the app's assignee picker shows. Use it to turn a name into the userId that update_work_item's assigneeId and reviewerId take, and to build a mention \u2014 [@Name](user:<userId>) in a comment notifies that person.",
760
+ inputSchema: {
761
+ projectId: z16.string().describe("projectId from list_projects")
762
+ },
763
+ annotations: {
764
+ readOnlyHint: true,
765
+ openWorldHint: false
766
+ }
767
+ },
768
+ async ({ projectId }) => {
769
+ const result = await getConvexClient().action(api.mcp.listProjectMembers, {
770
+ token: getToken(),
771
+ projectId
772
+ });
773
+ return {
774
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
775
+ };
776
+ }
777
+ );
778
+ }
779
+
780
+ // src/tools/unlink-pr.ts
781
+ import { z as z17 } from "zod";
782
+ function registerUnlinkPr(server) {
783
+ server.registerTool(
784
+ "unlink_pr",
785
+ {
786
+ description: "Take a pull request off a work item. PRs link themselves when their title or body names a display id, so a sample id in a PR description attaches that PR to a real item; this undoes it. Returns what was removed and what is still linked, so a wrong number can be corrected without another read. Removing the link does not touch the PR itself.",
787
+ inputSchema: {
788
+ workItemId: z17.string().describe("workItemId of the item the PR is wrongly on"),
789
+ prNumber: z17.number().int().positive().describe("The PR number, e.g. 354 for #354")
790
+ },
791
+ annotations: {
792
+ readOnlyHint: false,
793
+ destructiveHint: true,
794
+ idempotentHint: true,
795
+ openWorldHint: false
796
+ }
797
+ },
798
+ async ({ workItemId, prNumber }) => {
799
+ const result = await getConvexClient().action(api.mcp.unlinkPR, {
800
+ token: getToken(),
801
+ workItemId,
802
+ prNumber
803
+ });
804
+ return {
805
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
806
+ };
807
+ }
808
+ );
809
+ }
810
+
811
+ // src/tools/list-scratch-notes.ts
812
+ import { z as z18 } from "zod";
749
813
  function registerListScratchNotes(server) {
750
814
  server.registerTool(
751
815
  "list_scratch_notes",
752
816
  {
753
817
  description: "The token owner's OPEN scratch notes: thoughts and ideas they captured in the app with the `s` shortcut before deciding what to do with them. Returns the notes that belong with this project (tagged with it, or tagged with nothing), oldest first, each with noteId, body, projectId and createdAt. These are raw: a note may be one line or a paragraph, may describe one task or three, and may not be a task at all. Read each, decide what it should become (usually one or more work items via create_work_item, sometimes a comment on an existing item, sometimes nothing), do that, then call resolve_scratch_note with the noteId and the workItemId it became so the person sees where their note went. Ask in a comment rather than guess when a note is too thin to act on. Call list_projects first for the projectId.",
754
818
  inputSchema: {
755
- projectId: z16.string().describe("projectId from list_projects")
819
+ projectId: z18.string().describe("projectId from list_projects")
756
820
  },
757
821
  annotations: {
758
822
  readOnlyHint: true,
@@ -772,15 +836,15 @@ function registerListScratchNotes(server) {
772
836
  }
773
837
 
774
838
  // src/tools/resolve-scratch-note.ts
775
- import { z as z17 } from "zod";
839
+ import { z as z19 } from "zod";
776
840
  function registerResolveScratchNote(server) {
777
841
  server.registerTool(
778
842
  "resolve_scratch_note",
779
843
  {
780
844
  description: "Mark a scratch note as used, recording the work item it became. Call this after acting on a note from list_scratch_notes: pass the noteId and the workItemId you created or updated from it (omit workItemId only when the note needed no item). The note leaves the person's open list and shows where it went. Only the token owner's own notes.",
781
845
  inputSchema: {
782
- noteId: z17.string().describe("noteId from list_scratch_notes"),
783
- workItemId: z17.string().optional().describe("The workItemId the note became, from create_work_item or list_work_items.")
846
+ noteId: z19.string().describe("noteId from list_scratch_notes"),
847
+ workItemId: z19.string().optional().describe("The workItemId the note became, from create_work_item or list_work_items.")
784
848
  },
785
849
  annotations: {
786
850
  readOnlyHint: false,
@@ -803,15 +867,15 @@ function registerResolveScratchNote(server) {
803
867
  }
804
868
 
805
869
  // src/tools/heartbeat-work-item.ts
806
- import { z as z18 } from "zod";
870
+ import { z as z20 } from "zod";
807
871
  function registerHeartbeatWorkItem(server) {
808
872
  server.registerTool(
809
873
  "heartbeat_work_item",
810
874
  {
811
875
  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.',
812
876
  inputSchema: {
813
- workItemId: z18.string().describe("workItemId of the item you are working on"),
814
- model: z18.string().optional().describe("The model you are running as, e.g. claude-opus-5 or gpt-5, so the app can say which agent is on this. Your harness is reported automatically.")
877
+ workItemId: z20.string().describe("workItemId of the item you are working on"),
878
+ model: z20.string().optional().describe("The model you are running as, e.g. claude-opus-5 or gpt-5, so the app can say which agent is on this. Your harness is reported automatically.")
815
879
  },
816
880
  annotations: {
817
881
  readOnlyHint: false,
@@ -833,18 +897,49 @@ function registerHeartbeatWorkItem(server) {
833
897
  );
834
898
  }
835
899
 
900
+ // src/tools/watch-work-item.ts
901
+ import { z as z21 } from "zod";
902
+ function registerWatchWorkItem(server) {
903
+ server.registerTool(
904
+ "watch_work_item",
905
+ {
906
+ description: "Put the token owner on (or take them off) an item's watch list. A watcher is notified when the item changes status, gets a comment, gets a reviewer, is archived or moved \u2014 not on title or description edits. The item's assignee and reviewer already hear about it. Use this when you start work the person will want to follow, or when they ask to keep an eye on something.",
907
+ inputSchema: {
908
+ workItemId: z21.string().describe("workItemId of the item"),
909
+ watching: z21.boolean().default(true).describe("true to watch, false to stop")
910
+ },
911
+ annotations: {
912
+ readOnlyHint: false,
913
+ destructiveHint: false,
914
+ idempotentHint: true,
915
+ openWorldHint: false
916
+ }
917
+ },
918
+ async ({ workItemId, watching }) => {
919
+ const result = await getConvexClient().action(api.mcp.watchWorkItem, {
920
+ token: getToken(),
921
+ workItemId,
922
+ watching
923
+ });
924
+ return {
925
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
926
+ };
927
+ }
928
+ );
929
+ }
930
+
836
931
  // src/tools/add-work-item-image.ts
837
- import { z as z19 } from "zod";
932
+ import { z as z22 } from "zod";
838
933
  function registerAddWorkItemImage(server) {
839
934
  server.registerTool(
840
935
  "add_work_item_image",
841
936
  {
842
937
  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.",
843
938
  inputSchema: {
844
- workItemId: z19.string().describe("workItemId from list_work_items"),
845
- imageUrl: z19.string().url().describe("Public or otherwise fetchable http(s) image URL"),
846
- filename: z19.string().optional().describe("Optional display filename"),
847
- altText: z19.string().optional().describe("Optional description/caption for the image")
939
+ workItemId: z22.string().describe("workItemId from list_work_items"),
940
+ imageUrl: z22.string().url().describe("Public or otherwise fetchable http(s) image URL"),
941
+ filename: z22.string().optional().describe("Optional display filename"),
942
+ altText: z22.string().optional().describe("Optional description/caption for the image")
848
943
  },
849
944
  annotations: {
850
945
  readOnlyHint: false,
@@ -866,14 +961,14 @@ function registerAddWorkItemImage(server) {
866
961
  }
867
962
 
868
963
  // src/tools/list-work-item-images.ts
869
- import { z as z20 } from "zod";
964
+ import { z as z23 } from "zod";
870
965
  function registerListWorkItemImages(server) {
871
966
  server.registerTool(
872
967
  "list_work_item_images",
873
968
  {
874
969
  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.",
875
970
  inputSchema: {
876
- workItemId: z20.string().describe("workItemId from list_work_items")
971
+ workItemId: z23.string().describe("workItemId from list_work_items")
877
972
  },
878
973
  annotations: {
879
974
  readOnlyHint: true,
@@ -896,18 +991,18 @@ function registerListWorkItemImages(server) {
896
991
  }
897
992
 
898
993
  // src/tools/add-work-item-comment.ts
899
- import { z as z21 } from "zod";
994
+ import { z as z24 } from "zod";
900
995
  function registerAddWorkItemComment(server) {
901
996
  server.registerTool(
902
997
  "add_work_item_comment",
903
998
  {
904
999
  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.",
905
1000
  inputSchema: {
906
- workItemId: z21.string().describe("workItemId from list_work_items"),
907
- body: z21.string().min(1).describe(
1001
+ workItemId: z24.string().describe("workItemId from list_work_items"),
1002
+ body: z24.string().min(1).describe(
908
1003
  "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."
909
1004
  ),
910
- source: z21.enum(["user", "ai"]).optional().describe('Who authored it; defaults to "ai" for MCP callers')
1005
+ source: z24.enum(["user", "ai"]).optional().describe('Who authored it; defaults to "ai" for MCP callers')
911
1006
  },
912
1007
  annotations: {
913
1008
  readOnlyHint: false,
@@ -933,14 +1028,14 @@ function registerAddWorkItemComment(server) {
933
1028
  }
934
1029
 
935
1030
  // src/tools/list-work-item-comments.ts
936
- import { z as z22 } from "zod";
1031
+ import { z as z25 } from "zod";
937
1032
  function registerListWorkItemComments(server) {
938
1033
  server.registerTool(
939
1034
  "list_work_item_comments",
940
1035
  {
941
1036
  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.",
942
1037
  inputSchema: {
943
- workItemId: z22.string().describe("workItemId from list_work_items")
1038
+ workItemId: z25.string().describe("workItemId from list_work_items")
944
1039
  },
945
1040
  annotations: {
946
1041
  readOnlyHint: true,
@@ -963,14 +1058,14 @@ function registerListWorkItemComments(server) {
963
1058
  }
964
1059
 
965
1060
  // src/tools/list-validations.ts
966
- import { z as z23 } from "zod";
1061
+ import { z as z26 } from "zod";
967
1062
  function registerListValidations(server) {
968
1063
  server.registerTool(
969
1064
  "list_validations",
970
1065
  {
971
1066
  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.",
972
1067
  inputSchema: {
973
- projectId: z23.string().describe("projectId from list_projects")
1068
+ projectId: z26.string().describe("projectId from list_projects")
974
1069
  },
975
1070
  annotations: {
976
1071
  readOnlyHint: true,
@@ -991,15 +1086,15 @@ function registerListValidations(server) {
991
1086
  }
992
1087
 
993
1088
  // src/tools/record-validation.ts
994
- import { z as z24 } from "zod";
1089
+ import { z as z27 } from "zod";
995
1090
  function registerRecordValidation(server) {
996
1091
  server.registerTool(
997
1092
  "record_validation",
998
1093
  {
999
1094
  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.",
1000
1095
  inputSchema: {
1001
- validationTaskId: z24.string().describe("validationTaskId from list_validations"),
1002
- result: z24.enum(["pass", "fail"]).describe("Outcome of running the test")
1096
+ validationTaskId: z27.string().describe("validationTaskId from list_validations"),
1097
+ result: z27.enum(["pass", "fail"]).describe("Outcome of running the test")
1003
1098
  },
1004
1099
  annotations: {
1005
1100
  readOnlyHint: false,
@@ -1023,14 +1118,14 @@ function registerRecordValidation(server) {
1023
1118
  }
1024
1119
 
1025
1120
  // src/tools/mark-system-changed.ts
1026
- import { z as z25 } from "zod";
1121
+ import { z as z28 } from "zod";
1027
1122
  function registerMarkSystemChanged(server) {
1028
1123
  server.registerTool(
1029
1124
  "mark_system_changed",
1030
1125
  {
1031
1126
  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.",
1032
1127
  inputSchema: {
1033
- systemId: z25.string().describe("systemId from list_validations")
1128
+ systemId: z28.string().describe("systemId from list_validations")
1034
1129
  },
1035
1130
  annotations: {
1036
1131
  readOnlyHint: false,
@@ -1053,16 +1148,16 @@ function registerMarkSystemChanged(server) {
1053
1148
  }
1054
1149
 
1055
1150
  // src/tools/create-system.ts
1056
- import { z as z26 } from "zod";
1151
+ import { z as z29 } from "zod";
1057
1152
  function registerCreateSystem(server) {
1058
1153
  server.registerTool(
1059
1154
  "create_system",
1060
1155
  {
1061
1156
  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.",
1062
1157
  inputSchema: {
1063
- projectId: z26.string().describe("projectId from list_projects"),
1064
- name: z26.string().min(1).describe("Short system name, e.g. 'Auth'"),
1065
- description: z26.string().optional().describe("Optional details")
1158
+ projectId: z29.string().describe("projectId from list_projects"),
1159
+ name: z29.string().min(1).describe("Short system name, e.g. 'Auth'"),
1160
+ description: z29.string().optional().describe("Optional details")
1066
1161
  },
1067
1162
  annotations: {
1068
1163
  readOnlyHint: false,
@@ -1085,20 +1180,20 @@ function registerCreateSystem(server) {
1085
1180
  }
1086
1181
 
1087
1182
  // src/tools/create-validation-task.ts
1088
- import { z as z27 } from "zod";
1183
+ import { z as z30 } from "zod";
1089
1184
  function registerCreateValidationTask(server) {
1090
1185
  server.registerTool(
1091
1186
  "create_validation_task",
1092
1187
  {
1093
1188
  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.",
1094
1189
  inputSchema: {
1095
- projectId: z27.string().describe("projectId from list_projects"),
1096
- title: z27.string().min(1).describe("What this test validates"),
1097
- description: z27.string().optional().describe("Optional steps / details"),
1098
- kind: z27.enum(["auto", "manual"]).optional().describe(
1190
+ projectId: z30.string().describe("projectId from list_projects"),
1191
+ title: z30.string().min(1).describe("What this test validates"),
1192
+ description: z30.string().optional().describe("Optional steps / details"),
1193
+ kind: z30.enum(["auto", "manual"]).optional().describe(
1099
1194
  "'auto' if runnable by a test runner, 'manual' if a human checks it. Defaults to manual."
1100
1195
  ),
1101
- workItemId: z27.string().optional().describe(
1196
+ workItemId: z30.string().optional().describe(
1102
1197
  "Optional workItemId to link this test to a feature for traceability"
1103
1198
  )
1104
1199
  },
@@ -1123,15 +1218,15 @@ function registerCreateValidationTask(server) {
1123
1218
  }
1124
1219
 
1125
1220
  // src/tools/add-system-to-task.ts
1126
- import { z as z28 } from "zod";
1221
+ import { z as z31 } from "zod";
1127
1222
  function registerAddSystemToTask(server) {
1128
1223
  server.registerTool(
1129
1224
  "add_system_to_task",
1130
1225
  {
1131
1226
  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.",
1132
1227
  inputSchema: {
1133
- validationTaskId: z28.string().describe("validationTaskId from list_validations"),
1134
- systemId: z28.string().describe("systemId from list_validations")
1228
+ validationTaskId: z31.string().describe("validationTaskId from list_validations"),
1229
+ systemId: z31.string().describe("systemId from list_validations")
1135
1230
  },
1136
1231
  annotations: {
1137
1232
  readOnlyHint: false,
@@ -1155,15 +1250,15 @@ function registerAddSystemToTask(server) {
1155
1250
  }
1156
1251
 
1157
1252
  // src/tools/add-validation-dependency.ts
1158
- import { z as z29 } from "zod";
1253
+ import { z as z32 } from "zod";
1159
1254
  function registerAddValidationDependency(server) {
1160
1255
  server.registerTool(
1161
1256
  "add_validation_dependency",
1162
1257
  {
1163
1258
  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.",
1164
1259
  inputSchema: {
1165
- validationTaskId: z29.string().describe("The dependent (downstream) task"),
1166
- dependsOnTaskId: z29.string().describe("The dependency (upstream) task it relies on")
1260
+ validationTaskId: z32.string().describe("The dependent (downstream) task"),
1261
+ dependsOnTaskId: z32.string().describe("The dependency (upstream) task it relies on")
1167
1262
  },
1168
1263
  annotations: {
1169
1264
  readOnlyHint: false,
@@ -1187,14 +1282,14 @@ function registerAddValidationDependency(server) {
1187
1282
  }
1188
1283
 
1189
1284
  // src/tools/list-labels.ts
1190
- import { z as z30 } from "zod";
1285
+ import { z as z33 } from "zod";
1191
1286
  function registerListLabels(server) {
1192
1287
  server.registerTool(
1193
1288
  "list_labels",
1194
1289
  {
1195
1290
  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.",
1196
1291
  inputSchema: {
1197
- projectId: z30.string().describe("projectId from list_projects")
1292
+ projectId: z33.string().describe("projectId from list_projects")
1198
1293
  },
1199
1294
  annotations: {
1200
1295
  readOnlyHint: true,
@@ -1214,16 +1309,16 @@ function registerListLabels(server) {
1214
1309
  }
1215
1310
 
1216
1311
  // src/tools/create-label.ts
1217
- import { z as z31 } from "zod";
1312
+ import { z as z34 } from "zod";
1218
1313
  function registerCreateLabel(server) {
1219
1314
  server.registerTool(
1220
1315
  "create_label",
1221
1316
  {
1222
1317
  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.",
1223
1318
  inputSchema: {
1224
- projectId: z31.string().describe("projectId from list_projects"),
1225
- name: z31.string().min(1).describe("Label name, unique within the project"),
1226
- color: z31.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("Hex color like #2563eb. Defaults to a neutral slate.")
1319
+ projectId: z34.string().describe("projectId from list_projects"),
1320
+ name: z34.string().min(1).describe("Label name, unique within the project"),
1321
+ color: z34.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("Hex color like #2563eb. Defaults to a neutral slate.")
1227
1322
  },
1228
1323
  annotations: {
1229
1324
  readOnlyHint: false,
@@ -1245,15 +1340,15 @@ function registerCreateLabel(server) {
1245
1340
  }
1246
1341
 
1247
1342
  // src/tools/add-label-to-work-item.ts
1248
- import { z as z32 } from "zod";
1343
+ import { z as z35 } from "zod";
1249
1344
  function registerAddLabelToWorkItem(server) {
1250
1345
  server.registerTool(
1251
1346
  "add_label_to_work_item",
1252
1347
  {
1253
1348
  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.",
1254
1349
  inputSchema: {
1255
- workItemId: z32.string().describe("workItemId from list_work_items"),
1256
- labelId: z32.string().describe("labelId from list_labels or create_label")
1350
+ workItemId: z35.string().describe("workItemId from list_work_items"),
1351
+ labelId: z35.string().describe("labelId from list_labels or create_label")
1257
1352
  },
1258
1353
  annotations: {
1259
1354
  readOnlyHint: false,
@@ -1276,15 +1371,15 @@ function registerAddLabelToWorkItem(server) {
1276
1371
  }
1277
1372
 
1278
1373
  // src/tools/remove-label-from-work-item.ts
1279
- import { z as z33 } from "zod";
1374
+ import { z as z36 } from "zod";
1280
1375
  function registerRemoveLabelFromWorkItem(server) {
1281
1376
  server.registerTool(
1282
1377
  "remove_label_from_work_item",
1283
1378
  {
1284
1379
  description: "Remove a label from a work item (idempotent \u2014 a no-op if it wasn't attached).",
1285
1380
  inputSchema: {
1286
- workItemId: z33.string().describe("workItemId from list_work_items"),
1287
- labelId: z33.string().describe("labelId from list_labels")
1381
+ workItemId: z36.string().describe("workItemId from list_work_items"),
1382
+ labelId: z36.string().describe("labelId from list_labels")
1288
1383
  },
1289
1384
  annotations: {
1290
1385
  readOnlyHint: false,
@@ -1307,14 +1402,14 @@ function registerRemoveLabelFromWorkItem(server) {
1307
1402
  }
1308
1403
 
1309
1404
  // src/tools/list-milestones.ts
1310
- import { z as z34 } from "zod";
1405
+ import { z as z37 } from "zod";
1311
1406
  function registerListMilestones(server) {
1312
1407
  server.registerTool(
1313
1408
  "list_milestones",
1314
1409
  {
1315
1410
  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.",
1316
1411
  inputSchema: {
1317
- projectId: z34.string().describe("projectId from list_projects")
1412
+ projectId: z37.string().describe("projectId from list_projects")
1318
1413
  },
1319
1414
  annotations: {
1320
1415
  readOnlyHint: true,
@@ -1334,17 +1429,17 @@ function registerListMilestones(server) {
1334
1429
  }
1335
1430
 
1336
1431
  // src/tools/create-milestone.ts
1337
- import { z as z35 } from "zod";
1432
+ import { z as z38 } from "zod";
1338
1433
  function registerCreateMilestone(server) {
1339
1434
  server.registerTool(
1340
1435
  "create_milestone",
1341
1436
  {
1342
1437
  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').",
1343
1438
  inputSchema: {
1344
- projectId: z35.string().describe("projectId from list_projects"),
1345
- name: z35.string().min(1).describe("Milestone name"),
1346
- description: z35.string().optional().describe("Optional markdown description"),
1347
- dueDate: z35.number().optional().describe("Optional due date as a unix timestamp in milliseconds")
1439
+ projectId: z38.string().describe("projectId from list_projects"),
1440
+ name: z38.string().min(1).describe("Milestone name"),
1441
+ description: z38.string().optional().describe("Optional markdown description"),
1442
+ dueDate: z38.number().optional().describe("Optional due date as a unix timestamp in milliseconds")
1348
1443
  },
1349
1444
  annotations: {
1350
1445
  readOnlyHint: false,
@@ -1366,15 +1461,15 @@ function registerCreateMilestone(server) {
1366
1461
  }
1367
1462
 
1368
1463
  // src/tools/add-item-to-milestone.ts
1369
- import { z as z36 } from "zod";
1464
+ import { z as z39 } from "zod";
1370
1465
  function registerAddItemToMilestone(server) {
1371
1466
  server.registerTool(
1372
1467
  "add_item_to_milestone",
1373
1468
  {
1374
1469
  description: "Associate a work item with a milestone (idempotent). Both must be in the same project.",
1375
1470
  inputSchema: {
1376
- milestoneId: z36.string().describe("milestoneId from list_milestones or create_milestone"),
1377
- workItemId: z36.string().describe("workItemId from list_work_items")
1471
+ milestoneId: z39.string().describe("milestoneId from list_milestones or create_milestone"),
1472
+ workItemId: z39.string().describe("workItemId from list_work_items")
1378
1473
  },
1379
1474
  annotations: {
1380
1475
  readOnlyHint: false,
@@ -1400,15 +1495,15 @@ function registerAddItemToMilestone(server) {
1400
1495
  }
1401
1496
 
1402
1497
  // src/tools/remove-item-from-milestone.ts
1403
- import { z as z37 } from "zod";
1498
+ import { z as z40 } from "zod";
1404
1499
  function registerRemoveItemFromMilestone(server) {
1405
1500
  server.registerTool(
1406
1501
  "remove_item_from_milestone",
1407
1502
  {
1408
1503
  description: "Remove a work item's association with a milestone (idempotent \u2014 a no-op if it wasn't associated).",
1409
1504
  inputSchema: {
1410
- milestoneId: z37.string().describe("milestoneId from list_milestones"),
1411
- workItemId: z37.string().describe("workItemId from list_work_items")
1505
+ milestoneId: z40.string().describe("milestoneId from list_milestones"),
1506
+ workItemId: z40.string().describe("workItemId from list_work_items")
1412
1507
  },
1413
1508
  annotations: {
1414
1509
  readOnlyHint: false,
@@ -1460,9 +1555,12 @@ function createServer() {
1460
1555
  registerListDocuments(server);
1461
1556
  registerCreateProjectLink(server);
1462
1557
  registerListProjectLinks(server);
1558
+ registerListProjectMembers(server);
1559
+ registerUnlinkPr(server);
1463
1560
  registerListScratchNotes(server);
1464
1561
  registerResolveScratchNote(server);
1465
1562
  registerHeartbeatWorkItem(server);
1563
+ registerWatchWorkItem(server);
1466
1564
  registerAddWorkItemImage(server);
1467
1565
  registerListWorkItemImages(server);
1468
1566
  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", "../package.json", "../src/instructions.ts", "../src/convex.ts", "../../convex/convex/_generated/api.js", "../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 { setClientInfo } from \"./convex.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 // The client's name arrives with initialize; keep it for every later write.\n server.server.oninitialized = () => setClientInfo(server.server.getClientVersion());\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.5.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, model: <the model you run as> }. That lights its row for 15 minutes and lets the app say whose agent, and which, is on it; 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", "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\n/**\n * Who this server is talking to. Every MCP client names itself in the\n * `initialize` request (claude-code, codex, pi, \u2026); the server keeps it so\n * writes can say which agent made them, and the app can show \"Jordan's\n * Claude Code agent is working on this\" (NIM-F43). The model is not in the\n * protocol: an agent may pass it on the tools that take `model`.\n */\nlet clientInfo: { name: string; version?: string } | undefined;\n\nexport function setClientInfo(info: { name: string; version?: string } | undefined): void {\n clientInfo = info;\n}\n\n/** The `agent` argument for a Convex write, or undefined before initialize. */\nexport function agentArg(model?: string): { client: string; model?: string } | undefined {\n if (!clientInfo) return model ? { client: \"unknown\", model } : undefined;\n const client = clientInfo.version ? `${clientInfo.name} ${clientInfo.version}` : clientInfo.name;\n return model ? { client, model } : { client };\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 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 { agentArg, 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 model: z\n .string()\n .optional()\n .describe(\"With agentWorking: the model you are running as, e.g. claude-opus-5, so the app can say which agent is on this. Your harness is reported automatically.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ model, ...args }) => {\n const result = await getConvexClient().action(api.mcp.updateWorkItem, {\n token: getToken(),\n ...args,\n agent: agentArg(model),\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 { agentArg, 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 model: z\n .string()\n .optional()\n .describe(\"The model you are running as, e.g. claude-opus-5 or gpt-5, so the app can say which agent is on this. Your harness is reported automatically.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ workItemId, model }) => {\n const result = await getConvexClient().action(api.mcp.heartbeatWorkItem, {\n token: getToken(),\n workItemId,\n agent: agentArg(model),\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 { agentArg, 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 agent: agentArg(),\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"]
3
+ "sources": ["../src/index.ts", "../src/server.ts", "../package.json", "../src/instructions.ts", "../src/convex.ts", "../../convex/convex/_generated/api.js", "../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-project-members.ts", "../src/tools/unlink-pr.ts", "../src/tools/list-scratch-notes.ts", "../src/tools/resolve-scratch-note.ts", "../src/tools/heartbeat-work-item.ts", "../src/tools/watch-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 { setClientInfo } from \"./convex.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 { registerListProjectMembers } from \"./tools/list-project-members.js\";\nimport { registerUnlinkPr } from \"./tools/unlink-pr.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 { registerWatchWorkItem } from \"./tools/watch-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 // The client's name arrives with initialize; keep it for every later write.\n server.server.oninitialized = () => setClientInfo(server.server.getClientVersion());\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 registerListProjectMembers(server);\n registerUnlinkPr(server);\n registerListScratchNotes(server);\n registerResolveScratchNote(server);\n registerHeartbeatWorkItem(server);\n registerWatchWorkItem(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.7.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, model: <the model you run as> }. That lights its row for 15 minutes and lets the app say whose agent, and which, is on it; 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\nPeople are userIds from list_project_members: mention one in a comment as [@Name](user:<userId>), or hand them the item with update_work_item's assigneeId / reviewerId; each notifies them. 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 and it links itself; unlink_pr removes a PR that landed on the wrong item.`;\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\n/**\n * Who this server is talking to. Every MCP client names itself in the\n * `initialize` request (claude-code, codex, pi, \u2026); the server keeps it so\n * writes can say which agent made them, and the app can show \"Jordan's\n * Claude Code agent is working on this\" (NIM-F43). The model is not in the\n * protocol: an agent may pass it on the tools that take `model`.\n */\nlet clientInfo: { name: string; version?: string } | undefined;\n\nexport function setClientInfo(info: { name: string; version?: string } | undefined): void {\n clientInfo = info;\n}\n\n/** The `agent` argument for a Convex write, or undefined before initialize. */\nexport function agentArg(model?: string): { client: string; model?: string } | undefined {\n if (!clientInfo) return model ? { client: \"unknown\", model } : undefined;\n const client = clientInfo.version ? `${clientInfo.name} ${clientInfo.version}` : clientInfo.name;\n return model ? { client, model } : { client };\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 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 { agentArg, 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, assignee, reviewer, 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 assigneeId: z\n .string()\n .nullable()\n .optional()\n .describe(\n \"userId of the person to assign, from list_project_members; null to unassign. The person is notified. Must be someone on the project.\",\n ),\n reviewerId: z\n .string()\n .nullable()\n .optional()\n .describe(\n \"userId of the person to ask for review, from list_project_members; null to clear. The person is notified. Pair it with the Review status when you hand work over. Moving an item back up the workflow clears the reviewer unless the same call names one.\",\n ),\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 model: z\n .string()\n .optional()\n .describe(\"With agentWorking: the model you are running as, e.g. claude-opus-5, so the app can say which agent is on this. Your harness is reported automatically.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ model, ...args }) => {\n const result = await getConvexClient().action(api.mcp.updateWorkItem, {\n token: getToken(),\n ...args,\n agent: agentArg(model),\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 registerListProjectMembers(server: McpServer): void {\n server.registerTool(\n \"list_project_members\",\n {\n description:\n \"Who can open a project: userId, name, email and role for everyone with \" +\n \"access, the same list the app's assignee picker shows. Use it to turn a \" +\n \"name into the userId that update_work_item's assigneeId and reviewerId \" +\n \"take, and to build a mention \u2014 [@Name](user:<userId>) in a comment \" +\n \"notifies that person.\",\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.listProjectMembers, {\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 registerUnlinkPr(server: McpServer): void {\n server.registerTool(\n \"unlink_pr\",\n {\n description:\n \"Take a pull request off a work item. PRs link themselves when their \" +\n \"title or body names a display id, so a sample id in a PR description \" +\n \"attaches that PR to a real item; this undoes it. Returns what was \" +\n \"removed and what is still linked, so a wrong number can be corrected \" +\n \"without another read. Removing the link does not touch the PR itself.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId of the item the PR is wrongly on\"),\n prNumber: z.number().int().positive().describe(\"The PR number, e.g. 354 for #354\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n\n async ({ workItemId, prNumber }) => {\n const result = await getConvexClient().action(api.mcp.unlinkPR, {\n token: getToken(),\n workItemId,\n prNumber,\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 { agentArg, 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 model: z\n .string()\n .optional()\n .describe(\"The model you are running as, e.g. claude-opus-5 or gpt-5, so the app can say which agent is on this. Your harness is reported automatically.\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ workItemId, model }) => {\n const result = await getConvexClient().action(api.mcp.heartbeatWorkItem, {\n token: getToken(),\n workItemId,\n agent: agentArg(model),\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 registerWatchWorkItem(server: McpServer): void {\n server.registerTool(\n \"watch_work_item\",\n {\n description:\n \"Put the token owner on (or take them off) an item's watch list. A watcher \" +\n \"is notified when the item changes status, gets a comment, gets a reviewer, \" +\n \"is archived or moved \u2014 not on title or description edits. The item's \" +\n \"assignee and reviewer already hear about it. Use this when you start work \" +\n \"the person will want to follow, or when they ask to keep an eye on something.\",\n inputSchema: {\n workItemId: z.string().describe(\"workItemId of the item\"),\n watching: z.boolean().default(true).describe(\"true to watch, false to stop\"),\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async ({ workItemId, watching }) => {\n const result = await getConvexClient().action(api.mcp.watchWorkItem, {\n token: getToken(),\n workItemId,\n watching,\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 { agentArg, 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 agent: agentArg(),\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", "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.5.0",
3
+ "version": "0.7.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",