ofw-mcp 2.15.0 → 2.15.1
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/ofw/SKILL.md +36 -3
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "OurFamilyWizard tools for Claude Code",
|
|
9
|
-
"version": "2.15.
|
|
9
|
+
"version": "2.15.1"
|
|
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.15.
|
|
17
|
+
"version": "2.15.1",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Chris Chall"
|
|
20
20
|
},
|
package/dist/bundle.js
CHANGED
|
@@ -39910,7 +39910,7 @@ async function loginWithPassword(username, password) {
|
|
|
39910
39910
|
// package.json
|
|
39911
39911
|
var package_default = {
|
|
39912
39912
|
name: "ofw-mcp",
|
|
39913
|
-
version: "2.15.
|
|
39913
|
+
version: "2.15.1",
|
|
39914
39914
|
license: "MIT",
|
|
39915
39915
|
mcpName: "io.github.chrischall/ofw-mcp",
|
|
39916
39916
|
description: "OurFamilyWizard MCP server for Claude \u2014 developed and maintained by AI (Claude Code)",
|
|
@@ -44895,7 +44895,7 @@ var nodeCacheProvider = () => nodeCache ??= OFWCache.open(getCacheDbPath());
|
|
|
44895
44895
|
var nodeAttachmentIO = new NodeAttachmentIO();
|
|
44896
44896
|
await runMcp({
|
|
44897
44897
|
name: "ofw",
|
|
44898
|
-
version: "2.15.
|
|
44898
|
+
version: "2.15.1",
|
|
44899
44899
|
// x-release-please-version
|
|
44900
44900
|
deps: client,
|
|
44901
44901
|
tools: [
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ const nodeAttachmentIO = new NodeAttachmentIO();
|
|
|
36
36
|
// always succeeds before any credential check runs.
|
|
37
37
|
await runMcp({
|
|
38
38
|
name: 'ofw',
|
|
39
|
-
version: '2.15.
|
|
39
|
+
version: '2.15.1', // x-release-please-version
|
|
40
40
|
deps: client,
|
|
41
41
|
tools: [
|
|
42
42
|
registerHealthcheckTools,
|
package/package.json
CHANGED
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.15.
|
|
9
|
+
"version": "2.15.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "ofw-mcp",
|
|
14
|
-
"version": "2.15.
|
|
14
|
+
"version": "2.15.1",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
package/skills/ofw/SKILL.md
CHANGED
|
@@ -92,11 +92,11 @@ Always pass `--config ~/.mcporter/mcporter.json` unless a local `config/mcporter
|
|
|
92
92
|
|------|-------|
|
|
93
93
|
| `ofw_sync_messages(folders?, deep?, fetchUnreadBodies?)` | Sync OFW → local cache. **Call first if the cache might be stale.** Returns unread inbox hints (bodies not fetched, to avoid mark-as-read). |
|
|
94
94
|
| `ofw_list_message_folders` | List OFW folders with unread counts. Most reads use the cache; this is mainly for folder IDs and live unread counts. |
|
|
95
|
-
| `ofw_list_messages(folderId?, since?, until?, q?, sort?, page?, size?, autoRefresh?)` | Cache-backed list. Supports folder ("inbox"/"sent"/"both"), date range, and substring search. `sort:"oldest"` starts at the old end of a range instead of paging to it (default `"newest"`). Returns `complete` for the RESULT SET plus **`nextPage`** (null when done) — and the paging keys come FIRST in the JSON, before `messages`. `returned` carries the record count as a scalar, beside `total`. An **empty** result from a non-fresh cache is refused (`UNVERIFIED_EMPTY`) — pass `autoRefresh:true` to sync and answer instead. |
|
|
96
|
-
| `ofw_get_message(messageId, allowMarkRead?)` | Read a message OR draft body. Cache-first. Ids in the drafts cache return `folder: "drafts"`. ⚠️ Falls through to OFW for unread inbox messages, which marks them read AND stamps a "First Viewed" time the co-parent can see — irreversible. Pass `allowMarkRead:false` to refuse that fetch instead; cached, sent and already-read messages are unaffected. |
|
|
95
|
+
| `ofw_list_messages(folderId?, since?, until?, q?, sort?, page?, size?, autoRefresh?, view?)` | Cache-backed list. Supports folder ("inbox"/"sent"/"both"), date range, and substring search. `sort:"oldest"` starts at the old end of a range instead of paging to it (default `"newest"`). Returns `complete` for the RESULT SET plus **`nextPage`** (null when done) — and the paging keys come FIRST in the JSON, before `messages`. `returned` carries the record count as a scalar, beside `total`. An **empty** result from a non-fresh cache is refused (`UNVERIFIED_EMPTY`) — pass `autoRefresh:true` to sync and answer instead. |
|
|
96
|
+
| `ofw_get_message(messageId, allowMarkRead?, view?)` | Read a message OR draft body. Cache-first. Ids in the drafts cache return `folder: "drafts"`. ⚠️ Falls through to OFW for unread inbox messages, which marks them read AND stamps a "First Viewed" time the co-parent can see — irreversible. Pass `allowMarkRead:false` to refuse that fetch instead; cached, sent and already-read messages are unaffected. |
|
|
97
97
|
| `ofw_send_message(draftId?, subject?, body?, recipientIds?, replyToId?, expectedRevision?, deleteDraftOnSuccess?, myFileIDs?, force?)` | Send a message — **the one irreversible operation**. Preferred path: pass `draftId` (+ `expectedRevision`) to send an existing draft **as it exists on the server** — the tool re-reads it from OFW first and refuses if it changed since you read it (or was already sent/deleted); `subject`/`body` become optional overrides. `recipientIds` is usually still required: OFW does not store recipients on drafts. After a **confirmed** send the draft is auto-deleted (`deleteDraftOnSuccess:false` to keep it); on any failure or ambiguity it is retained and the response says why (`draftRetained`). Response leads with `sentMessageId`, `draftKey`, `threaded`, `draftDeleted`. Compose from scratch by passing `subject`/`body`/`recipientIds` with no `draftId`. |
|
|
98
98
|
| `ofw_get_unread_sent(page?, size?, autoRefresh?)` | Sent messages your co-parent hasn't read yet (from cache). Leads with `complete`/`hasMore`/`nextPage`, then `scanned`/`total`, then `unread`; an empty sent cache that is not fresh is refused rather than reported as "nothing sent". |
|
|
99
|
-
| `ofw_list_drafts(page?, size?, verify?, autoRefresh?)` | Leads with `complete`/`hasMore`/`nextPage`; `drafts` comes last. List saved drafts, **auto-verified**: when the cache is not verified-fresh a cheap drafts sync runs first (default `verify:true`), so one call answers server-confirmed. `verify:false` serves straight from cache. Each draft carries `serverConfirmed`, `revision` and `draftKey`. Returns `complete` — **check it before saying "you have N drafts"**. See [Freshness](#freshness). |
|
|
99
|
+
| `ofw_list_drafts(page?, size?, verify?, autoRefresh?, view?)` | Leads with `complete`/`hasMore`/`nextPage`; `drafts` comes last. List saved drafts, **auto-verified**: when the cache is not verified-fresh a cheap drafts sync runs first (default `verify:true`), so one call answers server-confirmed. `verify:false` serves straight from cache. Each draft carries `serverConfirmed`, `revision` and `draftKey`. Returns `complete` — **check it before saying "you have N drafts"**. See [Freshness](#freshness). |
|
|
100
100
|
| `ofw_save_draft(subject, body, recipientIds?, messageId?, replyToId?, myFileIDs?, expectedRevision?, force?)` | Create a new draft. Pass `messageId` to **replace** an existing draft: the tool creates a fresh draft and deletes the old one (OFW's update-in-place endpoint silently no-ops). The returned `id` is the NEW id; the response leads with `draftKey`, which stays the same across every edit — **track that, not the id**. Note: OFW does **not** store recipients on drafts — `recipientIds` are accepted but come back empty (a one-line NOTE says so; supply them at send time instead). Threading warnings fire only on genuine drops — a draft echoing `inReplyTo`/`showContext` IS threaded. |
|
|
101
101
|
| `ofw_delete_draft(messageId)` | Delete a draft. |
|
|
102
102
|
| `ofw_upload_attachment(path, shareClass?, label?, description?)` | Upload a local file to My Files; returns a fileId to pass into `myFileIDs`. |
|
|
@@ -125,6 +125,39 @@ Always pass `--config ~/.mcporter/mcporter.json` unless a local `config/mcporter
|
|
|
125
125
|
| `ofw_list_journal_entries(start?, max?)` | 1-based offset; default max 10 |
|
|
126
126
|
| `ofw_create_journal_entry(title, body)` | Create a new entry |
|
|
127
127
|
|
|
128
|
+
## Response shape (`view`)
|
|
129
|
+
|
|
130
|
+
`ofw_list_messages`, `ofw_get_message` and `ofw_list_drafts` take
|
|
131
|
+
`view: "compact" | "full"`, and **`compact` is the default** — you get the slim
|
|
132
|
+
shape without asking. It measured 135.1 KB → 41.1 KB on a real 50-message page.
|
|
133
|
+
|
|
134
|
+
What compact drops is `listData`, OFW's echo of the list payload. That blob was
|
|
135
|
+
58% of the response and 78% of it duplicated fields the same object already
|
|
136
|
+
emits at the top level — eleven pre-formatted renderings of one timestamp,
|
|
137
|
+
eight fields per recipient beside the three the row already normalised, and a
|
|
138
|
+
`preview` that is a truncation of the `body` in the same object.
|
|
139
|
+
|
|
140
|
+
**Two things about compact that will surprise you if you don't know them:**
|
|
141
|
+
|
|
142
|
+
- **The sender is `from`, not `fromUser`.** `fromUser` is the empty string on
|
|
143
|
+
every row — inbox and sent alike — because OFW names the sender only inside
|
|
144
|
+
`listData.author`. So compact promotes it. Dropping `listData` without that
|
|
145
|
+
would have taken the sender off every message; this is the one field the fat
|
|
146
|
+
blob was carrying alone.
|
|
147
|
+
- **On a draft, `ofw_get_message` returns `from: null`** — a draft is unsent, so
|
|
148
|
+
there is no sender, and `""` would read as one we failed to find.
|
|
149
|
+
|
|
150
|
+
Pass `view: "full"` when you need a field compact dropped — `listData` and
|
|
151
|
+
everything in it. There is deliberately **no `raw` rung**: a message here is
|
|
152
|
+
assembled from a list item, a detail GET and derived fields, so there is no
|
|
153
|
+
single upstream payload to hand back, and a rung that skipped normalisation
|
|
154
|
+
would put naive local times back beside UTC ones on exactly the rung you reach
|
|
155
|
+
for when something already looks wrong.
|
|
156
|
+
|
|
157
|
+
`ofw_get_unread_sent` takes no `view`: it emits a verdict list
|
|
158
|
+
(`{id, subject, sentAt, unreadBy}`) that is already narrower than the
|
|
159
|
+
projection.
|
|
160
|
+
|
|
128
161
|
## Freshness, completeness, and lifecycle
|
|
129
162
|
|
|
130
163
|
Message and draft reads come from a local cache, so **a result can be stale without looking stale**. Three separate questions, three separate signals — do not substitute one for another:
|