ofw-mcp 2.19.4 → 2.20.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +27 -4
- package/dist/auth.js +4 -4
- package/dist/bundle.js +1199 -180
- package/dist/client.js +4 -1
- package/dist/config.js +37 -0
- package/dist/index.js +13 -9
- package/dist/tool-surface.js +14 -0
- package/dist/tools/_shared.js +5 -1
- package/dist/tools/delivery.js +42 -2
- package/dist/tools/expenses.js +563 -56
- package/dist/tools/healthcheck.js +2 -2
- package/dist/tools/messages.js +2 -1
- package/package.json +3 -3
- package/server.json +14 -2
- package/skills/ofw/SKILL.md +11 -4
- package/skills/ofw-fpx/SKILL.md +5 -2
- package/skills/ofw-fpx/references/requests.md +58 -4
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "OurFamilyWizard tools for Claude Code",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.20.0"
|
|
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.
|
|
17
|
+
"version": "2.20.0",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Chris Chall"
|
|
20
20
|
},
|
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ Ask Claude: *"What does my OFW dashboard look like?"* — it should show your un
|
|
|
97
97
|
`ofw-mcp` tries three auth paths in order; whichever succeeds first is used. Existing setups keep working unchanged.
|
|
98
98
|
|
|
99
99
|
1. **Env-var credentials (legacy, recommended for Claude Desktop).** Set `OFW_USERNAME` + `OFW_PASSWORD` and the server logs in via OFW's form endpoint. This is the path shown in the Claude Desktop config above.
|
|
100
|
-
2. **fetchproxy fallback (no env vars needed).** When the credentials are absent, the server reads `localStorage["auth"]` once at startup from your already-signed-in `ourfamilywizard.com` tab via the [fetchproxy](https://github.com/chrischall/fetchproxy)
|
|
100
|
+
2. **fetchproxy fallback (no env vars needed).** When the credentials are absent, the server reads `localStorage["auth"]` once at startup from your already-signed-in `ourfamilywizard.com` tab via the **ContextMint Bridge** browser extension (built on [fetchproxy](https://github.com/chrischall/fetchproxy)). After that one read, all OFW API calls go directly from Node — the extension is **not** in the request hot path. Install ContextMint Bridge from its [releases page](https://github.com/nullnet-app/contextmint-bridge/releases) (Chrome: download the Chrome zip, unzip it, and load it unpacked at `chrome://extensions` with Developer mode on; Safari is not available yet — it will ship inside the ContextMint app, which has no public download — so use Chrome for now), sign into OurFamilyWizard once, and the MCP just works. ContextMint Bridge is the fetchproxy browser extension under its new name, from the same maintainer — fetchproxy's own README (https://github.com/chrischall/fetchproxy#extension) points to it. Its source is public at https://github.com/nullnet-app/contextmint-bridge: build it yourself, or check a release zip against the `.sha256` file published beside it (`shasum -a 256 -c contextmint-bridge-chrome-<version>.zip.sha256`). If you have multiple OFW accounts and want them to use separate caches, set `OFW_CACHE_IDENTITY` to a label per profile.
|
|
101
101
|
3. **Error.** If neither path is available, the server tells you exactly which fix to apply. Set `OFW_DISABLE_FETCHPROXY=1` to skip the fetchproxy fallback entirely (turns missing credentials into a hard error — useful in headless CI).
|
|
102
102
|
|
|
103
103
|
### Credential options (env-var path)
|
|
@@ -151,7 +151,10 @@ Read-only tools run automatically. Writes that reach your co-parent or the court
|
|
|
151
151
|
| `ofw_delete_event` | Delete a calendar event | Confirm (server) if shared | `all` (or `drafts` + `OFW_CALENDAR_WRITES`) |
|
|
152
152
|
| `ofw_get_expense_totals` | Expense summary totals | Auto | any |
|
|
153
153
|
| `ofw_list_expenses` | Expense history | Auto | any |
|
|
154
|
-
| `
|
|
154
|
+
| `ofw_list_expense_categories` | Expense category ids and split metadata | Auto | any |
|
|
155
|
+
| `ofw_upload_expense_pdf` | Upload a receipt PDF to My Files for an expense (SHARED — the co-parent sees it in My Files at once, even on a private expense) | Confirm (server) | `all` |
|
|
156
|
+
| `ofw_create_expense` | Log a new expense; supports private entries and one receipt PDF | Confirm (server) | `all` |
|
|
157
|
+
| `ofw_update_expense` | Change an expense, e.g. publish a private one. Pass only the fields to change; it reads the expense first so the rest are kept | Confirm (server) | `all` |
|
|
155
158
|
| `ofw_list_journal_entries` | Journal entries | Auto | any |
|
|
156
159
|
| `ofw_create_journal_entry` | Create a journal entry | Confirm | `all` |
|
|
157
160
|
|
|
@@ -250,6 +253,26 @@ The host's "Confirm" permission above is a *hint* to the MCP host — a host con
|
|
|
250
253
|
|
|
251
254
|
Unrecognized values fail closed to `none`, with a warning on stderr — a typo never silently grants write access.
|
|
252
255
|
|
|
256
|
+
#### Expense-only deployments
|
|
257
|
+
|
|
258
|
+
For a dedicated reimbursement integration, you can also structurally remove unrelated OFW capabilities:
|
|
259
|
+
|
|
260
|
+
| Setting | Registered surface |
|
|
261
|
+
|---|---|
|
|
262
|
+
| `OFW_EXPENSE_ONLY=true` | `ofw_healthcheck` plus the expense tools only. Profile/dashboard, messages, calendar, and journal tools do not exist. |
|
|
263
|
+
| `OFW_EXPENSE_UPLOAD_ONLY=true` | Strictest mode: `ofw_healthcheck`, `ofw_upload_expense_pdf`, `ofw_create_expense`, and `ofw_update_expense` only. Expense totals/listing are removed too. This flag implies `OFW_EXPENSE_ONLY`. |
|
|
264
|
+
|
|
265
|
+
These flags are registration-time restrictions, not prompt instructions. A host cannot call a tool that was never registered. Unrecognized non-empty flag values fail closed to the restricted state. `OFW_WRITE_MODE` still applies underneath; for the strict upload workflow set `OFW_WRITE_MODE=all` so expense creation is available.
|
|
266
|
+
|
|
267
|
+
Recommended reimbursement-only deployment:
|
|
268
|
+
|
|
269
|
+
```env
|
|
270
|
+
OFW_EXPENSE_UPLOAD_ONLY=true
|
|
271
|
+
OFW_WRITE_MODE=all
|
|
272
|
+
OFW_ALLOW_MARK_READ=false
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
|
|
253
276
|
### Reading is a write, too (`OFW_ALLOW_MARK_READ`)
|
|
254
277
|
|
|
255
278
|
Fetching a message body for the first time marks it read on OurFamilyWizard and stamps a **"First Viewed" timestamp your co-parent can see**. That is part of the record and cannot be undone — and it happens as a side effect of an ordinary read, so `OFW_WRITE_MODE` does not govern it.
|
|
@@ -275,9 +298,9 @@ Every outbound request passes its constructed URL through a host check before `f
|
|
|
275
298
|
|
|
276
299
|
**"0 messages"** — Claude may have read the notification counts rather than the actual messages. Ask explicitly: *"List the messages in my OFW inbox"* or *"Use ofw_list_message_folders then ofw_list_messages"*.
|
|
277
300
|
|
|
278
|
-
**"OFW auth: set OFW_USERNAME + OFW_PASSWORD, or install
|
|
301
|
+
**"OFW auth: set OFW_USERNAME + OFW_PASSWORD, or install ContextMint Bridge…"** — neither auth path is configured. Either fill in the `env` block in your Claude Desktop config, or install [ContextMint Bridge](https://github.com/nullnet-app/contextmint-bridge/releases) and sign into `ourfamilywizard.com` in your browser.
|
|
279
302
|
|
|
280
|
-
**"fetchproxy fallback failed"** — the env-var path wasn't configured and the extension couldn't be reached. Confirm
|
|
303
|
+
**"fetchproxy fallback failed"** / **"ContextMint Bridge is down"** — the env-var path wasn't configured and the extension couldn't be reached. Confirm ContextMint Bridge is installed, signed into OFW, and that it's running (open the extension popup). If you want to disable the fallback entirely, set `OFW_DISABLE_FETCHPROXY=1`.
|
|
281
304
|
|
|
282
305
|
**"OFW login not attempted — this OurFamilyWizard email and password were already rejected"** — OFW refused these credentials earlier in this session. OFW counts failed sign-ins against the account, so the server does not re-send a rejected password on every call. Update `OFW_USERNAME` / `OFW_PASSWORD` to your current login (or restart the server) and try again.
|
|
283
306
|
|
package/dist/auth.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
//
|
|
26
26
|
// 2. fetchproxy fallback (new)
|
|
27
27
|
// When credentials are absent, we try to lift the user's session
|
|
28
|
-
// out of their signed-in browser tab via
|
|
28
|
+
// out of their signed-in browser tab via ContextMint Bridge (fetchproxy).
|
|
29
29
|
// The `@fetchproxy/bootstrap` helper spins up a one-shot WebSocket
|
|
30
30
|
// bridge, asks the extension for `localStorage["auth"]` and
|
|
31
31
|
// `localStorage["tokenExpiry"]` from any ourfamilywizard.com tab,
|
|
@@ -80,7 +80,7 @@ function fetchproxyDisabled() {
|
|
|
80
80
|
* silently stopping matching the day this wording changed.
|
|
81
81
|
*/
|
|
82
82
|
export const NO_AUTH_CONFIGURED = 'OFW auth: set OFW_USERNAME + OFW_PASSWORD, ' +
|
|
83
|
-
'or install
|
|
83
|
+
'or install ContextMint Bridge and sign into ourfamilywizard.com ' +
|
|
84
84
|
'(unset OFW_DISABLE_FETCHPROXY if it is set).';
|
|
85
85
|
/**
|
|
86
86
|
* Prefix of the message raised when the fetchproxy bridge is unreachable.
|
|
@@ -92,7 +92,7 @@ export const NO_AUTH_CONFIGURED = 'OFW auth: set OFW_USERNAME + OFW_PASSWORD, '
|
|
|
92
92
|
* day the wording changed, while silently misreporting a downed bridge as an
|
|
93
93
|
* unconfigured server.
|
|
94
94
|
*/
|
|
95
|
-
export const BRIDGE_DOWN_PREFIX = 'OFW auth:
|
|
95
|
+
export const BRIDGE_DOWN_PREFIX = 'OFW auth: ContextMint Bridge is down';
|
|
96
96
|
/** True for the {@link BRIDGE_DOWN_PREFIX} failure and nothing else. */
|
|
97
97
|
export function isBridgeDown(e) {
|
|
98
98
|
return e instanceof Error && e.message.startsWith(BRIDGE_DOWN_PREFIX);
|
|
@@ -145,7 +145,7 @@ export async function resolveAuth() {
|
|
|
145
145
|
const expiryRaw = session.localStorage['tokenExpiry'];
|
|
146
146
|
if (!token) {
|
|
147
147
|
throw new Error('localStorage["auth"] missing on ourfamilywizard.com. ' +
|
|
148
|
-
'Sign into OFW in your browser (with
|
|
148
|
+
'Sign into OFW in your browser (with ContextMint Bridge installed) and retry.');
|
|
149
149
|
}
|
|
150
150
|
return {
|
|
151
151
|
credential: token,
|