@nonbot/mcp 0.2.0 → 0.2.2

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.
@@ -1,7 +1,7 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ApiContext } from './config.js';
3
3
  export declare const SERVER_NAME = "nonbot-mcp";
4
- export declare const SERVER_VERSION = "0.2.0";
4
+ export declare const SERVER_VERSION = "0.2.2";
5
5
  export declare const INSTRUCTIONS: string;
6
6
  export declare function registerAll(server: McpServer, ctx: ApiContext): void;
7
7
  export declare function createNonbotMcpServer(ctx: ApiContext): McpServer;
@@ -8,7 +8,7 @@ import { registerMonitorTools } from './toolsets/monitor.js';
8
8
  import { registerResources } from './resources.js';
9
9
  import { registerPrompts } from './prompts.js';
10
10
  export const SERVER_NAME = 'nonbot-mcp';
11
- export const SERVER_VERSION = '0.2.0';
11
+ export const SERVER_VERSION = '0.2.2';
12
12
  export const INSTRUCTIONS = [
13
13
  'non.bot MCP — work against the caller’s real product-management data, not a copy.',
14
14
  'Two domains: PORTFOLIOS (the SAFe portfolio canvas — epics → features → stories) and',
@@ -25,74 +25,47 @@ export declare const toHtml: (s: string) => string;
25
25
  export declare function newItemId(now?: number): string;
26
26
  declare const itemSpec: z.ZodObject<{
27
27
  key: z.ZodOptional<z.ZodString>;
28
- level: z.ZodEnum<["objective", "key-result", "epic", "feature", "story", "enabler", "milestone"]>;
28
+ level: z.ZodEnum<{
29
+ epic: "epic";
30
+ objective: "objective";
31
+ "key-result": "key-result";
32
+ feature: "feature";
33
+ story: "story";
34
+ enabler: "enabler";
35
+ milestone: "milestone";
36
+ }>;
29
37
  title: z.ZodString;
30
38
  description: z.ZodOptional<z.ZodString>;
31
39
  bluf: z.ZodOptional<z.ZodString>;
32
40
  acceptance_criteria: z.ZodOptional<z.ZodString>;
33
41
  hypothesis: z.ZodOptional<z.ZodString>;
34
- state: z.ZodOptional<z.ZodEnum<["funnel", "reviewing", "analyzing", "ready", "implementing", "done"]>>;
42
+ state: z.ZodOptional<z.ZodEnum<{
43
+ done: "done";
44
+ funnel: "funnel";
45
+ reviewing: "reviewing";
46
+ analyzing: "analyzing";
47
+ ready: "ready";
48
+ implementing: "implementing";
49
+ }>>;
35
50
  parent: z.ZodOptional<z.ZodString>;
36
- okr: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
37
- depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
51
+ okr: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
53
  start_week: z.ZodOptional<z.ZodNumber>;
39
54
  start_date: z.ZodOptional<z.ZodString>;
40
55
  duration_weeks: z.ZodOptional<z.ZodNumber>;
41
- tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
56
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
57
  wsjf: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
43
58
  owner: z.ZodOptional<z.ZodString>;
44
59
  kr_target: z.ZodOptional<z.ZodString>;
45
60
  kr_current: z.ZodOptional<z.ZodString>;
46
- okr_status: z.ZodOptional<z.ZodEnum<["on-track", "at-risk", "behind"]>>;
47
- images: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
61
+ okr_status: z.ZodOptional<z.ZodEnum<{
62
+ "on-track": "on-track";
63
+ "at-risk": "at-risk";
64
+ behind: "behind";
65
+ }>>;
66
+ images: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
67
  fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
49
- }, "strip", z.ZodTypeAny, {
50
- title: string;
51
- level: "epic" | "objective" | "key-result" | "feature" | "story" | "enabler" | "milestone";
52
- parent?: string | undefined;
53
- description?: string | undefined;
54
- acceptance_criteria?: string | undefined;
55
- hypothesis?: string | undefined;
56
- owner?: string | undefined;
57
- key?: string | undefined;
58
- bluf?: string | undefined;
59
- state?: "done" | "funnel" | "reviewing" | "analyzing" | "ready" | "implementing" | undefined;
60
- okr?: string[] | undefined;
61
- depends_on?: string[] | undefined;
62
- start_week?: number | undefined;
63
- start_date?: string | undefined;
64
- duration_weeks?: number | undefined;
65
- tags?: string[] | undefined;
66
- wsjf?: [number, number, number, number] | undefined;
67
- kr_target?: string | undefined;
68
- kr_current?: string | undefined;
69
- okr_status?: "on-track" | "at-risk" | "behind" | undefined;
70
- images?: string[] | undefined;
71
- fields?: Record<string, unknown> | undefined;
72
- }, {
73
- title: string;
74
- level: "epic" | "objective" | "key-result" | "feature" | "story" | "enabler" | "milestone";
75
- parent?: string | undefined;
76
- description?: string | undefined;
77
- acceptance_criteria?: string | undefined;
78
- hypothesis?: string | undefined;
79
- owner?: string | undefined;
80
- key?: string | undefined;
81
- bluf?: string | undefined;
82
- state?: "done" | "funnel" | "reviewing" | "analyzing" | "ready" | "implementing" | undefined;
83
- okr?: string[] | undefined;
84
- depends_on?: string[] | undefined;
85
- start_week?: number | undefined;
86
- start_date?: string | undefined;
87
- duration_weeks?: number | undefined;
88
- tags?: string[] | undefined;
89
- wsjf?: [number, number, number, number] | undefined;
90
- kr_target?: string | undefined;
91
- kr_current?: string | undefined;
92
- okr_status?: "on-track" | "at-risk" | "behind" | undefined;
93
- images?: string[] | undefined;
94
- fields?: Record<string, unknown> | undefined;
95
- }>;
68
+ }, z.core.$strip>;
96
69
  type ItemSpec = z.infer<typeof itemSpec>;
97
70
  export declare function buildItems(g: Graph, specs: ItemSpec[], now?: Date): {
98
71
  nodes: Node[];
@@ -68,7 +68,7 @@ const itemSpec = z.object({
68
68
  kr_current: z.string().max(200).optional(),
69
69
  okr_status: z.enum(OKR_STATUSES).optional(),
70
70
  images: z.array(z.string().max(2048)).max(8).optional().describe('Image URLs from portfolio_asset_upload — the first is the card hero.'),
71
- fields: z.record(z.unknown()).optional().describe('Any other PortfolioItemData fields, merged last (structural keys are refused).'),
71
+ fields: z.record(z.string(), z.unknown()).optional().describe('Any other PortfolioItemData fields, merged last (structural keys are refused).'),
72
72
  });
73
73
  const DEFAULT_WEEKS = { epic: 8, feature: 4, story: 1, enabler: 2, milestone: 0, objective: 12, 'key-result': 12 };
74
74
  const LEGAL_PARENT = {
@@ -225,7 +225,7 @@ export function registerBuildTools(server, ctx) {
225
225
  inputSchema: {
226
226
  portfolio_id: z.string(),
227
227
  item_id: z.string(),
228
- set: z.record(z.unknown()).optional(),
228
+ set: z.record(z.string(), z.unknown()).optional(),
229
229
  unset: z.array(z.string()).max(40).optional(),
230
230
  expected_version: z.number().int().optional(),
231
231
  },
@@ -251,7 +251,7 @@ export function registerBuildTools(server, ctx) {
251
251
  description: 'Re-position every item so the Timeline reads cleanly: x from each item\'s start date (the canvas reads dates off x), y top-down — objectives, key results, then one block per epic (epic, features, stories + enablers, milestones), each row lane-packed so overlapping items stack, IP nodes directly above their first source. Short items get a minimum painted width so titles fit. Content is untouched. `heights` overrides the estimated card height per id (px) when a card measures taller on screen.',
252
252
  inputSchema: {
253
253
  portfolio_id: z.string(),
254
- heights: z.record(z.number().min(20).max(2000)).optional(),
254
+ heights: z.record(z.string(), z.number().min(20).max(2000)).optional(),
255
255
  expected_version: z.number().int().optional(),
256
256
  },
257
257
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
@@ -270,9 +270,9 @@ export function registerBuildTools(server, ctx) {
270
270
  inputSchema: {
271
271
  portfolio_id: z.string(),
272
272
  context_text: z.string().max(20000).optional(),
273
- palette: z.object({ id: z.string().min(1).max(64), name: z.string().min(1).max(64), swatches: z.array(z.object({ hex: z.string().regex(/^#[0-9a-fA-F]{6}$/), label: z.string().max(32).optional() })).max(10), roles: z.record(z.string()).optional() }).optional(),
274
- canvas_style: z.record(z.unknown()).optional(),
275
- sprint_settings: z.record(z.unknown()).optional(),
273
+ palette: z.object({ id: z.string().min(1).max(64), name: z.string().min(1).max(64), swatches: z.array(z.object({ hex: z.string().regex(/^#[0-9a-fA-F]{6}$/), label: z.string().max(32).optional() })).max(10), roles: z.record(z.string(), z.string()).optional() }).optional(),
274
+ canvas_style: z.record(z.string(), z.unknown()).optional(),
275
+ sprint_settings: z.record(z.string(), z.unknown()).optional(),
276
276
  expected_version: z.number().int().optional(),
277
277
  },
278
278
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
@@ -75,7 +75,7 @@ export function registerIpTools(server, ctx) {
75
75
  server.registerTool('ip_update', {
76
76
  title: 'Edit an IP node (op list)',
77
77
  description: 'Apply an op list to one IP node in ONE versioned write: unit.set {unitId, value, expectedRev} · unit.confirm · unit.unconfirm · evidence.update {evId, patch} · evidence.remove {evId} (a tombstone) · evidence.witness {evId, witness:{for,name,line}|null} · evidence.add (max 5 per request; identical adds collapse into one row) · event.upsert · event.remove · filing.set · meta.set. A stale expected_version is HTTP 409 version_conflict with currentVersion — re-read with ip_get and retry.',
78
- inputSchema: { ...ids, expected_version: z.number().int().describe('The graph version from ip_get.'), ops: z.array(z.record(z.unknown())).min(1).max(50).refine(o => o.filter(x => x.op === 'evidence.add').length <= 5, 'At most 5 evidence.add ops per request.').describe('The op list.') },
78
+ inputSchema: { ...ids, expected_version: z.number().int().describe('The graph version from ip_get.'), ops: z.array(z.record(z.string(), z.unknown())).min(1).max(50).refine(o => o.filter(x => x.op === 'evidence.add').length <= 5, 'At most 5 evidence.add ops per request.').describe('The op list.') },
79
79
  annotations: WRITE,
80
80
  }, async (a) => textResult(await patchNode(ctx, { portfolioId: a.portfolio_id, nodeId: a.node_id, expectedVersion: a.expected_version, ops: a.ops })));
81
81
  server.registerTool('ip_evidence_add', {
@@ -85,7 +85,7 @@ export function registerIpTools(server, ctx) {
85
85
  ...ids,
86
86
  expected_version: z.number().int().describe('The graph version from ip_get.'),
87
87
  kind: z.enum(KINDS),
88
- from: z.record(z.unknown()).describe('Exactly one source (see description).'),
88
+ from: z.record(z.string(), z.unknown()).describe('Exactly one source (see description).'),
89
89
  title: z.string().min(1).max(300),
90
90
  describes: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe('The date the evidence describes (YYYY-MM-DD).'),
91
91
  supports: z.array(z.enum(SUPPORTS)).max(5).optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonbot/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "The non.bot MCP server — one server for your portfolios, decision graph, and Runs. Runs over stdio (Claude Code, Cursor, VS Code) with a pat_ token. Built on MCP protocol 2025-11-25.",
6
6
  "keywords": [
@@ -56,7 +56,7 @@
56
56
  "dependencies": {
57
57
  "@cfworker/json-schema": "^4.1.1",
58
58
  "@modelcontextprotocol/sdk": "^1.29.0",
59
- "zod": "^3.25.0"
59
+ "zod": "^4.6.7"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^22.19.19",