@brainervirus/workit-mcp 6.0.1 → 7.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-mcp",
3
- "version": "6.0.1",
3
+ "version": "7.1.0",
4
4
  "private": false,
5
5
  "description": "Workit shared MCP transport for the eight task and policy operation families",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "build": "bun scripts/build.ts"
43
43
  },
44
44
  "dependencies": {
45
- "@brainervirus/workit-core": "^6.0.1",
45
+ "@brainervirus/workit-core": "^7.1.0",
46
46
  "@modelcontextprotocol/sdk": "1.32.0",
47
47
  "zod": "4.6.5"
48
48
  },
package/src/server.ts CHANGED
@@ -15,10 +15,10 @@ import {
15
15
  OPERATION_FAMILIES,
16
16
  WorkitCore,
17
17
  TaskStore,
18
- boundedOperationJsonSchema,
19
- parseOperation,
18
+ flatOperationJsonSchema,
19
+ operationDescription,
20
+ parseAdvertisedOperation,
20
21
  type OperationContext,
21
- type OperationFamily,
22
22
  } from "@brainervirus/workit-core/src/core";
23
23
  import {
24
24
  changedSourcesSinceLoad,
@@ -112,61 +112,32 @@ export function assertMcpHost(host: unknown): asserts host is McpHost {
112
112
  }
113
113
  }
114
114
 
115
- const operationDescription = (family: OperationFamily): string =>
116
- `Workit ${family} operations. Inputs are validated by the shared Workit contract.`;
117
-
118
115
  const READ_ONLY_ACTIONS = new Set(["list", "inspect", "preview", "explain", "export"]);
119
116
  const requiresCallerIdentity = (input: unknown): boolean =>
120
117
  typeof input !== "object" ||
121
118
  input === null ||
122
119
  !READ_ONLY_ACTIONS.has(String((input as { action?: unknown }).action));
123
120
 
124
- const toolInputSchema = (family: OperationFamily) => {
125
- const schema = boundedOperationJsonSchema(family);
126
- // MCP requires an object at the root. The operation union remains entirely
127
- // core-derived; this envelope preserves it while satisfying that protocol rule.
128
- return { type: "object" as const, ...schema };
129
- };
130
-
131
- const schemaBranches = (schema: Record<string, unknown>): unknown[] =>
132
- Array.isArray(schema.oneOf)
133
- ? schema.oneOf
134
- : Array.isArray(schema.anyOf)
135
- ? schema.anyOf
136
- : [schema];
137
-
138
- const readOnlyBranches = (family: OperationFamily): unknown[] =>
139
- schemaBranches(boundedOperationJsonSchema(family)).filter((branch) => {
140
- const action = (branch as { properties?: { action?: { const?: unknown } } }).properties?.action
141
- ?.const;
142
- return typeof action === "string" && READ_ONLY_ACTIONS.has(action);
143
- });
144
-
145
- /** Attested callers (host sessions that can mutate) see the full family union;
121
+ /** Attested callers (host sessions that can mutate) see every action;
146
122
  * unattested MCP callers see only read-only actions, and families with no
147
- * read-only action are not advertised as callable tools at all. */
123
+ * read-only action are not advertised as callable tools at all. Schemas are
124
+ * flat (depth 1): no provider needs a nesting projection. */
148
125
  export const advertisedToolSchemas = (
149
126
  attested: boolean,
150
- ): { name: string; description: string; inputSchema: Record<string, unknown> }[] => {
151
- if (attested)
152
- return OPERATION_FAMILIES.map((family) => ({
153
- name: `workit_${family}`,
154
- description: operationDescription(family),
155
- inputSchema: toolInputSchema(family),
156
- }));
157
- return OPERATION_FAMILIES.flatMap((family) => {
158
- const branches = readOnlyBranches(family);
159
- if (!branches.length) return [];
160
- const schema = boundedOperationJsonSchema(family);
127
+ ): { name: string; description: string; inputSchema: Record<string, unknown> }[] =>
128
+ OPERATION_FAMILIES.flatMap((family) => {
129
+ const schema = flatOperationJsonSchema(family, { readOnly: !attested });
130
+ if (!schema) return [];
161
131
  return [
162
132
  {
163
133
  name: `workit_${family}`,
164
- description: `${operationDescription(family)} Unattested MCP callers can only run read-only actions; mutating operations require an attested host session.`,
165
- inputSchema: { type: "object" as const, ...schema, oneOf: branches },
134
+ description: attested
135
+ ? operationDescription(family)
136
+ : `${operationDescription(family)} Unattested MCP callers can only run read-only actions; mutating operations require an attested host session.`,
137
+ inputSchema: schema,
166
138
  },
167
139
  ];
168
140
  });
169
- };
170
141
 
171
142
  const sanitizeFailure = (result: Result<unknown>, workspaceRoot?: string): Result<unknown> => {
172
143
  if (result.ok) return result;
@@ -374,7 +345,7 @@ export function createMcpServer(host: McpHost, contextProvider: NativeContextPro
374
345
  workspaceRoot,
375
346
  );
376
347
  }
377
- const parsed = parseOperation(family, request.params.arguments);
348
+ const parsed = parseAdvertisedOperation(family, request.params.arguments, host);
378
349
  if (!parsed.ok) return resultForClient(parsed, workspaceRoot);
379
350
  if (context.callerAttested !== true && requiresCallerIdentity(parsed.data))
380
351
  return resultForClient(