数据分析

Tmp.BcPQA7YzJI

试用

让你的智能体读写 OurFamilyWizard 的消息、日程、费用和日志。

它能做什么

为 OurFamilyWizard 提供读写的 MCP 接口,可访问共同育儿数据:收件箱与发件箱消息、草稿、日程事件、共同费用与亲子日志。消息和草稿走本地缓存,每次返回都带 staleness、asOf、ageSeconds、serverConfirmed 等新鲜度信号,便于区分缓存结果与实时状态;无法在线核实时工具会以 UNVERIFIED_EMPTY 拒绝报告。发信、删除日程、读取收件箱消息都属于对具备法律效力的记录的不可逆副作用,操作前需用户明确确认。可通过 .mcp.json 或 mcporter 注册,凭据使用环境变量 OFW_USERNAME 与 OFW_PASSWORD。

什么时候用它

  • 查看 OFW 收件箱与共同家长往来消息
  • 按日期范围查询共享日程事件
  • 登记一笔新的共同费用
  • 审核后再发送草稿消息给共同家长

技能文档

ofw-mcp

MCP server for OurFamilyWizard — provides read/write access to messages, calendar, expenses, and journal.

Setup

Option A — Claude Code (direct MCP, no mcporter)

Add to .mcp.json in your project or ~/.claude/mcp.json:

{
  "mcpServers": {
    "ofw": {
      "command": "npx",
      "args": ["-y", "ofw-mcp"],
      "env": {
        "OFW_USERNAME": "you@example.com",
        "OFW_PASSWORD": "yourpassword"
      }
    }
  }
}

Option B — mcporter

1. Install

npm install -g ofw-mcp

Or from source:

git clone https://github.com/chrischall/ofw-mcp
cd ofw-mcp
npm install && npm run build

2. Configure credentials

cp .env.example .env
# Edit .env: set OFW_USERNAME and OFW_PASSWORD

3. Register with mcporter

mcporter config add ofw \
  --command "ofw-mcp" \
  --env "OFW_USERNAME=you@example.com" \
  --env "OFW_PASSWORD=yourpassword" \
  --config ~/.mcporter/mcporter.json

4. Verify

mcporter list --config ~/.mcporter/mcporter.json
mcporter call ofw.ofw_get_profile --config ~/.mcporter/mcporter.json

Calling tools (mcporter)

mcporter call ofw. [key=value ...] --config ~/.mcporter/mcporter.json

Always pass --config ~/.mcporter/mcporter.json unless a local config/mcporter.json exists.

Tools

User

ToolDescription
ofw_get_profileCurrent user + co-parent info (IDs, contact details)
ofw_get_notificationsDashboard summary: unread count, upcoming events, outstanding expenses. ⚠️ Updates last-seen status.

Messages

ToolNotes
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).
ofw_list_message_foldersList OFW folders with unread counts. Most reads use the cache; this is mainly for folder IDs and live unread counts.
ofw_list_messages(folderId?, since?, until?, q?, page?, size?, autoRefresh?)Cache-backed list. Supports folder ("inbox"/"sent"/"both"), date range, and substring search. Returns complete for the RESULT SET. An empty result from a non-fresh cache is refused (UNVERIFIED_EMPTY) — pass autoRefresh:true to sync and answer instead.
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.
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.
ofw_get_unread_sent(page?, size?, autoRefresh?)Sent messages your co-parent hasn't read yet (from cache). Reports scanned/total/complete; an empty sent cache that is not fresh is refused rather than reported as "nothing sent".
ofw_list_drafts(page?, size?, verify?, autoRefresh?)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 completecheck it before saying "you have N drafts". See Freshness.
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.
ofw_delete_draft(messageId)Delete a draft.
ofw_upload_attachment(path, shareClass?, label?, description?)Upload a local file to My Files; returns a fileId to pass into myFileIDs.
ofw_download_attachment(fileId, inline?, saveTo?, force?, extract?, maxChars?, parts?)Download an attachment. Inline delivery returns the first rung that works: image → ImageContent; .xlsx/.csv/.pdf/.docx/.pptx/text → extracted content under extracted (per-sheet CSV, per-page/slide text); anything else → raw bytes. Default writes to ~/Downloads/ofw-mcp/ (add extract:true for content too). Use parts:"1-2" / a sheet name and maxChars on large files.
ofw_check_freshness(folders?, messageIds?, allowMarkRead?)Cheap live check that the cache still matches OFW — one request for folder counts plus one per id, no bodies, no sync. Each id gets a live state (draft/sent/received/deleted/unknown) plus folder and sentAt. Probes ids cached as drafts, as sent, or as already-read inbox messages freely; anything else needs allowMarkRead:true (it would mark an inbox message read).
ofw_status(ids?, draftKeys?, includeDraftInventory?, allowMarkRead?)The status call. One live round trip. With no arguments: the full, server-verified draft inventory. With ids/draftKeys: each one's live lifecycle state. Top-level complete is true only when every part was verified live.

Calendar

ToolNotes
ofw_list_events(startDate, endDate, detailed?)Dates as YYYY-MM-DD
ofw_create_event(title, startDate, endDate, ...)startDate/endDate as ISO datetime
ofw_update_event(eventId, ...)Partial update — only pass fields to change
ofw_delete_event(eventId)Permanent delete

Expenses

ToolNotes
ofw_get_expense_totalsSummary of owed/paid totals
ofw_list_expenses(start?, max?)Paginated; default max 20
ofw_create_expense(amount, description)Log a new expense

Journal

ToolNotes
ofw_list_journal_entries(start?, max?)1-based offset; default max 10
ofw_create_journal_entry(title, body)Create a new entry

Freshness, completeness, and lifecycle

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:

QuestionSignal
How old is this data?freshnessstaleness (fresh/unverified/stale), asOf, ageSeconds, a quotable warning
Is this the WHOLE answer?complete on ofw_list_messages / ofw_list_drafts / ofw_get_unread_sent / ofw_status
Is this entity still what I think it is?state from ofw_status / ofw_check_freshness

Rules:

  • Verification is cheaper than recollection. Use it. Any status summary about drafts costs exactly one ofw_status() call. There is no situation in which recalling an earlier tool result is the better option.
  • Never state current state from memory. A draft you saved earlier in the session is not evidence it still exists unsent now — the user may have sent, edited or deleted it in the web app since. This has gone wrong twice: drafts described as "still sitting unsent" that had already been sent.
  • existsOnServer does not mean "still a draft". A draft that was SENT still exists on the server. Only state distinguishes them.
  • Check complete before quoting a count. complete: false means the result set is a slice, or unverified, or both — completeNote says which. "You have 3 drafts" requires complete: true.
  • serverConfirmed: false means "remembered, not known." Call ofw_status / ofw_check_freshness first, or say plainly that you are reporting cached state and give its age.
  • A refusal is a good outcome. result: "UNVERIFIED_EMPTY" means the tool declined to report an absence it could not verify. Do the remedy — never re-report it as "nothing found". A wrong "no, that was never sent" is far costlier here than one extra call.
  • state: "unknown" is not "fine". It means the question was not answered.
  • OFW does not bump a draft's timestamp when it is edited in the web app, which is why freshness is compared by content revision. "Nothing changed" and "we didn't look" are otherwise indistinguishable.
  • A missing folder count in ofw_sync_messages output means that folder was not checked — it is never "no changes". Check notRefreshed.

Draft identity (draftKey)

Editing a draft mints a new OFW id every timeofw_save_draft replaces by create-then-delete, so one message can burn through ten ids in a session. Track the draftKey it returns, not the id:

  • ofw_status(draftKeys: ["dk_…"]) resolves the key to the chain's current id and state.
  • The key keeps resolving after the draft is sent: state: "sent" with sentMessageId and sentAt.
  • draftKey: null on a draft means it was authored outside this tool; it is adopted into a chain the first time you save over it.

Workflows

Check inbox:

  1. ofw_list_message_folders → find inbox folder ID
  2. ofw_list_messages(folderId) → list messages
  3. ofw_get_message(messageId) → read a specific message

Send a message:

  1. ofw_get_profile → get co-parent's user ID
  2. ofw_send_message(subject, body, [coParentId])

Reply to a message (with thread history):

  1. ofw_get_message(messageId) → read the message to reply to
  2. ofw_send_message(subject, body, [coParentId], replyToId: messageId) — original message is included in the thread

Draft before sending (sensitive messages):

  1. ofw_save_draft(subject, body) → review with user; note the returned draftKey and revision
  2. ofw_send_message(draftId, recipientIds, expectedRevision) after approval — sends the server's copy of the draft (no body re-supply), refuses if it changed since review, and deletes the draft only after the send is confirmed

Check what's coming up:

  • ofw_get_notifications for a quick summary
  • ofw_list_events(today, +30days) for calendar detail

Caution

  • Always confirm before sending messages or deleting anything — OFW is a legal co-parenting record.
  • ofw_get_notifications updates last-seen status — avoid calling silently in the background.
  • ofw_get_message marks messages read — warn the user if they want to keep something unread.
  • Do not narrate cached state as present fact. Before saying what "is" true on OFW right now, call ofw_status — one live round trip that answers drafts, ids and draft keys at once. Never assemble a status summary from earlier tool results in the conversation; re-read.

常见问题

消息读取是实时的还是缓存的?
消息和草稿走本地缓存。每次返回都带新鲜度字段(staleness、asOf、ageSeconds)和 serverConfirmed 标记;当结果无法在线核实时,工具会以 UNVERIFIED_EMPTY 拒绝报告,而不是返回空结果。
读取或发送会产生哪些副作用?
ofw_get_message 会把收件箱消息标记为已读,并写入对方可见的 First Viewed 时间戳,可用 allowMarkRead:false 拒绝该读取。ofw_send_message 与 ofw_delete_event 不可逆,调用前需要用户明确确认。
如何安全地发送草稿?
先用 ofw_save_draft 保存草稿,记录返回的 draftKey 和 revision;审核后再调用 ofw_send_message(draftId, recipientIds, expectedRevision),工具会重新从 OFW 读取草稿,若与审核时不一致则拒绝发送,并在发送确认后才删除草稿。

相关技能

This skill should be used when the user asks about OurFamilyWizard (OFW) co-parenting data. Triggers on phrases like "check OFW", "OurFamilyWizard inbox", "OFW messages", "OFW calendar", "OFW expenses", "what did my co-parent say", "log an expense in OFW", "OFW journal", or any request involving co-parenting messages, calendar events, shared expenses, or journal entries.

Access OurFamilyWizard (OFW) — messages, calendar, expenses, journal — from a shell with the fpx CLI (@fetchproxy/cli) instead of running the ofw-mcp server: capture the signed-in web app's Bearer token once via the browser bridge, then curl the REST API directly. Use when you want OFW data without the MCP, in a script, or on a machine where the MCP isn't installed.

让 OpenClaw 代理通过 Microsoft Graph API 接入个人微软账户,读写 Outlook 邮件、日历事件和 To Do 任务。

74 次安装2 星标

Let your AI assistant manage your Outlook calendar for you. Just say what you need — add, change, or delete events, set up repeating meetings, or ask when you're free — and it happens on your own calendar.

Read and manage your Skylight Calendar family hub — calendar events, chores and reward stars, shared lists (grocery/to-do), and meal plans. Triggers on phrases like "check Skylight", "what's on the family calendar", "add an event to Skylight", "what chores does [kid] have", "mark [chore] done", "add milk to the grocery list", "what's on our shopping list", "what's for dinner", "what's on the meal plan", "who's on the Skylight frame", or any request involving the Skylight frame, family calendar, chores, rewards, shared lists, or meals. Works against your own signed-in Skylight account via email + password.

15 次安装

Manage daily bills, expenses, and recurring payments with tracking, reminders, and analysis. Use when the user asks about bill management, expense tracking,...

16 次安装