ofw-mcp 2.4.1 → 2.4.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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "OurFamilyWizard tools for Claude Code",
9
- "version": "2.4.1"
9
+ "version": "2.4.2"
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.1",
17
+ "version": "2.4.2",
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.1",
4
+ "version": "2.4.2",
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,40 +17,5 @@
17
17
  "family"
18
18
  ],
19
19
  "skills": "./skills/",
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
- }
20
+ "mcp": "./.mcp.json"
56
21
  }
package/.mcp.json CHANGED
@@ -4,11 +4,8 @@
4
4
  "command": "npx",
5
5
  "args": ["-y", "ofw-mcp"],
6
6
  "env": {
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}"
7
+ "OFW_USERNAME": "${OFW_USERNAME}",
8
+ "OFW_PASSWORD": "${OFW_PASSWORD}"
12
9
  }
13
10
  }
14
11
  }
package/dist/bundle.js CHANGED
@@ -38150,7 +38150,7 @@ function getDefaultInlineAttachments() {
38150
38150
  // package.json
38151
38151
  var package_default = {
38152
38152
  name: "ofw-mcp",
38153
- version: "2.4.1",
38153
+ version: "2.4.2",
38154
38154
  license: "MIT",
38155
38155
  mcpName: "io.github.chrischall/ofw-mcp",
38156
38156
  description: "OurFamilyWizard MCP server for Claude \u2014 developed and maintained by AI (Claude Code)",
@@ -38261,26 +38261,7 @@ async function resolveAuth() {
38261
38261
  );
38262
38262
  }
38263
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
-
38282
38264
  // src/client.ts
38283
- clearBlankInjectedEnv();
38284
38265
  var __dirname = dirname(fileURLToPath(import.meta.url));
38285
38266
  await loadDotenvSafely({ path: join4(__dirname, "..", ".env") });
38286
38267
  function parseContentDispositionFilename(cd) {
@@ -39806,7 +39787,7 @@ process.emit = function(event, ...args) {
39806
39787
  };
39807
39788
  await runMcp({
39808
39789
  name: "ofw",
39809
- version: "2.4.1",
39790
+ version: "2.4.2",
39810
39791
  // x-release-please-version
39811
39792
  deps: client,
39812
39793
  tools: [
package/dist/client.js CHANGED
@@ -4,13 +4,7 @@ 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';
8
7
  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();
14
8
  // Load .env for local dev; silently skip if dotenv is unavailable (e.g. mcpb
15
9
  // bundle). loadDotenvSafely applies override:false + quiet:true and swallows a
16
10
  // missing dotenv module, matching the prior inline try/catch exactly.
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.1', // x-release-please-version
27
+ version: '2.4.2', // x-release-please-version
28
28
  deps: client,
29
29
  tools: [
30
30
  registerUserTools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofw-mcp",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "license": "MIT",
5
5
  "mcpName": "io.github.chrischall/ofw-mcp",
6
6
  "description": "OurFamilyWizard MCP server for Claude — developed and maintained by AI (Claude Code)",
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.1",
9
+ "version": "2.4.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "ofw-mcp",
14
- "version": "2.4.1",
14
+ "version": "2.4.2",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -1,28 +0,0 @@
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
- }