ofw-mcp 2.4.0 → 2.4.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 +37 -2
- package/.mcp.json +5 -2
- package/dist/bundle.js +26 -3
- package/dist/client.js +6 -0
- package/dist/env-bootstrap.js +28 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "OurFamilyWizard tools for Claude Code",
|
|
9
|
-
"version": "2.4.
|
|
9
|
+
"version": "2.4.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.4.
|
|
17
|
+
"version": "2.4.1",
|
|
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.4.
|
|
4
|
+
"version": "2.4.1",
|
|
5
5
|
"description": "OurFamilyWizard co-parenting tools for Claude — messages, calendar, expenses, and journal via MCP",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Chall"
|
|
@@ -17,5 +17,40 @@
|
|
|
17
17
|
"family"
|
|
18
18
|
],
|
|
19
19
|
"skills": "./skills/",
|
|
20
|
-
"mcp": "./.mcp.json"
|
|
20
|
+
"mcp": "./.mcp.json",
|
|
21
|
+
"userConfig": {
|
|
22
|
+
"ofw_username": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"title": "OFW Email",
|
|
25
|
+
"description": "Your OurFamilyWizard login email address. Optional — if omitted, the server falls back to the fetchproxy browser extension (requires being signed in to ourfamilywizard.com in your browser).",
|
|
26
|
+
"required": false
|
|
27
|
+
},
|
|
28
|
+
"ofw_password": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"title": "OFW Password",
|
|
31
|
+
"description": "Your OurFamilyWizard password. Optional — see ofw_username.",
|
|
32
|
+
"required": false,
|
|
33
|
+
"sensitive": true
|
|
34
|
+
},
|
|
35
|
+
"ofw_inline_attachments": {
|
|
36
|
+
"type": "boolean",
|
|
37
|
+
"title": "Return attachments inline",
|
|
38
|
+
"description": "When on, ofw_download_attachment returns bytes inline as MCP content (images render directly; other files come back as embedded resources) instead of writing to disk. Recommended for sandboxed hosts like Claude Desktop where the model cannot read files written to ~/Downloads. Callers can still override per-call via the tool's `inline` argument.",
|
|
39
|
+
"required": false,
|
|
40
|
+
"default": false
|
|
41
|
+
},
|
|
42
|
+
"ofw_attachments_dir": {
|
|
43
|
+
"type": "directory",
|
|
44
|
+
"title": "Attachments download directory",
|
|
45
|
+
"description": "Directory where ofw_download_attachment writes files when not returning inline. Defaults to ~/Downloads/ofw-mcp/. Pick a directory that is readable by your MCP host.",
|
|
46
|
+
"required": false
|
|
47
|
+
},
|
|
48
|
+
"ofw_write_mode": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"title": "Write mode",
|
|
51
|
+
"description": "Structural write gate. \"none\" = no write tools registered (read/sync/search only); \"drafts\" = draft-level writes only (save/delete drafts, upload attachments — never send or calendar/expense/journal writes); \"all\" = everything (default). Unrecognized values fail closed to \"none\".",
|
|
52
|
+
"required": false,
|
|
53
|
+
"default": "all"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
21
56
|
}
|
package/.mcp.json
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
"command": "npx",
|
|
5
5
|
"args": ["-y", "ofw-mcp"],
|
|
6
6
|
"env": {
|
|
7
|
-
"OFW_USERNAME": "${
|
|
8
|
-
"OFW_PASSWORD": "${
|
|
7
|
+
"OFW_USERNAME": "${user_config.ofw_username}",
|
|
8
|
+
"OFW_PASSWORD": "${user_config.ofw_password}",
|
|
9
|
+
"OFW_INLINE_ATTACHMENTS": "${user_config.ofw_inline_attachments}",
|
|
10
|
+
"OFW_ATTACHMENTS_DIR": "${user_config.ofw_attachments_dir}",
|
|
11
|
+
"OFW_WRITE_MODE": "${user_config.ofw_write_mode}"
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
}
|
package/dist/bundle.js
CHANGED
|
@@ -13,7 +13,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
13
13
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
14
14
|
});
|
|
15
15
|
var __commonJS = (cb, mod) => function __require2() {
|
|
16
|
-
|
|
16
|
+
try {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
throw mod = 0, e;
|
|
20
|
+
}
|
|
17
21
|
};
|
|
18
22
|
var __export = (target, all) => {
|
|
19
23
|
for (var name in all)
|
|
@@ -38146,7 +38150,7 @@ function getDefaultInlineAttachments() {
|
|
|
38146
38150
|
// package.json
|
|
38147
38151
|
var package_default = {
|
|
38148
38152
|
name: "ofw-mcp",
|
|
38149
|
-
version: "2.4.
|
|
38153
|
+
version: "2.4.1",
|
|
38150
38154
|
license: "MIT",
|
|
38151
38155
|
mcpName: "io.github.chrischall/ofw-mcp",
|
|
38152
38156
|
description: "OurFamilyWizard MCP server for Claude \u2014 developed and maintained by AI (Claude Code)",
|
|
@@ -38257,7 +38261,26 @@ async function resolveAuth() {
|
|
|
38257
38261
|
);
|
|
38258
38262
|
}
|
|
38259
38263
|
|
|
38264
|
+
// src/env-bootstrap.ts
|
|
38265
|
+
var USER_CONFIG_KEYS = [
|
|
38266
|
+
"OFW_USERNAME",
|
|
38267
|
+
"OFW_PASSWORD",
|
|
38268
|
+
"OFW_INLINE_ATTACHMENTS",
|
|
38269
|
+
"OFW_ATTACHMENTS_DIR",
|
|
38270
|
+
"OFW_WRITE_MODE"
|
|
38271
|
+
];
|
|
38272
|
+
function clearBlankInjectedEnv(env = process.env, keys = USER_CONFIG_KEYS) {
|
|
38273
|
+
for (const key of keys) {
|
|
38274
|
+
const value = env[key];
|
|
38275
|
+
if (value === void 0) continue;
|
|
38276
|
+
if (value.trim() === "" || value.includes("${")) {
|
|
38277
|
+
delete env[key];
|
|
38278
|
+
}
|
|
38279
|
+
}
|
|
38280
|
+
}
|
|
38281
|
+
|
|
38260
38282
|
// src/client.ts
|
|
38283
|
+
clearBlankInjectedEnv();
|
|
38261
38284
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
38262
38285
|
await loadDotenvSafely({ path: join4(__dirname, "..", ".env") });
|
|
38263
38286
|
function parseContentDispositionFilename(cd) {
|
|
@@ -39783,7 +39806,7 @@ process.emit = function(event, ...args) {
|
|
|
39783
39806
|
};
|
|
39784
39807
|
await runMcp({
|
|
39785
39808
|
name: "ofw",
|
|
39786
|
-
version: "2.4.
|
|
39809
|
+
version: "2.4.1",
|
|
39787
39810
|
// x-release-please-version
|
|
39788
39811
|
deps: client,
|
|
39789
39812
|
tools: [
|
package/dist/client.js
CHANGED
|
@@ -4,7 +4,13 @@ import { dirname, join } from 'path';
|
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { resolveAuth } from './auth.js';
|
|
6
6
|
import { parseBoolEnv } from './config.js';
|
|
7
|
+
import { clearBlankInjectedEnv } from './env-bootstrap.js';
|
|
7
8
|
import { BASE_URL, OFW_PROTOCOL_HEADERS, OFW_TOKEN_TTL_MS, OFW_TOKEN_EXPIRY_SKEW_MS } from './protocol.js';
|
|
9
|
+
// When the plugin runs via a host that maps creds from optional
|
|
10
|
+
// `${user_config.*}` fields, an unset field can be injected as a blank /
|
|
11
|
+
// placeholder env value. Clear those first so the next step's .env (and the
|
|
12
|
+
// shell env) can still populate them — a filled field keeps its real value.
|
|
13
|
+
clearBlankInjectedEnv();
|
|
8
14
|
// Load .env for local dev; silently skip if dotenv is unavailable (e.g. mcpb
|
|
9
15
|
// bundle). loadDotenvSafely applies override:false + quiet:true and swallows a
|
|
10
16
|
// missing dotenv module, matching the prior inline try/catch exactly.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Credentials + config the plugin's .mcp.json maps from `${user_config.*}`.
|
|
2
|
+
// These are the keys whose host-injected values we sanity-check before
|
|
3
|
+
// loading .env.
|
|
4
|
+
export const USER_CONFIG_KEYS = [
|
|
5
|
+
'OFW_USERNAME',
|
|
6
|
+
'OFW_PASSWORD',
|
|
7
|
+
'OFW_INLINE_ATTACHMENTS',
|
|
8
|
+
'OFW_ATTACHMENTS_DIR',
|
|
9
|
+
'OFW_WRITE_MODE',
|
|
10
|
+
];
|
|
11
|
+
// A host that maps an UNSET optional `${user_config.x}` into the server env
|
|
12
|
+
// may inject the key as an empty string or the literal, unexpanded
|
|
13
|
+
// "${user_config.x}". Either one SHADOWS the user's `.env`/shell value,
|
|
14
|
+
// because the server loads .env with dotenv `override:false` (it won't
|
|
15
|
+
// replace a key that's already present). Clearing those blanks first lets the
|
|
16
|
+
// `.env`/shell credential path keep working when the Connectors field is left
|
|
17
|
+
// empty — while a real, user-provided value is left untouched (so the desktop
|
|
18
|
+
// userConfig path still wins when set).
|
|
19
|
+
export function clearBlankInjectedEnv(env = process.env, keys = USER_CONFIG_KEYS) {
|
|
20
|
+
for (const key of keys) {
|
|
21
|
+
const value = env[key];
|
|
22
|
+
if (value === undefined)
|
|
23
|
+
continue;
|
|
24
|
+
if (value.trim() === '' || value.includes('${')) {
|
|
25
|
+
delete env[key];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import { registerJournalTools } from './tools/journal.js';
|
|
|
24
24
|
// always succeeds before any credential check runs.
|
|
25
25
|
await runMcp({
|
|
26
26
|
name: 'ofw',
|
|
27
|
-
version: '2.4.
|
|
27
|
+
version: '2.4.1', // x-release-please-version
|
|
28
28
|
deps: client,
|
|
29
29
|
tools: [
|
|
30
30
|
registerUserTools,
|
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.4.
|
|
9
|
+
"version": "2.4.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "ofw-mcp",
|
|
14
|
-
"version": "2.4.
|
|
14
|
+
"version": "2.4.1",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|