Skip to main content
Glama
OurFamilyWizard MCP

OurFamilyWizard MCP

by chrischall

ofw_save_draft

Destructive

Save a message as an OurFamilyWizard draft with held attachments and recipients; replace an existing draft safely by detecting changes before writing.

Instructions

Save a message as a draft in OurFamilyWizard. RECIPIENTS: OurFamilyWizard has not reliably kept recipients on drafts (when the saved draft comes back with none it is noted once, not warned about) — supply recipientIds at send time as well. ATTACHMENTS: OurFamilyWizard does not store files on drafts, so myFileIDs / inlineAttachments / blobKeys are HELD with the draft by this server (carried across edits, de-duplicated; removeFileIDs drops one), shown under attachments.held, folded into revision, and attached when the draft is sent with ofw_send_message(draftId). They are not visible on the draft in the OurFamilyWizard web app. IDENTITY: the response leads with draftKey, the stable identity that survives editing — key off it, because the id changes on EVERY edit (replacing a draft creates a NEW draft and deletes the old one; OFW's update-in-place endpoint silently no-ops, so we never use it). Pass messageId to replace an existing draft; the response.id will be the NEW id, and a transparency NOTE documents the swap and which fields were carried over. THREADING: if replyToId is provided, the cache may rewrite it to the latest reply in the thread (note included). The threading verdict is read from OFW's full echo (replyToId/inReplyTo/showContext) — a warning appears ONLY when the reply linkage was genuinely dropped or re-targeted, and the response's top-level replyToId/inReplyTo always agree with its listData. After saving, the tool re-fetches the draft from OFW, and the returned revision reflects that authoritative state (so it will match on your next edit). SAFETY: because replacing DESTROYS the old draft rather than merging, passing messageId first re-reads that draft from OFW and REFUSES the write if its subject/body/recipients changed since you read it (drafts edited in the OFW web app do not bump any timestamp, so the local cache can be silently behind). A pure replyToId normalization by OFW is NOT treated as a conflict. The refusal returns the current server body under serverBody — merge your edit into it and retry with expectedRevision.

Input Schema

NameRequiredDescriptionDefault
bodyYesMessage body text
forceNoDefault false. Overwrite even when the draft changed on OurFamilyWizard since you read it. The discarded server version is echoed back in the response. Only use after showing the user the conflict.
subjectYesMessage subject
blobKeysNoHosted deployments: blobKeys from ofw_upload_attachment uploadSlots whose files you have already PUT. Each is uploaded to My Files as PRIVATE, attached alongside any myFileIDs, and deleted from the upload store.
messageIdNoID of an existing draft to replace (the new draft will have a new id; the old is deleted)
myFileIDsNoAttachment file ids (from ofw_upload_attachment) to attach. OurFamilyWizard does not store attachments on drafts, so they are HELD with this draft by this server and attached when you send it with ofw_send_message(draftId). When replacing a draft (messageId), the files already held are kept and these are added (de-duplicated); use removeFileIDs to drop one.
replyToIdNoID of the message this draft replies to
recipientIdsNoArray of recipient user IDs (optional for drafts)
removeFileIDsNoWhen replacing a draft: held attachment file ids to drop.
expectedRevisionNoWith messageId: the `revision` you got from ofw_list_drafts/ofw_get_message for that draft. Asserts you are replacing THAT version. If the draft changed on OFW since, the write is refused and the current server body is returned. Omit and the tool compares the server against the local cache instead — omitting never means "overwrite anyway".
inlineAttachmentsNoFiles to attach, supplied as base64 BYTES ({filename, contentBase64, mimeType?}). Each is uploaded to My Files as PRIVATE and attached alongside any myFileIDs (a send attaches PRIVATE files as they are). Use for small files; on a hosted deployment, larger files (phone photos) go faster through ofw_upload_attachment uploadSlots + blobKeys here. Every entry is validated before anything is uploaded.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv2.27.2
    • addedInput schema / properties / blobKeys
      Added value: +{
      +  "description": "Hosted deployments: blobKeys from ofw_upload_attachment uploadSlots whose files you have already PUT. Each is uploaded to My Files as PRIVATE, attached alongside any myFileIDs, and deleted from the upload store.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • addedInput schema / properties / inlineAttachments
      Added value: +{
      +  "description": "Files to attach, supplied as base64 BYTES ({filename, contentBase64, mimeType?}). Each is uploaded to My Files as PRIVATE and attached alongside any myFileIDs (a send attaches PRIVATE files as they are). Use for small files; on a hosted deployment, larger files (phone photos) go faster through ofw_upload_attachment uploadSlots + blobKeys here. Every entry is validated before anything is uploaded.",
      +  "items": {
      +    "properties": {
      +      "contentBase64": {
      +        "description": "The file's bytes, standard base64 (line breaks and a \"data:<type>;base64,\" prefix are tolerated).",
      +        "type": "string"
      +      },
      +      "filename": {
      +        "description": "Filename the upstream will show — a bare name, no path, not starting with a dot. Its extension sets the MIME type when mimeType is omitted.",
      +        "type": "string"
      +      },
      +      "mimeType": {
      +        "description": "MIME type, e.g. \"image/jpeg\". Default: inferred from the filename extension.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "filename",
      +      "contentBase64"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • changedInput schema / properties / myFileIDs / description
      Previous value: -"Attachment file ids (from ofw_upload_attachment)"New value: +"Attachment file ids (from ofw_upload_attachment) to attach. OurFamilyWizard does not store attachments on drafts, so they are HELD with this draft by this server and attached when you send it with ofw_send_message(draftId). When replacing a draft (messageId), the files already held are kept and these are added (de-duplicated); use removeFileIDs to drop one."
    • addedInput schema / properties / removeFileIDs
      Added value: +{
      +  "description": "When replacing a draft: held attachment file ids to drop.",
      +  "items": {
      +    "type": "number"
      +  },
      +  "type": "array"
      +}
  2. Changed1 schema field changedv2.17.0
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  3. First observedv2.8.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark this as destructive, and the description explains exactly why: replacing a draft creates a new draft and deletes the old one, while OFW's update-in-place endpoint is a no-op. It further discloses that OFW does not store draft attachments, that this server holds them and folds them into revision, that draft ids change on every edit while draftKey is stable, and that conflicting edits can cause a refusal with serverBody returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loads the core action and then organizes caveats under clear labels like RECIPIENTS, ATTACHMENTS, IDENTITY, THREADING, and SAFETY. The density is justified for an 11-parameter destructive tool, though some sentences could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description explains the important return signals: draftKey as stable identity, revision as authoritative state after re-fetch, attachments.held, serverBody on conflict, and notes about carried-over fields and thread normalization. For a complex destructive save/replace operation, an agent has enough information to invoke it correctly and recover from conflicts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is already 100%, the description adds crucial meaning beyond the schema: messageId replacement changes the id, expectedRevision asserts a specific version and is not an overwrite flag, force should be used only after showing the conflict, removeFileIDs drops held attachments, and inlineAttachments/blobKeys are validated and uploaded as private files. These interactions are not apparent from the parameter descriptions alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: "Save a message as a draft in OurFamilyWizard." It also distinguishes this from sending by explaining that held attachments are later attached with ofw_send_message(draftId), and it clarifies that passing messageId replaces an existing draft rather than creating an unrelated one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage paths: omit messageId to save a new draft, pass messageId to replace one, use expectedRevision from ofw_list_drafts/ofw_get_message, and use ofw_upload_attachment uploadSlots plus blobKeys for larger hosted-deployment files. It also warns to supply recipientIds at send time because recipients are not reliably kept on drafts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.