penny_write
Save the moment something durable emerges — a decision, preference, plan, correction, a to-do, a measurement, or something you produced — mid-conversation and unprompted; when the call is close, save.
Write something new to the user's memory. Choosing entityType — walk this ladder top to bottom, first match wins:
Durable fact about the user or their people (names, preferences, relationships) → update the profile: use
entityType: "profile"(orpenny_edit— profile blocks are upserts), NOT a note. Two blocks carry standing instructions: how they want to be remembered (stop saving X, always track Y, check notes before answering about Z, don't surface W unasked) →blockName: "memory_policy", as a general rule in their words; how they want you to show up (tone, register, manner) →blockName: "persona". When the user tells you what to save, skip, check, or surface, update their memory_policy block in the same turn as a general rule in their words.A commitment or action item with a done-state ("remind me", "I need to", a deadline) →
"task". Areas/projects/headings that organize tasks →"area"/"project"/"heading". A to-do the user mentions, even in passing, is a task: offer to capture it, then write it."project"also opens or revises a Penny Project: create withpatch.name(andpatch.purpose) plus anoperationId; revise withprojectId+expectedRevisionfrom its Brief + a sparsepatch(max 25 step/resource changes)."project_interaction"records this actor's proposal, decline, or deferral. Apending_share_approvalresult is a proposal, not a save. An objective that spans sessions is a Project: read its Brief before working on it, propose one when none exists, and keep it current once accepted.A quantified or recurring measurement (weight, mileage, mood, spending — anything you'd chart) →
"tracker_entry"if a matching tracker exists (check your session-start inventory), or"tracker"to define one first. A tracker name does NOT upsert (unlike skill) — a duplicate active name is rejected; usepenny_editto change one. A measurement the user would log more than once is a tracker entry; if no tracker fits, propose one before logging.Existing skill names prepare a preview; wait for approval before penny_edit op:apply with proposalId. Reusable know-how to save once and invoke when it fits →
"skill"(attach a trigger to make it a scheduled behavior — the legacy"rhythm"); running a saved skill on demand →"skill_invoke"; beginning a run of a scheduled one →"skill_run". Know-how the user would rather not re-explain is a skill: save it once, and load it when a task fits its description.Everything else — context, events, ideas, things learned →
"note". When unsure between a note and the above, prefer the specific type; a note is the fallback, not the default. Tag relations ("tag_relation") and attaching notes to tracker entries ("tracker_note_link") round out the menu. Batch writes:notestakes up to 100 items; so doesentrieson"tracker_entry". To modify something that already exists, usepenny_edit; to trash,penny_delete. Reuse an existing tag before minting a new one. Tagging and linking conventions live in the MyPenny skill.
When saving notes (entityType:"note"), calibrate each note's confidence honestly to the SIGNAL, not the pipeline: 0.95 = explicit user statement; 0.80 = confirmed decision; 0.60 = reasonable inference; 0.40 = hedged or sleeptime-derived; 0.20 = weak signal. Every note must include sampleQuestions: exactly three short, natural-language questions for which that note would be a useful retrieval result. Derive them FROM the content you're about to write — three different ways the user might ask, in conversation, something this memory should answer. Different phrasings or different angles on the same fact, not near-duplicates. Write them in the user's voice (how they'd actually ask in chat), not as retrieval queries. Example: for the memory "user prefers APA citation style for academic writing", good sampleQuestions are ["What citation style should I use for the paper?", "How should I format references in my thesis?", "What's my usual academic style?"].
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | entityType:"rhythm" (required) — natural-language instruction: what the run should do. On entityType:"skill" this is `instructions`. | |
| kind | No | entityType:"tracker" (required) — habit | metric | goal | log | status | custom. | |
| name | No | Required for tracker/area/project and entityType:"skill" (also rhythm); for skill_invoke/skill_run, an alternative to skillId. Existing skill names prepare a change preview; new names create. Active tracker duplicates are rejected; archived names reactivate. | |
| tags | No | entityType:"task" — tags to attach. | |
| unit | No | entityType:"tracker" — unit of measure. | |
| actor | No | entityType:"task"/"area"/"project"/"heading" — who took the action (me|agent), written to the activity ledger. | |
| child | No | entityType:"tag_relation" (required) — the child tag. | |
| notes | No | note: array (max 100), each requires content and confidence (0–1), plus tags and exactly 3 sampleQuestions in the user’s voice; optional source/memoryType (episodic|semantic|procedural)/validFrom. task/area/project: markdown string. | |
| order | No | entityType:"task"/"area"/"project"/"heading" — sort order. | |
| owner | No | entityType:"task" — assignee. | |
| patch | No | Project sparse changes; omitted fields stay. Max 25 step/resource changes. | |
| scope | No | Profile: global|workspace. Projects: private; workspace requires workspaceId. | |
| title | No | entityType:"task" (required) or "heading" (required) — the title/label. | |
| areaId | No | entityType:"project" (required) — the area the project belongs to. | |
| parent | No | entityType:"tag_relation" (required) — the parent tag in the child_of edge. | |
| source | No | entityType:"note"/"tracker_entry" — provenance label (defaults 'conversation' / 'agent-mcp'). | |
| status | No | entityType:"task" — initial status. | |
| whenAt | No | entityType:"task"/"project" — schedule date (ms epoch). | |
| content | No | entityType:"profile" (required) — the block content. | |
| deliver | No | entityType:"skill" — REQUIRED once `trigger` is set (and on the legacy entityType:"rhythm"); omit on an on-demand skill. Where a scheduled run's output lands: { kind:'note', tags?:string[] } | { kind:'profile_block', blockName:string } | { kind:'notify' }. | |
| entries | No | tracker_entry: batch up to 100 entries for one trackerId; each {payload,loggedAt?,agentNote?,noteIds?,source?,metadata?}. Mutually exclusive with top-level payload. Receipts report each saved/failed item; do not claim all saved from a partial result. | |
| noteIds | No | entityType:"tracker_entry" — archival note ids to attach; or "tracker_note_link" (required) — the notes to link. | |
| payload | No | entityType:"tracker_entry" (required unless `entries` is used) — the structured data point; shape is tracker-defined. | |
| posture | No | entityType:"skill" with a `trigger` set (or legacy "rhythm") — read | propose | act (defaults 'read'). | |
| skillId | No | entityType:"skill_invoke" (required, or pass `name`) — the skill to run now. entityType:"skill_run" — the skill to begin a run of (or pass `name`). | |
| trigger | No | entityType:"skill": optional schedule (required for rhythm), requires deliver. MyPenny does not run it: due signals reach the connected agent. Schedule: {kind:"schedule",cadence:"daily"|"weekly"|"monthly",at?:"Fri 16:00",timezone?:"America/Denver"}. ALWAYS set timezone (IANA); default UTC shifts local times. Event: {kind:"event",on:"note.created",where?:{tags?:string[]}}. | |
| deadline | No | entityType:"task"/"project" — hard due date (ms epoch). | |
| rhythmId | No | entityType:"rhythm_run" — the rhythm to begin a run of (or pass `name`). | |
| agentNote | No | entityType:"tracker_entry" (single-entry form only) — short caption on this one data point (not searchable). | |
| blockName | No | entityType:"profile" (required) — the profile block name to upsert. | |
| dependsOn | No | entityType:"task" — full replacement set of taskIds that must complete first. | |
| headingId | No | entityType:"task" — heading to file the task under. | |
| linkNotes | No | entityType:"task" — note ids to link to this task. | |
| projectId | No | entityType:"task" — parent project; or "heading" — the project it belongs to (required). | |
| reasoning | No | entityType:"tag_relation" — short justification (typically a user quote) for the edge. | |
| trackerId | No | entityType:"tracker_entry" (required) — the tracker to log against. | |
| entityType | Yes | What to create. Walk the ladder in the tool description; first match wins. | |
| recordedAt | No | entityType:"tracker_entry" (single-entry form only) — observation time (ms epoch; defaults to now). | |
| recurrence | No | entityType:"task" — makes the task repeat. The returned `taskId` is this task's first occurrence; completing it later returns `nextTaskId` for the next one (see penny_edit's `status` field) — don't cache this id past its first completion. | |
| targetSpec | No | entityType:"tracker" — JSON target spec, interpreted at retrieval (e.g. { kind: 'daily_minimum', value: 10000 }). | |
| whenBucket | No | entityType:"task"/"project" — undated bucket; mutually exclusive with whenAt. | |
| description | No | entityType:"tracker" (required) — natural-language meaning. entityType:"skill" (required — every skill, on-demand or scheduled) or legacy "rhythm" — one-line description of what it is for. | |
| interaction | No | project_interaction: actor decision; read first, update with expectedUpdatedAt. | |
| operationId | No | Project receipt key; identical retries only. | |
| instructions | No | entityType:"skill" (required) — the saved know-how: what to do when the skill is invoked, or when a connected agent picks it up after it comes due. Generalizes the rhythm "goal". | |
| retrievalPlan | No | entityType:"skill" (or legacy "rhythm") — OPTIONAL deterministic steps [{ tool, args }] for a bounded tier. | |
| trackerEntryId | No | entityType:"tracker_note_link" (required) — the logged tracker entry to attach notes to. | |
| expectedRevision | No | Project edit revision from Brief; reconcile conflicts. | |
| expectedUpdatedAt | No | Source version from the read. |