ofw-mcp 2.0.7 → 2.0.8

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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "OurFamilyWizard tools for Claude Code",
9
- "version": "2.0.7"
9
+ "version": "2.0.8"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -14,7 +14,7 @@
14
14
  "displayName": "OurFamilyWizard",
15
15
  "source": "./",
16
16
  "description": "OurFamilyWizard co-parenting tools for Claude — messages, calendar, expenses, and journal via MCP",
17
- "version": "2.0.7",
17
+ "version": "2.0.8",
18
18
  "author": {
19
19
  "name": "Chris Chall"
20
20
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ofw",
3
3
  "displayName": "OurFamilyWizard",
4
- "version": "2.0.7",
4
+ "version": "2.0.8",
5
5
  "description": "OurFamilyWizard co-parenting tools for Claude — messages, calendar, expenses, and journal via MCP",
6
6
  "author": {
7
7
  "name": "Chris Chall"
package/dist/bundle.js CHANGED
@@ -31087,6 +31087,13 @@ function rowFromDb(r) {
31087
31087
  listData: JSON.parse(r.list_data_json)
31088
31088
  };
31089
31089
  }
31090
+ function nullish3(v) {
31091
+ return v === void 0 ? null : v;
31092
+ }
31093
+ function requireString(field, v) {
31094
+ if (typeof v === "string") return v;
31095
+ throw new Error(`cache: ${field} is required (got ${v === void 0 ? "undefined" : "null"})`);
31096
+ }
31090
31097
  function upsertMessage(row) {
31091
31098
  const { db } = openCache();
31092
31099
  db.prepare(
@@ -31108,16 +31115,16 @@ function upsertMessage(row) {
31108
31115
  last_seen_at=excluded.last_seen_at`
31109
31116
  ).run(
31110
31117
  row.id,
31111
- row.folder,
31112
- row.subject,
31113
- row.fromUser,
31114
- row.sentAt,
31115
- JSON.stringify(row.recipients),
31116
- row.body,
31117
- row.fetchedBodyAt,
31118
- row.replyToId,
31119
- row.chainRootId,
31120
- JSON.stringify(row.listData),
31118
+ requireString("messages.folder", row.folder),
31119
+ requireString("messages.subject", row.subject),
31120
+ requireString("messages.fromUser", row.fromUser),
31121
+ requireString("messages.sentAt", row.sentAt),
31122
+ JSON.stringify(row.recipients ?? []),
31123
+ nullish3(row.body),
31124
+ nullish3(row.fetchedBodyAt),
31125
+ nullish3(row.replyToId),
31126
+ nullish3(row.chainRootId),
31127
+ JSON.stringify(row.listData ?? null),
31121
31128
  (/* @__PURE__ */ new Date()).toISOString()
31122
31129
  );
31123
31130
  }
@@ -31207,12 +31214,12 @@ function upsertDraft(row) {
31207
31214
  list_data_json=excluded.list_data_json`
31208
31215
  ).run(
31209
31216
  row.id,
31210
- row.subject,
31211
- row.body,
31212
- JSON.stringify(row.recipients),
31213
- row.replyToId,
31214
- row.modifiedAt,
31215
- JSON.stringify(row.listData)
31217
+ requireString("drafts.subject", row.subject),
31218
+ requireString("drafts.body", row.body),
31219
+ JSON.stringify(row.recipients ?? []),
31220
+ nullish3(row.replyToId),
31221
+ requireString("drafts.modifiedAt", row.modifiedAt),
31222
+ JSON.stringify(row.listData ?? null)
31216
31223
  );
31217
31224
  }
31218
31225
  function getDraft(id) {
@@ -31329,9 +31336,9 @@ async function syncMessageFolder(client2, folder, folderId, opts) {
31329
31336
  const row = {
31330
31337
  id: item.id,
31331
31338
  folder,
31332
- subject: item.subject,
31339
+ subject: item.subject ?? "(no subject)",
31333
31340
  fromUser: item.from?.name ?? "",
31334
- sentAt: item.date.dateTime,
31341
+ sentAt: item.date?.dateTime ?? (/* @__PURE__ */ new Date()).toISOString(),
31335
31342
  recipients: recipientsFromList(item),
31336
31343
  body,
31337
31344
  fetchedBodyAt,
@@ -31359,22 +31366,23 @@ async function syncDrafts(client2, draftsFolderId) {
31359
31366
  let synced = 0;
31360
31367
  for (const item of items) {
31361
31368
  seenIds.add(item.id);
31369
+ const modifiedAt = item.date?.dateTime ?? (/* @__PURE__ */ new Date()).toISOString();
31362
31370
  const existing = getDraft(item.id);
31363
- if (existing && existing.modifiedAt === item.date.dateTime) {
31371
+ if (existing && existing.modifiedAt === modifiedAt) {
31364
31372
  continue;
31365
31373
  }
31366
31374
  const detail = await client2.request("GET", `/pub/v3/messages/${item.id}`);
31367
31375
  const row = {
31368
31376
  id: item.id,
31369
- subject: detail.subject ?? item.subject,
31377
+ subject: detail.subject ?? item.subject ?? "(no subject)",
31370
31378
  body: detail.body ?? "",
31371
31379
  recipients: (item.recipients ?? []).map((r) => ({
31372
- userId: r.user.id,
31373
- name: r.user.name,
31380
+ userId: r.user?.id ?? 0,
31381
+ name: r.user?.name ?? "",
31374
31382
  viewedAt: r.viewed?.dateTime ?? null
31375
31383
  })),
31376
- replyToId: item.replyToId,
31377
- modifiedAt: item.date.dateTime,
31384
+ replyToId: item.replyToId ?? null,
31385
+ modifiedAt,
31378
31386
  listData: item
31379
31387
  };
31380
31388
  upsertDraft(row);
@@ -31833,7 +31841,7 @@ process.emit = function(event, ...args) {
31833
31841
  }
31834
31842
  return originalEmit(event, ...args);
31835
31843
  };
31836
- var server = new McpServer({ name: "ofw", version: "2.0.7" });
31844
+ var server = new McpServer({ name: "ofw", version: "2.0.8" });
31837
31845
  registerUserTools(server, client);
31838
31846
  registerMessageTools(server, client);
31839
31847
  registerCalendarTools(server, client);
package/dist/cache.js CHANGED
@@ -79,6 +79,18 @@ function rowFromDb(r) {
79
79
  listData: JSON.parse(r.list_data_json),
80
80
  };
81
81
  }
82
+ // node:sqlite rejects `undefined` as a bound parameter ("Provided value cannot
83
+ // be bound"). Normalize undefined to null for nullable columns so callers
84
+ // don't have to remember; throw with a useful error for NOT NULL fields that
85
+ // somehow arrived as undefined.
86
+ function nullish(v) {
87
+ return v === undefined ? null : v;
88
+ }
89
+ function requireString(field, v) {
90
+ if (typeof v === 'string')
91
+ return v;
92
+ throw new Error(`cache: ${field} is required (got ${v === undefined ? 'undefined' : 'null'})`);
93
+ }
82
94
  export function upsertMessage(row) {
83
95
  const { db } = openCache();
84
96
  db.prepare(`INSERT INTO messages (
@@ -96,7 +108,7 @@ export function upsertMessage(row) {
96
108
  reply_to_id=excluded.reply_to_id,
97
109
  chain_root_id=excluded.chain_root_id,
98
110
  list_data_json=excluded.list_data_json,
99
- last_seen_at=excluded.last_seen_at`).run(row.id, row.folder, row.subject, row.fromUser, row.sentAt, JSON.stringify(row.recipients), row.body, row.fetchedBodyAt, row.replyToId, row.chainRootId, JSON.stringify(row.listData), new Date().toISOString());
111
+ last_seen_at=excluded.last_seen_at`).run(row.id, requireString('messages.folder', row.folder), requireString('messages.subject', row.subject), requireString('messages.fromUser', row.fromUser), requireString('messages.sentAt', row.sentAt), JSON.stringify(row.recipients ?? []), nullish(row.body), nullish(row.fetchedBodyAt), nullish(row.replyToId), nullish(row.chainRootId), JSON.stringify(row.listData ?? null), new Date().toISOString());
100
112
  }
101
113
  export function getMessage(id) {
102
114
  const { db } = openCache();
@@ -179,7 +191,7 @@ export function upsertDraft(row) {
179
191
  recipients_json=excluded.recipients_json,
180
192
  reply_to_id=excluded.reply_to_id,
181
193
  modified_at=excluded.modified_at,
182
- list_data_json=excluded.list_data_json`).run(row.id, row.subject, row.body, JSON.stringify(row.recipients), row.replyToId, row.modifiedAt, JSON.stringify(row.listData));
194
+ list_data_json=excluded.list_data_json`).run(row.id, requireString('drafts.subject', row.subject), requireString('drafts.body', row.body), JSON.stringify(row.recipients ?? []), nullish(row.replyToId), requireString('drafts.modifiedAt', row.modifiedAt), JSON.stringify(row.listData ?? null));
183
195
  }
184
196
  export function getDraft(id) {
185
197
  const { db } = openCache();
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import { registerMessageTools } from './tools/messages.js';
17
17
  import { registerCalendarTools } from './tools/calendar.js';
18
18
  import { registerExpenseTools } from './tools/expenses.js';
19
19
  import { registerJournalTools } from './tools/journal.js';
20
- const server = new McpServer({ name: 'ofw', version: '2.0.7' });
20
+ const server = new McpServer({ name: 'ofw', version: '2.0.8' });
21
21
  registerUserTools(server, client);
22
22
  registerMessageTools(server, client);
23
23
  registerCalendarTools(server, client);
package/dist/sync.js CHANGED
@@ -62,9 +62,9 @@ export async function syncMessageFolder(client, folder, folderId, opts) {
62
62
  const row = {
63
63
  id: item.id,
64
64
  folder,
65
- subject: item.subject,
65
+ subject: item.subject ?? '(no subject)',
66
66
  fromUser: item.from?.name ?? '',
67
- sentAt: item.date.dateTime,
67
+ sentAt: item.date?.dateTime ?? new Date().toISOString(),
68
68
  recipients: recipientsFromList(item),
69
69
  body,
70
70
  fetchedBodyAt,
@@ -98,20 +98,23 @@ export async function syncDrafts(client, draftsFolderId) {
98
98
  let synced = 0;
99
99
  for (const item of items) {
100
100
  seenIds.add(item.id);
101
+ const modifiedAt = item.date?.dateTime ?? new Date().toISOString();
101
102
  const existing = getDraft(item.id);
102
- if (existing && existing.modifiedAt === item.date.dateTime) {
103
+ if (existing && existing.modifiedAt === modifiedAt) {
103
104
  continue;
104
105
  }
105
106
  const detail = await client.request('GET', `/pub/v3/messages/${item.id}`);
106
107
  const row = {
107
108
  id: item.id,
108
- subject: detail.subject ?? item.subject,
109
+ subject: detail.subject ?? item.subject ?? '(no subject)',
109
110
  body: detail.body ?? '',
110
111
  recipients: (item.recipients ?? []).map((r) => ({
111
- userId: r.user.id, name: r.user.name, viewedAt: r.viewed?.dateTime ?? null,
112
+ userId: r.user?.id ?? 0,
113
+ name: r.user?.name ?? '',
114
+ viewedAt: r.viewed?.dateTime ?? null,
112
115
  })),
113
- replyToId: item.replyToId,
114
- modifiedAt: item.date.dateTime,
116
+ replyToId: item.replyToId ?? null,
117
+ modifiedAt,
115
118
  listData: item,
116
119
  };
117
120
  upsertDraft(row);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofw-mcp",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "mcpName": "io.github.chrischall/ofw-mcp",
5
5
  "description": "OurFamilyWizard MCP server for Claude — developed and maintained by AI (Claude Code)",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/ofw-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "2.0.7",
9
+ "version": "2.0.8",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "ofw-mcp",
14
- "version": "2.0.7",
14
+ "version": "2.0.8",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },