Penny
Server Details
Portable AI memory you own. Keep memories and notes across Claude, ChatGPT, and other AI tools.
- Status
- Healthy
- Uptime
- 100.0% over 41 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 7 tools
The write/edit pair overlaps materially: penny_write's ladder includes profile upserts, project creation, and skill previews that penny_edit also handles, and penny_get_skill is a narrower re-entry into penny_read's `target:skills` path. The long routing ladders ("first match wins", "modify with penny_edit") do most of the disambiguation work, but that work is pushed into prose rather than clean tool boundaries, and penny_delete is really "trash+restore" while restore actually lives in penny_edit.
A uniform `penny_` prefix with snake_case is used throughout, and most names are verb-first (delete, edit, read, write, get_skill). Two deviate into noun-first/compound forms (penny_session_start, penny_start_setup), which sit awkwardly next to the verb-first majority.
Seven tools is a sensible, deliberately consolidated surface for a broad personal-memory domain covering notes, tasks, trackers, projects, skills, and setup. The trade-off is that two tools (penny_read, penny_write) carry enormous polymorphic responsibility, which compresses count at the cost of clarity.
Full lifecycle coverage exists for the core entities — create/edit/trash/restore, revision history, run recording, and onboarding — with intentional variants (tasks cancel rather than delete, trackers archive). Gaps are acknowledged rather than hidden: workspace trackers are unsupported and project reads are limited to a bounded private directory.
Available Tools
7 toolspenny_deleteADestructiveIdempotentInspect
Move to Trash. Project: projectId + expectedRevision + operationId; penny_edit op:restore recovers. Repeat in_progress with the same operationId; report partial_recovery conflicts. Note/tracker_entry: ids (max100); skill/rhythm: one id; profile_block: ids are block names. Tag/link removal uses the identifiers below. Tasks are canceled via penny_edit; tracker definitions are archived, not deleted.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | note/tracker_entry: IDs to trash, max 100. rhythm/skill: exactly one ID. profile_block: block names to trash. | |
| tagA | No | tag_relation: required edge endpoint to remove. | |
| tagB | No | tag_relation: required other endpoint. | |
| scope | No | Profile block scope; Project private overrides defaults, workspace requires workspaceId. | |
| noteIds | No | tracker_note_link: required note IDs to unlink. | |
| projectId | No | ||
| entityType | Yes | What to trash. | |
| operationId | No | ||
| trackerEntryId | No | tracker_note_link: required entry to detach notes from. | |
| expectedRevision | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds real value beyond them: the operationId retry rule ('repeat in_progress with the same operationId'), partial_recovery conflict reporting, and the recovery path via penny_edit op:restore. It does not state permission/auth requirements or the shape of a partial_recovery response, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and every fragment carries information, but the telegraphic, semicolon-chained style ('Project: projectId + expectedRevision + operationId') strains readability. No sentence is filler, yet a little more structure would aid parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter, no-output-schema, destructive multi-entity tool, the description covers recovery, idempotent retry, conflict handling, and per-entity applicability. It leaves gaps on return values and on which entity types accept which of the remaining parameters, but overall it is enough to call the tool safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 70% schema coverage the schema carries much of the load, yet the description adds conditional requirements the schema does not encode (projectId + expectedRevision + operationId for projects; 'one id' for skill/rhythm; block names for profile_block; tag/link identifiers). Some content, such as max 100 and 'exactly one ID', duplicates the ids schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening 'Move to Trash' states a specific action (soft delete, not hard delete) on memory entities, and the description goes on to distinguish per-entity behavior. It explicitly contrasts itself with penny_edit for tasks and tracker definitions, so an agent can separate this from siblings like penny_edit and penny_write without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives positive conditions (Project needs projectId + expectedRevision + operationId; tag/link removal uses the identifiers below) and explicit exclusions (tasks are canceled via penny_edit; tracker definitions are archived, not deleted). Alternatives are named rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_editADestructiveIdempotentInspect
When the user corrects something on file, or a task, tracker, skill, or block needs to change, edit the existing item rather than writing a duplicate. Modify what already exists; entityType uses the same taxonomy as penny_write (see ladder). Notes: updates[] patch/replace, max100. Tasks: taskId; cancel via status:canceled, never Trash. Profile: blockName + content upsert; memory_policy and persona hold standing instructions. 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. Skill redefinition prepares a preview, not a save; wait for user approval before op:apply with proposalId. cancel discards; undo recovers the prior version if no later edit exists. skills/history supplies historyId; restore_revision with skillId/historyId/expectedUpdatedAt previews recovery. restore with skillId recovers deleted skills disabled. No invocation waiting period. Trackers: trackerId + sparse name/description/unit/kind/targetSpec/archived; retire by archiving, no delete. Private trackers only; workspace trackers unsupported. Rhythms: full manifest. skill_run/rhythm_run: complete runId + status. Projects: projectId + expectedRevision + operationId + sparse patch; reread and reconcile on conflict. restore_revision restores fields/resourceIds from historyId as a new revision. Tracker entries: trackerId + entryId + expectedUpdatedAt + full payload. restore un-trashes note/tracker_entry ids or Project projectId. When the user asks to go off the record, entityType: "session" + record: "off" + the sessionId from <mypenny-session> stops this session's transcript reaching Penny and drops what wasn't processed yet; it can't be undone for the session.
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | restore: un-trash notes/tracker entries by ids. | |
| ids | No | restore: IDs to un-trash; max 100. | |
| goal | No | rhythm: required run instructions; skill uses instructions instead. | |
| kind | No | tracker: habit|metric|goal|log|status|custom. | |
| name | No | area/project/tracker: name. entityType:"skill": previews replacement; rhythm: upserts. | |
| unit | No | tracker: unit of measure. | |
| actor | No | task/area/project/heading: actor (me|agent) recorded in activity ledger. | |
| notes | No | task/area/project: markdown body. | |
| order | No | task/area/project/heading: sort order. | |
| orgId | No | area/project/heading: required container ID to update. | |
| owner | No | task: assignee. | |
| patch | No | Project patch: full schema on penny_write. | |
| runId | No | skill_run/rhythm_run: required run ID to complete. | |
| scope | No | Profile: global|workspace. Projects: private; workspace requires workspaceId. | |
| title | No | task/heading: title/label. | |
| areaId | No | project: parent area. | |
| fields | No | Restore selection: field names or step:<stepId>; fields/resourceIds required. | |
| record | No | entityType:"session" (required) — "off". One-way: there is no way back on for the session. | |
| status | No | task: open|in_progress|done|canceled. Repeating completion returns nextTaskId: act on that new occurrence; the completed ID rejects further status writes. skill_run/rhythm_run: done|error|skipped. | |
| taskId | No | task: ID to update. | |
| whenAt | No | task/project: schedule date (ms epoch). | |
| content | No | profile: required new block content. | |
| deliver | No | entityType:"skill": required with trigger; rhythm: required. Omit for on-demand. Shape: penny_write. | |
| enabled | No | skill: false pauses due signals, true resumes; requires skillId. Penny does not run skills. | |
| entryId | No | ||
| payload | No | ||
| posture | No | entityType:"skill" with trigger, or rhythm: read|propose|act. | |
| skillId | No | skill: ID required with enabled to pause/resume. | |
| trigger | No | entityType:"skill": optional; rhythm: required. Omit to return to on-demand. Penny does not run it; connected agents receive due signals. Shape: penny_write. ALWAYS set IANA timezone; default UTC. | |
| updates | No | note: patch or supersede up to 100 existing notes. | |
| archived | No | Area/project/tracker: archive; false reactivates. Tracker definitions retire only this way. | |
| deadline | No | task/project: hard due date (ms epoch). | |
| snapshot | No | skill restore_revision: history side; default before. after recovers an undone change. | |
| agentNote | No | ||
| blockName | No | profile: required block to upsert. | |
| dependsOn | No | task: full prerequisite taskId set; replaces all. | |
| historyId | No | restore_revision: Project/skill history ID. Skill restore previews; requires skillId and expectedUpdatedAt. | |
| linkNotes | No | task: note IDs to link. | |
| projectId | No | heading: required parent Project. | |
| sessionId | No | entityType:"session" — the transcript session to take off the record, from <mypenny-session>; omit when the host gives none. | |
| trackerId | No | tracker: required ID to update; only supplied fields change. | |
| entityType | Yes | Item type. | |
| proposalId | No | Returned skill proposal. apply commits after user review; cancel discards; undo restores the previous version only if no later edit exists. | |
| provenance | No | rhythm_run: accountability summary (IDs/labels, never full content). | |
| recordedAt | No | ||
| recurrence | No | task: set/change recurrence. clearFields:["recurrence"] ends the series, making the task one-off and preserving completed history. Target currentOccurrenceId, not a stale/completed ID. | |
| targetSpec | No | tracker: replaces the whole target spec; shape as penny_write. | |
| whenBucket | No | task/project: undated bucket; mutually exclusive with whenAt. | |
| clearFields | No | task: optional fields to unset. | |
| description | No | entityType:"skill"/rhythm: required use-when description. tracker: meaning; log trackers must document payload shape. | |
| operationId | No | Project receipt key; identical retries only. | |
| resourceIds | No | Restore selected links. | |
| taskUpdates | No | task: edits, each {taskId, ...task fields} except card. All are checked first; one bad item saves none. | |
| instructions | No | skill: required saved know-how; replaces rhythm goal. | |
| retrievalPlan | No | entityType:"skill"/rhythm: optional deterministic steps for a bounded tier. | |
| expectedRevision | No | Project revision from Brief; reconcile conflicts. | |
| expectedUpdatedAt | No | Source version from read. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool destructive and idempotent, and the description adds substantial context beyond them: skill redefinition previews require approval, cancel discards, undo only works if no later edit exists, project conflicts require rereading, private trackers only, and going off-record cannot be undone. These details materially improve safe invocation and do not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and the information density is high, which suits a 57-parameter tool. However, the body is a dense semicolon-separated run-on with cryptic fragments like 'Rhythms: full manifest' and 'No invocation waiting period', making it harder to scan than it needs to be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a highly complex destructive tool with no output schema, it covers the major entity types, operation modes, approval and undo behavior, conflict reconciliation, and session privacy semantics. It is strong overall, though some entity types such as areas and headings are left mostly to the schema, and return/error expectations are not described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 93%, so the baseline is 3, but the description adds useful entity-specific recipes such as updates[] patch/replace max 100, profile blockName + content upsert, skill preview via proposalId, and tracker entries requiring trackerId + entryId + expectedUpdatedAt + full payload. Some params remain vague or externally referenced, such as 'see ladder', and a few fields like agentNote and recordedAt are not clarified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: edit an existing item rather than writing a duplicate. It distinguishes itself from penny_write by naming the shared taxonomy, so an agent can tell this is the mutation/update path rather than creation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to edit instead of duplicating, then gives entity-specific triggers for tasks, trackers, skills, profiles, projects, rhythms, and sessions. It also names operation alternatives such as cancel, apply, undo, and restore_revision, so the agent has clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_get_skillARead-onlyIdempotentInspect
Read the Penny operating skill (the SKILL.md penny_read target:skills name:Penny returns) or its reference files, including after a catalog refresh. Reuse files already read this conversation. Default SKILL.md; fetch manifest references when their cues apply. Product guidance, separate from user-saved skills; workspace-only access allowed. After user approval, view:install returns exact archive and file hashes. Retain results before bounded display; never transcribe installation bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Exact manifest path; default SKILL.md; read view only. | |
| view | No | Default read. install returns an archive, not guidance. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and closed-world, so the safety profile is covered. The description adds genuinely useful behavior: results should be cached rather than re-read, install returns an archive with exact hashes, and installation bytes must not be transcribed. However, cryptic constraints like 'bounded display' are unexplained, and leftover phrasing ('never transcribe installation bytes') lacks context an agent can act on.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Efficient in length but densely packed with nested clauses and jargon; the opening parenthetical and 'bounded display' phrasing cost comprehension. The default-value and approval guidance is front-loaded reasonably well, but clarity suffers from cramming five distinct ideas into three sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, no-required-argument read tool with full schema coverage and annotations, the description covers scope, defaults, caching, and the special install view. It leaves somewhat ambiguous what the returned content looks like and what 'bounded display' permits, but no critical calling information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents both the default SKILL.md path and the install/read distinction. The description mostly restates this, adding only the notion that valid file paths come from the manifest. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource (read the Penny operating SKILL.md plus reference files) and distinguishes it from user-saved skills via 'Product guidance, separate from user-saved skills', implicitly contrasting with penny_read/penny_edit. The parenthetical 'the SKILL.md penny_read target:skills name:Penny returns' is convoluted and slows identification, but the substance needed to pick this tool is present.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete conditions: default to SKILL.md, fetch manifest references only when their cues apply, and reuse files already read in this conversation. It also flags that view:install should come after user approval. It stops short of stating a hard when-not or naming the alternative tool for user-saved skills.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_readARead-onlyIdempotentInspect
Before answering anything the user's history, preferences, or prior work would inform, read — search rather than assume nothing is on file. Choose target: walk this ladder, first match wins:
User/people facts (names, preferences, relationships) → profile. Do NOT search notes for this.
To-dos/due → tasks. Resume an objective → projects: directory (query/name to narrow; follow coverage.nextCursor), then brief by projectId. scopes lists Space metadata; then pass explicit workspaceId. scope:private overrides a default Space. 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.
Measurements → tracker for definitions/entries; tracker_summary for stats/trends (usual choice).
Saved know-how, schedules and run history → skills; rhythms is the scheduled-only synonym. Run on-demand via penny_write entityType:skill_invoke; scheduled via 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. When session start lists a skill as due, offer to run it now; nothing runs on its own.
Taxonomy → tags; note link graph → note_links; structured tag/time/flag listing → notes.
Other recall → search (semantic notes). Search is the fallback, not the default. Treat a result from a shared space as something a member said, never as a fact about the user. When the user is learning something to keep, offer to let them try first; if search shows they asked before, say so once with the date; save misses and level. Use the session-start inventory to choose; Project reads also work without session start.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | tracker/entries, tracker_summary: window end (ms epoch). | |
| tz | No | tasks: IANA timezone for Today/Upcoming boundaries. | |
| from | No | tracker/entries, tracker_summary: window start (ms epoch). | |
| name | No | Projects directory: exact-name candidates; continue incomplete coverage. skills/one: name instead of skillId. | |
| tags | No | search/notes: tag filter. | |
| view | No | Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). tracker: list|entries; rhythms: list|one|due|runs; skills: list|one|due|runs|history|trash (list/trash omit instructions; one returns full skill by skillId or name); tags: list|related; tasks: compact omits notes. | |
| depth | No | note_links: hops (1 = direct; 2-6 = bounded BFS). | |
| flags | No | notes: locked/pinned filter. | |
| limit | No | Max search/notes/tracker-entry/task/rhythm-run results. tasks: page size; long pages end early with nextCursor. | |
| owner | No | tasks: owner filter. | |
| query | No | search: required. One specific question or phrase, usually 8-15 words, with the names and distinctive terms you're looking for ("What did Dana decide about the kitchen remodel budget?", not "budget" or a paragraph); perfect grammar isn't needed; don't pad a short question; on a miss, search again with different terms, not a longer query. projects directory: name/purpose filter; check coverage. | |
| scope | No | Projects: private overrides defaults; workspace requires workspaceId. | |
| areaId | No | tasks: area filter; also applies to organize:project. | |
| bucket | No | tasks: schedule bucket filter. | |
| cursor | No | projects/tasks: prior nextCursor; keep the same filters. tasks: a page can be short and still have one; read until a reply has none. | |
| status | No | tasks: status filter. | |
| target | Yes | What to read; first match in the tool description's ladder wins. | |
| taskId | No | tasks: full detail. A repeating task returns seriesId/currentOccurrenceId; act on the current occurrence, not a completed ID. | |
| blocked | No | tasks: only tasks with unmet dependsOn. | |
| section | No | projects/section: one Brief section. | |
| seedIds | No | note_links: required starting note IDs. | |
| skillId | No | skills: required for one unless name is given; optional run scope for runs. | |
| dateAxis | No | notes: timeRange axis; created = when written, valid = when the fact holds. | |
| dueRange | No | tasks: due-date window (ms epoch). | |
| eventKey | No | Projects interactions: actor event key; omit to page. | |
| maxDepth | No | tags/related: maximum traversal depth. | |
| maxNodes | No | note_links: node cap for depth > 1; default 50. | |
| organize | No | tasks: list containers instead of tasks. | |
| rhythmId | No | rhythms: required for one; optional run scope for runs. | |
| seriesId | No | tasks: complete recurring-series history, newest first, including completed occurrences. | |
| edgeTypes | No | note_links: only follow/return these relationship types. | |
| minWeight | No | tags/related: minimum edge weight (default 0.4). | |
| orgStatus | No | tasks organize:project: Project status filter. | |
| projectId | No | projects brief/section/resources/resource/history: required stable Project ID. tasks: Project filter or heading parent. | |
| timeRange | No | search/notes: time window (ms epoch). | |
| trackerId | No | Required for tracker/entries and tracker_summary. | |
| blockNames | No | profile: exact block names. | |
| confidence | No | notes: confidence range. | |
| ifRevision | No | profile: last-read revision; returns {unchanged:true} if unchanged. | |
| projectKey | No | profile: include subconscious:<projectKey>. | |
| resourceId | No | Projects resource: read the authorized current source. | |
| enabledOnly | No | rhythms/list: only enabled rhythms. | |
| resourceState | No | ||
| graphTraversal | No | search: opt into tag/link graph expansion (default false; measured recall loss). Use only for deliberate graph exploration. | |
| includeArchived | No | Include archived trackers, Projects, or task containers. | |
| includeCompleted | No | tasks: include done/canceled; default false. An explicit status wins. | |
| includeRelations | No | tags/list: include parents/children/synonyms. | |
| legacyProjectKey | No | profile: coding-plugin migration aid — the same repo's older key, served in place of subconscious:<projectKey> until that exists. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, and the description adds real behavioral context beyond them: shared-space results must be treated as a member's statement rather than a user fact, nothing runs on its own, Project reads work without session start, and on a search miss you should re-query with different terms rather than lengthen the query. It stops short of describing what a read actually returns (result shape, size), which matters given there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The numbered ladder is well front-loaded and scannable, but the text also carries agent policy that does not help select or invoke this tool ("offer to let them try first", "say so once with the date", "save misses and level"). For a single read entry point, roughly a third of the prose is behavioural coaching layered onto a 48-parameter router, which dilutes the selection signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 48-parameter multi-target router, the description is unusually complete on the routing axis: it covers every target in the enum, states the two cursor/pagination cases (coverage.nextCursor, nextCursor) and the private-vs-workspace scope rule. The gap is on the output side — with no output schema and eleven distinct result shapes, nothing tells the agent what each target returns, so the schema and description together still leave returns opaque.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 98%, so the baseline would be 3, but the description adds routing meaning the schema cannot: it explains which target a parameter belongs to conceptually ("note link graph → note_links", "structured tag/time/flag listing → notes") and clarifies precedence such as scope:private overriding a default Space. It also flags the usual default (tracker_summary for stats/trends), which is selection guidance rather than restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the verb (read/search) and then enumerates exactly what can be read via a six-step ladder mapped onto the `target` enum (profile, projects, tasks, tracker, skills, tags, note_links, notes, search). It distinguishes itself from siblings by naming penny_write, skill_run and penny_session_start as the write/run paths, so an agent can tell a read from a mutation without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit first-match-wins decision ladder plus hard exclusions ("Do NOT search notes for this", "Search is the fallback, not the default") and names the alternative for each branch (tracker_summary over tracker for stats, rhythms over skills for scheduled-only). It also states a prerequisite gate — read before answering anything the user's history would inform — which is exactly the when-to-use signal an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_session_startARead-onlyIdempotentInspect
Call ONCE at the start of every conversation, before the first substantive reply. If the host saves this result to a file because it is too large, read the whole file before you reply. Retain results in execution storage before bounded display; inspect one text OR structured payload. Follow next[] in order; it starts with reading the Penny skill. Reuse the complete, untruncated profile (persona/facts/preferences/custom blocks) and answer from it before searching notes. Follow self_improvement throughout the conversation. meta.onboarding present: offer penny_start_setup, resuming from its phase. meta.saveDrought true: follow drought repair. Inventories of trackers, rhythms, tasks and Projects are capped; meta.truncated.* means drill down with penny_read. skills.defined names every user-saved skill (read one with penny_read target:skills view:one before using it); it excludes the built-in Penny skill. features says which features are in use and when; consult it and the inventory before choosing entityType. tz is IANA (default UTC) for local Today/Overdue and dueNow. projects is a bounded PRIVATE directory with coverage and dated attention candidates, not a search of all Spaces; read relevant Briefs by projectId. Workspace-only connections cannot call this: use penny_read target:projects view:scopes, then explicit workspaceId. projectKey includes only the matching repository subconscious block, not a Penny Project.
| Name | Required | Description | Default |
|---|---|---|---|
| tz | No | IANA timezone for today/overdue boundaries (e.g. America/New_York); default UTC. | |
| projectKey | No | Include subconscious:<projectKey>; exclude all other subconscious blocks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses important behaviors: large results may be saved to a file, results should be retained in execution storage before bounded display, next[] must be followed in order, and the complete profile should be reused before searching notes. It also explains special metadata flags such as meta.onboarding, meta.saveDrought, and meta.truncated.*, along with workspace-only invocation limits. These are substantial behavioral details that annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The most important instruction, calling once at the start before replying, is front-loaded. However, the description is a dense single paragraph with many compact clauses and cryptic field references, making it harder to scan than necessary. It is information-rich but would benefit from clearer separation of invocation rules, output handling, and metadata semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and two optional parameters, the description covers the important context: what the session payload contains, how to handle large results, how next[] should be followed, how truncated inventories should be drilled into, and how special metadata flags should alter behavior. It also documents workspace restrictions and the distinction between projectKey and Penny Projects. That is complete enough for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both optional parameters. The description still adds useful meaning: tz controls local Today/Overdue and dueNow boundaries, and projectKey includes only the matching repository subconscious block while explicitly not representing a Penny Project. It also clarifies the workspace-only limitation around project-scoped access, which is more than the schema alone conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description makes clear that this is a session-start bootstrap that returns a reusable profile, inventories, next steps, and metadata, rather than a general read tool. It distinguishes itself from siblings by directing drill-downs to penny_read and onboarding to penny_start_setup. A direct one-line statement of the returned payload would make the purpose unmistakable, but the overall intent is easily inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to call this ONCE at the start of every conversation before the first substantive reply. It also names alternatives and exclusions: use penny_read for truncated inventories or skills, offer penny_start_setup when meta.onboarding is present, and use penny_read target:projects view:scopes for workspace-only connections. This leaves little ambiguity about when and when not to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_start_setupCIdempotentInspect
Setup in phases; omit phase to start, resume from meta.onboarding.phase. skipForGood opts out. Stage an encrypted import, show showUser, then save or discard as the user says. While an import is open, finish can't complete setup.
| Name | Required | Description | Default |
|---|---|---|---|
| stop | No | Tour stop, with phase tour. | |
| phase | No | Phase to run; omit to start. | |
| client | No | Actual host: claude-desktop, claude-web, claude-code, codex, chatgpt, gemini, perplexity, grok (web only), grok-bot or other; tailors paste guidance. | |
| counts | No | Cumulative answers/featuresCreated. Ledger imports ignore imported; only committed receipts count. | |
| draftId | No | Returned draft ID. | |
| dropItemIds | No | save: dropped ids (values of items). | |
| importDraft | No | Strict JSON {notes,profiles}; returned schema. 10 notes, 4 replacements, 64 KiB UTF-8. | |
| keepItemIds | No | save: left-out ids the user kept. | |
| skipForGood | No | User requested permanent setup opt-out. | |
| importAction | No | All but status need draftId and expectedRevision; stage also importDraft. status re-sends the list. | |
| prevAccepted | No | Did the user accept the previous tour stop's offer? | |
| expectedRevision | No | Returned revision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, idempotent, non-destructive, closed-world, so the description adds value via the sequencing constraint ("while an import is open, finish can't complete setup") and the encrypted-import staging flow, which are genuine behavioral facts. It still leaves unclear what persisting side effects phases like finish, gaps or skipForGood produce, and 'discard' silently dropping a staged import sits in mild tension with destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences with little filler and the invocation rule front-loaded, which is efficient. However the telegraphic style ("skipForGood opts out", "show showUser") packs jargon without explaining it, so brevity comes at the cost of parseability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, five-phase state machine with nested objects and no output schema, the description is thin: it does not explain what the gaps or tour phases do, what stop/prevAccepted drive, how counts/ledger imports behave, or what each phase returns. Given the completeness burden this complex a tool places on the description, material gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, including enums for phase and importAction and inline notes on expectedRevision and importDraft limits, which sets the baseline at 3. The description largely restates schema facts (omit phase to start, skipForGood opts out) and adds no new meaning for draftId, counts, stop, prevAccepted, or the keep/drop item ID pairs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description frames a phased onboarding state machine ("Setup in phases", "omit phase to start, resume from meta.onboarding.phase") so an agent can infer it drives setup progression, but it never states plainly what the tool does at the top level (start onboarding, run a phase, or manage an import draft). Terms like "showUser" and "meta.onboarding.phase" are undefined and the verb/resource pairing is vague.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives real invocation guidance: omit phase to start, resume from meta.onboarding.phase, skipForGood opts out, and the import sequence stage -> show -> save/discard. It offers no differentiation from the siblings (penny_session_start, penny_write, penny_read), so an agent has no cue about when to pick this over starting a session.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
penny_writeAInspect
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. Choose entityType: walk this ladder, first match wins:
Durable fact about the user or their people → update the profile (profile upsert or penny_edit), not a note. How they want to be remembered → memory_policy, a general rule in their words; how they want you to show up (tone/register/manner) → 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.
Commitment/action with a done-state → task. Organize via area/project/heading. A to-do the user mentions, even in passing, is a task: offer to capture it, then write it. Project create: patch.name/purpose + operationId; revise: projectId + expectedRevision from Brief + sparse patch (max 25 step/resource changes). project_interaction records actor proposals/declines/deferrals. pending_share_approval 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.
Measurement → tracker_entry for an existing tracker (check inventory); otherwise propose tracker first. Active duplicate tracker names are rejected; edit with penny_edit. A measurement the user would log more than once is a tracker entry; if no tracker fits, propose one before logging.
Reusable know-how → skill; trigger makes it scheduled (legacy rhythm). Existing skill names prepare a preview; wait for user approval before penny_edit op:apply with proposalId. Run on-demand via skill_invoke; begin scheduled runs via 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.
Other context/events/ideas/learning → note. Prefer a specific type when unsure; a note is the fallback, not the default. When the user is learning something to keep, offer to let them try first; if search shows they asked before, say so once with the date; save misses and level. If so, read penny_get_skill references/learning.md. Also tag_relation and tracker_note_link. Batch notes or tracker_entry entries: max100. Modify existing items with penny_edit; trash with penny_delete. Reuse an existing tag before minting a new one. Tagging and linking conventions live in the Penny skill.
Note confidence measures signal, not pipeline: 0.95 = explicit user statement; 0.80 = confirmed decision; 0.60 = reasonable inference; 0.40 = hedged or sleeptime-derived; 0.20 = weak signal. Each note needs sampleQuestions: exactly three short, distinct natural-language questions derived from its content, in the user's voice, not keywords or near-duplicates. For an APA preference: ["What citation style should I use for the paper?", "How should I format references in my thesis?", "What’s my usual academic style?"].
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | rhythm: required run instructions; skill uses instructions instead. | |
| kind | No | tracker: required; habit|metric|goal|log|status|custom. | |
| name | No | Required: tracker/area/project/rhythm and entityType:"skill". skill_invoke/skill_run: alternative to skillId. Existing skill names preview changes; new names create. Active tracker duplicates are rejected; archived names reactivate. | |
| tags | No | task: tags to attach. | |
| unit | No | tracker: unit of measure. | |
| actor | No | task/area/project/heading: actor (me|agent) recorded in activity ledger. | |
| child | No | tag_relation: required 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 | task/area/project/heading: sort order. | |
| owner | No | 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 | task/heading: required title/label. | |
| areaId | No | project: required parent area. | |
| parent | No | tag_relation: required parent tag of child_of edge. | |
| source | No | note/tracker_entry: provenance; defaults conversation/agent-mcp respectively. | |
| status | No | task: initial status. | |
| whenAt | No | task/project: schedule date (ms epoch). | |
| content | No | profile: required block content. | |
| deliver | No | entityType:"skill": required with trigger; rhythm: required. Omit for on-demand. Scheduled output: {kind:'note',tags?:string[]}|{kind:'profile_block',blockName:string}|{kind:'notify'}. | |
| entries | No | tracker_entry: up to 100 for one trackerId; each {payload,loggedAt?,agentNote?,noteIds?,source?,metadata?,externalId?}. Mutually exclusive with top-level payload. Receipts list saved/failed items and duplicates for stored externalIds; do not claim all saved from a partial result. | |
| noteIds | No | tracker_entry: archival note IDs to attach. tracker_note_link: required note IDs to link. | |
| payload | No | tracker_entry: tracker-defined data point; required unless entries is used. | |
| posture | No | entityType:"skill" with trigger, or rhythm: read|propose|act; default read. | |
| skillId | No | skill_invoke/skill_run: skill to run now/begin; required unless name is given. | |
| trigger | No | entityType:"skill": optional; rhythm: required. Requires deliver. Penny 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 IANA timezone; default UTC shifts local times. Event: {kind:"event",on:"note.created",where?:{tags?:string[]}}. | |
| deadline | No | task/project: hard due date (ms epoch). | |
| rhythmId | No | rhythm_run: rhythm to begin; or pass name. | |
| agentNote | No | tracker_entry, single only: short non-searchable caption. | |
| blockName | No | profile: required block name to upsert. | |
| dependsOn | No | task: full prerequisite taskId set; replaces all. | |
| headingId | No | task: parent heading. | |
| linkNotes | No | task: note IDs to link. | |
| projectId | No | task: parent Project. heading: required parent Project. | |
| reasoning | No | tag_relation: short edge justification, typically a user quote. | |
| trackerId | No | tracker_entry: required tracker to log against. | |
| entityType | Yes | What to create; first match in the tool description's ladder wins. | |
| externalId | No | tracker_entry, also entries items: source record ID, max 200 chars. Use for imports/sync: repeats on the same tracker return the existing entry as duplicate. Opaque, unencrypted: never include content. | |
| recordedAt | No | tracker_entry, single only: observation time (ms epoch); default now. | |
| recurrence | No | task: repeat. Returned taskId is the first occurrence; completion returns nextTaskId (see penny_edit status). Never reuse a completed occurrence's ID. | |
| targetSpec | No | tracker: JSON target spec, interpreted at retrieval (e.g. {kind:'daily_minimum',value:10000}). | |
| whenBucket | No | task/project: undated bucket; mutually exclusive with whenAt. | |
| description | No | tracker: required meaning. entityType:"skill"/rhythm: required one-line purpose, including on-demand skills. | |
| interaction | No | project_interaction: actor decision; read first, update with expectedUpdatedAt. | |
| operationId | No | Project receipt key; identical retries only. | |
| instructions | No | skill: required know-how for invocation or when a connected agent picks up a due skill. Replaces rhythm goal. | |
| retrievalPlan | No | entityType:"skill"/rhythm: optional deterministic steps [{tool,args}] for a bounded tier. | |
| trackerEntryId | No | tracker_note_link: required entry to attach notes to. | |
| expectedRevision | No | Project revision from Brief; reconcile conflicts. | |
| expectedUpdatedAt | No | Source version from read. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a write tool, but the description adds substantial behavioral context: batch limits of 100, duplicate handling, tracker receipts, skill preview/approval flow, task recurrence return behavior, project revision conflicts, and confidence scoring semantics. These are concrete operational traits beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and uses a numbered ladder for structure, but it is very dense, includes duplicated schema detail, and contains long run-on clauses. The complexity justifies some length, but several details could be tightened without losing invocation guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 50-parameter omnibus tool with no output schema, the description covers the major workflows, constraints, and return-relevant behaviors such as duplicates and task recurrence. It still does not fully explain return behavior or every entity type, but schema coverage and annotations make it sufficiently complete for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents parameters extensively. The description adds crucial meaning beyond the schema by providing the entityType selection ladder and mapping each entity type to the relevant workflow and parameters, though it does not add semantics for all 50 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action—save durable information mid-conversation—and defines the resource scope through an explicit entityType ladder. It also distinguishes the tool from siblings by naming penny_edit for modifications, penny_delete for trashing, and other alternatives for profiles, trackers, skills, and notes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives extensive when-to-use guidance: save when something durable emerges and the call is close, follow the first-match entityType ladder, prefer specific types over notes, check tracker inventory, propose trackers when missing, and use penny_edit or penny_delete instead of penny_write for modifications/removals. It also names exceptions such as pending_share_approval being a proposal, not a save.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
penny_start_setup1 field changed- changed
Input schema / properties / client / descriptionPrevious value: -"Actual host: claude-desktop, claude-web, claude-code, codex, chatgpt, gemini, perplexity or other; tailors paste guidance."New value: +"Actual host: claude-desktop, claude-web, claude-code, codex, chatgpt, gemini, perplexity, grok (web only), grok-bot or other; tailors paste guidance."
1 tool update
- Changed
penny_start_setup1 field changed- changed
Input schema / properties / client / descriptionPrevious value: -"Actual host: claude-desktop, claude-code, codex, chatgpt or other; tailors paste guidance."New value: +"Actual host: claude-desktop, claude-web, claude-code, codex, chatgpt, gemini, perplexity or other; tailors paste guidance."
2 tool updates
- Changed
penny_read1 field changed- changed
Input schema / properties / query / descriptionPrevious value: -"search: required semantic query. projects directory: name/purpose filter; check coverage."New value: +"search: required. One specific question or phrase, usually 8-15 words, with the names and distinctive terms you're looking for (\"What did Dana decide about the kitchen remodel budget?\", not \"budget\" or a paragraph); perfect grammar isn't needed; don't pad a short question; on a miss, search again with different terms, not a longer query. projects directory: name/purpose filter; check coverage."
- Changed
penny_session_start4 fields changed- removed
Input schema / properties / installedSkillSha256Removed value: -{ - "description": "Exact metadata.bundle_sha256; report absent metadata as unversioned.", - "type": "string" -} - removed
Input schema / properties / installedSkillSourceRemoved value: -{ - "description": "Manage plugin copies via plugin manager; standalone via approved archive installation.", - "enum": [ - "standalone", - "plugin", - "unsupported", - "unknown" - ], - "type": "string" -} - removed
Input schema / properties / installedSkillStatusRemoved value: -{ - "description": "Read installed skill, then report. Legacy omission returns not_reported.", - "enum": [ - "versioned", - "unversioned", - "missing" - ], - "type": "string" -} - removed
Input schema / properties / installedSkillVersionRemoved value: -{ - "description": "Exact installed metadata.version; omit if missing or unversioned.", - "type": "string" -}
2 tool updates
- Changed
penny_edit5 fields changed- changed
Input schema / properties / entityType / enumPrevious value: -[ - "profile", - "task", - "area", - "project", - "heading", - "tracker", - "rhythm", - "rhythm_run", - "skill", - "skill_run", - "note", - "tracker_entry" -]New value: +[ + "profile", + "task", + "area", + "project", + "heading", + "tracker", + "rhythm", + "rhythm_run", + "skill", + "skill_run", + "note", + "tracker_entry", + "session" +] - added
Input schema / properties / recordAdded value: +{ + "description": "entityType:\"session\" (required) — \"off\". One-way: there is no way back on for the session.", + "enum": [ + "off" + ], + "type": "string" +} - added
Input schema / properties / sessionIdAdded value: +{ + "description": "entityType:\"session\" — the transcript session to take off the record, from <mypenny-session>; omit when the host gives none.", + "type": "string" +} - changed
Input schema / properties / taskId / descriptionPrevious value: -"task: required ID to update."New value: +"task: ID to update." - added
Input schema / properties / taskUpdatesAdded value: +{ + "description": "task: edits, each {taskId, ...task fields} except card. All are checked first; one bad item saves none.", + "items": { + "type": "object" + }, + "maxItems": 100, + "type": "array" +}
- Changed
penny_read1 field changed- added
Input schema / properties / legacyProjectKeyAdded value: +{ + "description": "profile: coding-plugin migration aid — the same repo's older key, served in place of subconscious:<projectKey> until that exists.", + "type": "string" +}
1 tool update
- Changed
penny_start_setup7 fields changed- changed
Input schema / properties / draftId / descriptionPrevious value: -"Returned collection ID; stage only."New value: +"Returned draft ID." - added
Input schema / properties / dropItemIdsAdded value: +{ + "description": "save: dropped ids (values of items).", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / expectedRevision / descriptionPrevious value: -"Returned revision; stage only."New value: +"Returned revision." - changed
Input schema / properties / importAction / descriptionPrevious value: -"Stage needs importDraft, draftId, expectedRevision. Status has no content. No model approval."New value: +"All but status need draftId and expectedRevision; stage also importDraft. status re-sends the list." - changed
Input schema / properties / importAction / enumPrevious value: -[ - "stage", - "status" -]New value: +[ + "stage", + "status", + "save", + "discard" +] - changed
Input schema / properties / importDraft / descriptionPrevious value: -"Strict JSON {notes,profiles}; returned schema. 10 notes, 4 replacements, 64 KiB UTF-8. No approval/source/selection."New value: +"Strict JSON {notes,profiles}; returned schema. 10 notes, 4 replacements, 64 KiB UTF-8." - added
Input schema / properties / keepItemIdsAdded value: +{ + "description": "save: left-out ids the user kept.", + "items": { + "type": "string" + }, + "type": "array" +}
1 tool update
- Changed
penny_read4 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Project cursor; retain view/scope."New value: +"projects/tasks: prior nextCursor; keep the same filters. tasks: a page can be short and still have one; read until a reply has none." - changed
Input schema / properties / includeCompleted / descriptionPrevious value: -"tasks: include done/canceled; default false."New value: +"tasks: include done/canceled; default false. An explicit status wins." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max search/notes/tracker-entry/task/rhythm-run results."New value: +"Max search/notes/tracker-entry/task/rhythm-run results. tasks: page size; long pages end early with nextCursor." - changed
Input schema / properties / view / descriptionPrevious value: -"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). tracker: list|entries; rhythms: list|one|due|runs; skills: list|one|due|runs|history|trash (list/trash omit instructions; one returns full skill by skillId or name); tags: list|related."New value: +"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). tracker: list|entries; rhythms: list|one|due|runs; skills: list|one|due|runs|history|trash (list/trash omit instructions; one returns full skill by skillId or name); tags: list|related; tasks: compact omits notes."
7 tool updates
- Changed
penny_delete5 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"entityType:\"note\"/\"tracker_entry\" — ids to trash (max 100); \"rhythm\"/\"skill\" — exactly one id; \"profile_block\" — block names to trash."New value: +"note/tracker_entry: IDs to trash, max 100. rhythm/skill: exactly one ID. profile_block: block names to trash." - changed
Input schema / properties / noteIds / descriptionPrevious value: -"entityType:\"tracker_note_link\" (required) — the notes to unlink."New value: +"tracker_note_link: required note IDs to unlink." - changed
Input schema / properties / tagA / descriptionPrevious value: -"entityType:\"tag_relation\" (required) — one endpoint of the edge to remove."New value: +"tag_relation: required edge endpoint to remove." - changed
Input schema / properties / tagB / descriptionPrevious value: -"entityType:\"tag_relation\" (required) — the other endpoint."New value: +"tag_relation: required other endpoint." - changed
Input schema / properties / trackerEntryId / descriptionPrevious value: -"entityType:\"tracker_note_link\" (required) — the entry to detach notes from."New value: +"tracker_note_link: required entry to detach notes from."
- Changed
penny_edit42 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"entityType:\"task\"/\"area\"/\"project\"/\"heading\" — who took the action (me|agent), written to the activity ledger."New value: +"task/area/project/heading: actor (me|agent) recorded in activity ledger." - changed
Input schema / properties / areaId / descriptionPrevious value: -"entityType:\"project\" — the area the project belongs to."New value: +"project: parent area." - changed
Input schema / properties / blockName / descriptionPrevious value: -"entityType:\"profile\" (required) — the profile block to upsert."New value: +"profile: required block to upsert." - changed
Input schema / properties / clearFields / descriptionPrevious value: -"entityType:\"task\" — names of optional fields to UNSET on the task."New value: +"task: optional fields to unset." - changed
Input schema / properties / content / descriptionPrevious value: -"entityType:\"profile\" (required) — the new block content."New value: +"profile: required new block content." - changed
Input schema / properties / deadline / descriptionPrevious value: -"entityType:\"task\"/\"project\" — hard due date (ms epoch)."New value: +"task/project: hard due date (ms epoch)." - changed
Input schema / properties / deliver / descriptionPrevious value: -"entityType:\"skill\": required with trigger (also rhythm); omit for on-demand. See penny_write for shape."New value: +"entityType:\"skill\": required with trigger; rhythm: required. Omit for on-demand. Shape: penny_write." - changed
Input schema / properties / dependsOn / descriptionPrevious value: -"entityType:\"task\" — full replacement set of taskIds that must complete first."New value: +"task: full prerequisite taskId set; replaces all." - changed
Input schema / properties / description / descriptionPrevious value: -"entityType:\"skill\": REQUIRED use-when description; also rhythm. tracker: meaning; log trackers must document payload shape."New value: +"entityType:\"skill\"/rhythm: required use-when description. tracker: meaning; log trackers must document payload shape." - changed
Input schema / properties / enabled / descriptionPrevious value: -"entityType:\"skill\": false pauses due signals, true resumes; requires skillId. Penny does not run skills."New value: +"skill: false pauses due signals, true resumes; requires skillId. Penny does not run skills." - changed
Input schema / properties / expectedRevision / descriptionPrevious value: -"Project edit revision from Brief; reconcile conflicts."New value: +"Project revision from Brief; reconcile conflicts." - changed
Input schema / properties / expectedUpdatedAt / descriptionPrevious value: -"Source version from the read."New value: +"Source version from read." - changed
Input schema / properties / goal / descriptionPrevious value: -"entityType:\"rhythm\" (required) — what the run should do. On entityType:\"skill\" this is `instructions`."New value: +"rhythm: required run instructions; skill uses instructions instead." - changed
Input schema / properties / historyId / descriptionPrevious value: -"restore_revision: Project history item or skill history item. Skill restoration prepares a preview; requires skillId and expectedUpdatedAt."New value: +"restore_revision: Project/skill history ID. Skill restore previews; requires skillId and expectedUpdatedAt." - changed
Input schema / properties / ids / descriptionPrevious value: -"op:\"restore\" — ids to un-trash (max 100)."New value: +"restore: IDs to un-trash; max 100." - changed
Input schema / properties / instructions / descriptionPrevious value: -"entityType:\"skill\" (required) — the saved know-how (generalizes the rhythm \"goal\")."New value: +"skill: required saved know-how; replaces rhythm goal." - changed
Input schema / properties / kind / descriptionPrevious value: -"entityType:\"tracker\" — habit | metric | goal | log | status | custom."New value: +"tracker: habit|metric|goal|log|status|custom." - changed
Input schema / properties / linkNotes / descriptionPrevious value: -"entityType:\"task\" — note ids to link to this task."New value: +"task: note IDs to link." - changed
Input schema / properties / name / descriptionPrevious value: -"Area/project/tracker name; entityType:\"skill\" names prepare a preview of the replacement (rhythm names upsert)."New value: +"area/project/tracker: name. entityType:\"skill\": previews replacement; rhythm: upserts." - changed
Input schema / properties / notes / descriptionPrevious value: -"entityType:\"task\"/\"area\"/\"project\" — markdown body."New value: +"task/area/project: markdown body." - changed
Input schema / properties / op / descriptionPrevious value: -"op:\"restore\" un-trashes notes or tracker entries by `ids`."New value: +"restore: un-trash notes/tracker entries by ids." - changed
Input schema / properties / order / descriptionPrevious value: -"entityType:\"task\"/\"area\"/\"project\"/\"heading\" — sort order."New value: +"task/area/project/heading: sort order." - changed
Input schema / properties / orgId / descriptionPrevious value: -"entityType:\"area\"/\"project\"/\"heading\" (required) — the container to update."New value: +"area/project/heading: required container ID to update." - changed
Input schema / properties / owner / descriptionPrevious value: -"entityType:\"task\" — assignee."New value: +"task: assignee." - changed
Input schema / properties / posture / descriptionPrevious value: -"entityType:\"skill\" with a `trigger` set (or legacy \"rhythm\") — read | propose | act."New value: +"entityType:\"skill\" with trigger, or rhythm: read|propose|act." - changed
Input schema / properties / projectId / descriptionPrevious value: -"entityType:\"heading\" (required) — the project the heading belongs to."New value: +"heading: required parent Project." - changed
Input schema / properties / proposalId / descriptionPrevious value: -"Skill change proposal returned by an edit. op:apply commits after user review; cancel discards; undo restores the previous version if no later edit exists."New value: +"Returned skill proposal. apply commits after user review; cancel discards; undo restores the previous version only if no later edit exists." - changed
Input schema / properties / provenance / descriptionPrevious value: -"entityType:\"rhythm_run\" — accountability summary of what the run did (ids/labels, never full content)."New value: +"rhythm_run: accountability summary (IDs/labels, never full content)." - changed
Input schema / properties / retrievalPlan / descriptionPrevious value: -"entityType:\"skill\" (or legacy \"rhythm\") — OPTIONAL deterministic steps for a bounded tier."New value: +"entityType:\"skill\"/rhythm: optional deterministic steps for a bounded tier." - changed
Input schema / properties / runId / descriptionPrevious value: -"entityType:\"skill_run\" (required) — the run to complete; same field on the legacy \"rhythm_run\"."New value: +"skill_run/rhythm_run: required run ID to complete." - changed
Input schema / properties / skillId / descriptionPrevious value: -"entityType:\"skill\" pause/resume — the skill id (required with enabled)."New value: +"skill: ID required with enabled to pause/resume." - changed
Input schema / properties / snapshot / descriptionPrevious value: -"Skill restore_revision: which side of the history entry to restore (default before). Select after to recover a change that was undone."New value: +"skill restore_revision: history side; default before. after recovers an undone change." - changed
Input schema / properties / taskId / descriptionPrevious value: -"entityType:\"task\" (required) — the task to update."New value: +"task: required ID to update." - changed
Input schema / properties / title / descriptionPrevious value: -"entityType:\"task\"/\"heading\" — the title/label."New value: +"task/heading: title/label." - changed
Input schema / properties / trackerId / descriptionPrevious value: -"entityType:\"tracker\" (required) — the tracker to update. Only the fields you pass are patched — omit any you don't want to change."New value: +"tracker: required ID to update; only supplied fields change." - changed
Input schema / properties / trigger / descriptionPrevious value: -"entityType:\"skill\": optional (required for rhythm). Omit to return to on-demand. Penny does not run it; the connected agent receives due signals. See penny_write for shape; ALWAYS set IANA timezone, default UTC."New value: +"entityType:\"skill\": optional; rhythm: required. Omit to return to on-demand. Penny does not run it; connected agents receive due signals. Shape: penny_write. ALWAYS set IANA timezone; default UTC." - changed
Input schema / properties / unit / descriptionPrevious value: -"entityType:\"tracker\" — unit of measure."New value: +"tracker: unit of measure." - changed
Input schema / properties / updates / descriptionPrevious value: -"entityType:\"note\" — patch or supersede existing notes (up to 100)."New value: +"note: patch or supersede up to 100 existing notes." - changed
Input schema / properties / updates / items / properties / content / descriptionPrevious value: -"Required when mode is \"patch\"."New value: +"Required for patch." - changed
Input schema / properties / updates / items / properties / supersededBy / descriptionPrevious value: -"Required when mode is \"replace\" — the id of the note that replaces this one."New value: +"replace: required replacement note ID." - changed
Input schema / properties / whenAt / descriptionPrevious value: -"entityType:\"task\"/\"project\" — schedule date (ms epoch)."New value: +"task/project: schedule date (ms epoch)." - changed
Input schema / properties / whenBucket / descriptionPrevious value: -"entityType:\"task\"/\"project\" — undated bucket; mutually exclusive with whenAt."New value: +"task/project: undated bucket; mutually exclusive with whenAt."
- Changed
penny_get_skill2 fields changed- changed
Input schema / properties / file / descriptionPrevious value: -"Exact manifest path, default SKILL.md; read view only."New value: +"Exact manifest path; default SKILL.md; read view only." - changed
Input schema / properties / view / descriptionPrevious value: -"Default read. Install returns an archive, not readable guidance."New value: +"Default read. install returns an archive, not guidance."
- Changed
penny_read31 fields changed- changed
Input schema / properties / areaId / descriptionPrevious value: -"target:\"tasks\" — filter by area, or organize=\"project\" filter."New value: +"tasks: area filter; also applies to organize:project." - changed
Input schema / properties / blocked / descriptionPrevious value: -"target:\"tasks\" — restrict to tasks with unmet dependsOn."New value: +"tasks: only tasks with unmet dependsOn." - changed
Input schema / properties / bucket / descriptionPrevious value: -"target:\"tasks\" — filter by schedule bucket."New value: +"tasks: schedule bucket filter." - changed
Input schema / properties / dateAxis / descriptionPrevious value: -"target:\"notes\" — which date timeRange filters ('created' = when written, 'valid' = when the fact holds)."New value: +"notes: timeRange axis; created = when written, valid = when the fact holds." - changed
Input schema / properties / depth / descriptionPrevious value: -"target:\"note_links\" — hops to expand (1 = direct links; 2-6 = bounded BFS)."New value: +"note_links: hops (1 = direct; 2-6 = bounded BFS)." - changed
Input schema / properties / dueRange / descriptionPrevious value: -"target:\"tasks\" — due-date window (ms epoch)."New value: +"tasks: due-date window (ms epoch)." - changed
Input schema / properties / edgeTypes / descriptionPrevious value: -"target:\"note_links\" — only follow/return edges of these relationship types."New value: +"note_links: only follow/return these relationship types." - changed
Input schema / properties / enabledOnly / descriptionPrevious value: -"target:\"rhythms\" view:\"list\" — only enabled rhythms."New value: +"rhythms/list: only enabled rhythms." - changed
Input schema / properties / from / descriptionPrevious value: -"target:\"tracker\" entries / tracker_summary — start of window (ms epoch)."New value: +"tracker/entries, tracker_summary: window start (ms epoch)." - changed
Input schema / properties / ifRevision / descriptionPrevious value: -"profile: the revision from your last read; returns {unchanged:true} if nothing changed."New value: +"profile: last-read revision; returns {unchanged:true} if unchanged." - changed
Input schema / properties / includeCompleted / descriptionPrevious value: -"target:\"tasks\" — include done/canceled tasks (default false)."New value: +"tasks: include done/canceled; default false." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results. Applies to search, notes, tracker entries, tasks, and rhythm runs."New value: +"Max search/notes/tracker-entry/task/rhythm-run results." - changed
Input schema / properties / maxNodes / descriptionPrevious value: -"target:\"note_links\" — cap on returned nodes when depth > 1 (default 50)."New value: +"note_links: node cap for depth > 1; default 50." - changed
Input schema / properties / name / descriptionPrevious value: -"Projects directory: exact-name candidates; continue incomplete coverage. target:\"skills\" view:\"one\": the skill's name, in place of skillId."New value: +"Projects directory: exact-name candidates; continue incomplete coverage. skills/one: name instead of skillId." - changed
Input schema / properties / orgStatus / descriptionPrevious value: -"target:\"tasks\" organize=\"project\" — filter projects by status."New value: +"tasks organize:project: Project status filter." - changed
Input schema / properties / organize / descriptionPrevious value: -"target:\"tasks\" — enumerate containers instead of tasks."New value: +"tasks: list containers instead of tasks." - changed
Input schema / properties / owner / descriptionPrevious value: -"target:\"tasks\" — filter by owner."New value: +"tasks: owner filter." - changed
Input schema / properties / projectId / descriptionPrevious value: -"target:projects brief/section/resources/resource/history — required stable Project ID. target:tasks — Project filter, or heading parent."New value: +"projects brief/section/resources/resource/history: required stable Project ID. tasks: Project filter or heading parent." - changed
Input schema / properties / rhythmId / descriptionPrevious value: -"target:\"rhythms\" view:\"one\" (required) or view:\"runs\" (optional scope)."New value: +"rhythms: required for one; optional run scope for runs." - changed
Input schema / properties / section / descriptionPrevious value: -"target:projects view:section — one Brief section."New value: +"projects/section: one Brief section." - changed
Input schema / properties / seedIds / descriptionPrevious value: -"target:\"note_links\" — note id(s) to start the link-graph walk from (required)."New value: +"note_links: required starting note IDs." - changed
Input schema / properties / seriesId / descriptionPrevious value: -"tasks: one recurring series’ complete occurrence history, newest first (includes completed)."New value: +"tasks: complete recurring-series history, newest first, including completed occurrences." - changed
Input schema / properties / skillId / descriptionPrevious value: -"target:\"skills\" view:\"one\" (required unless name is given) or view:\"runs\" (optional scope)."New value: +"skills: required for one unless name is given; optional run scope for runs." - changed
Input schema / properties / status / descriptionPrevious value: -"target:\"tasks\" — filter by task status."New value: +"tasks: status filter." - changed
Input schema / properties / tags / descriptionPrevious value: -"Filter by tags. Applies to target \"search\" and \"notes\"."New value: +"search/notes: tag filter." - changed
Input schema / properties / target / descriptionPrevious value: -"What to read. Walk the ladder in the tool description; first match wins."New value: +"What to read; first match in the tool description's ladder wins." - changed
Input schema / properties / timeRange / descriptionPrevious value: -"Time window (ms epoch). Applies to target \"search\" and \"notes\"."New value: +"search/notes: time window (ms epoch)." - changed
Input schema / properties / to / descriptionPrevious value: -"target:\"tracker\" entries / tracker_summary — end of window (ms epoch)."New value: +"tracker/entries, tracker_summary: window end (ms epoch)." - changed
Input schema / properties / trackerId / descriptionPrevious value: -"target:\"tracker\" view:\"entries\" (required), or target:\"tracker_summary\" (required)."New value: +"Required for tracker/entries and tracker_summary." - changed
Input schema / properties / tz / descriptionPrevious value: -"target:\"tasks\" — IANA timezone for Today/Upcoming boundaries."New value: +"tasks: IANA timezone for Today/Upcoming boundaries." - changed
Input schema / properties / view / descriptionPrevious value: -"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). Secondary selector: target:\"tracker\" list|entries; target:\"rhythms\" list|one|due|runs; target:\"skills\" list|one|due|runs|history|trash (list/trash omit instructions; one: full skill by skillId or name); target:\"tags\" list|related."New value: +"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). tracker: list|entries; rhythms: list|one|due|runs; skills: list|one|due|runs|history|trash (list/trash omit instructions; one returns full skill by skillId or name); tags: list|related."
- Changed
penny_session_start5 fields changed- changed
Input schema / properties / installedSkillSource / descriptionPrevious value: -"Management: plugin manager for plugin copies; approved archive installation for standalone copies."New value: +"Manage plugin copies via plugin manager; standalone via approved archive installation." - changed
Input schema / properties / installedSkillStatus / descriptionPrevious value: -"Report after reading the installed skill. Legacy omission returns not_reported."New value: +"Read installed skill, then report. Legacy omission returns not_reported." - changed
Input schema / properties / installedSkillVersion / descriptionPrevious value: -"Exact metadata.version from the installed skill; omit if missing or unversioned."New value: +"Exact installed metadata.version; omit if missing or unversioned." - changed
Input schema / properties / projectKey / descriptionPrevious value: -"Includes only the matching subconscious:<projectKey> block; other subconscious blocks are always excluded."New value: +"Include subconscious:<projectKey>; exclude all other subconscious blocks." - changed
Input schema / properties / tz / descriptionPrevious value: -"IANA timezone for deriving today/overdue date boundaries (e.g. America/New_York). Defaults to UTC when omitted."New value: +"IANA timezone for today/overdue boundaries (e.g. America/New_York); default UTC."
- Changed
penny_start_setup4 fields changed- changed
Input schema / properties / client / descriptionPrevious value: -"Actual host: claude-desktop, claude-code, codex, chatgpt or other. Also tailors paste guidance."New value: +"Actual host: claude-desktop, claude-code, codex, chatgpt or other; tailors paste guidance." - changed
Input schema / properties / counts / descriptionPrevious value: -"Cumulative answers/featuresCreated. imported is ignored for ledger imports; only committed receipts count."New value: +"Cumulative answers/featuresCreated. Ledger imports ignore imported; only committed receipts count." - changed
Input schema / properties / prevAccepted / descriptionPrevious value: -"Whether the user took the previous tour stop's offer."New value: +"Did the user accept the previous tour stop's offer?" - changed
Input schema / properties / skipForGood / descriptionPrevious value: -"The user said to skip setup for good."New value: +"User requested permanent setup opt-out."
- Changed
penny_write48 fields changed- changed
Input schema / properties / actor / descriptionPrevious value: -"entityType:\"task\"/\"area\"/\"project\"/\"heading\" — who took the action (me|agent), written to the activity ledger."New value: +"task/area/project/heading: actor (me|agent) recorded in activity ledger." - changed
Input schema / properties / agentNote / descriptionPrevious value: -"entityType:\"tracker_entry\" (single-entry form only) — short caption on this one data point (not searchable)."New value: +"tracker_entry, single only: short non-searchable caption." - changed
Input schema / properties / areaId / descriptionPrevious value: -"entityType:\"project\" (required) — the area the project belongs to."New value: +"project: required parent area." - changed
Input schema / properties / blockName / descriptionPrevious value: -"entityType:\"profile\" (required) — the profile block name to upsert."New value: +"profile: required block name to upsert." - changed
Input schema / properties / child / descriptionPrevious value: -"entityType:\"tag_relation\" (required) — the child tag."New value: +"tag_relation: required child tag." - changed
Input schema / properties / content / descriptionPrevious value: -"entityType:\"profile\" (required) — the block content."New value: +"profile: required block content." - changed
Input schema / properties / deadline / descriptionPrevious value: -"entityType:\"task\"/\"project\" — hard due date (ms epoch)."New value: +"task/project: hard due date (ms epoch)." - changed
Input schema / properties / deliver / descriptionPrevious value: -"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' }."New value: +"entityType:\"skill\": required with trigger; rhythm: required. Omit for on-demand. Scheduled output: {kind:'note',tags?:string[]}|{kind:'profile_block',blockName:string}|{kind:'notify'}." - changed
Input schema / properties / dependsOn / descriptionPrevious value: -"entityType:\"task\" — full replacement set of taskIds that must complete first."New value: +"task: full prerequisite taskId set; replaces all." - changed
Input schema / properties / description / descriptionPrevious value: -"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."New value: +"tracker: required meaning. entityType:\"skill\"/rhythm: required one-line purpose, including on-demand skills." - changed
Input schema / properties / entityType / descriptionPrevious value: -"What to create. Walk the ladder in the tool description; first match wins."New value: +"What to create; first match in the tool description's ladder wins." - changed
Input schema / properties / entries / descriptionPrevious value: -"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."New value: +"tracker_entry: up to 100 for one trackerId; each {payload,loggedAt?,agentNote?,noteIds?,source?,metadata?,externalId?}. Mutually exclusive with top-level payload. Receipts list saved/failed items and duplicates for stored externalIds; do not claim all saved from a partial result." - changed
Input schema / properties / expectedRevision / descriptionPrevious value: -"Project edit revision from Brief; reconcile conflicts."New value: +"Project revision from Brief; reconcile conflicts." - changed
Input schema / properties / expectedUpdatedAt / descriptionPrevious value: -"Source version from the read."New value: +"Source version from read." - added
Input schema / properties / externalIdAdded value: +{ + "description": "tracker_entry, also entries items: source record ID, max 200 chars. Use for imports/sync: repeats on the same tracker return the existing entry as duplicate. Opaque, unencrypted: never include content.", + "type": "string" +} - changed
Input schema / properties / goal / descriptionPrevious value: -"entityType:\"rhythm\" (required) — natural-language instruction: what the run should do. On entityType:\"skill\" this is `instructions`."New value: +"rhythm: required run instructions; skill uses instructions instead." - changed
Input schema / properties / headingId / descriptionPrevious value: -"entityType:\"task\" — heading to file the task under."New value: +"task: parent heading." - changed
Input schema / properties / instructions / descriptionPrevious value: -"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\"."New value: +"skill: required know-how for invocation or when a connected agent picks up a due skill. Replaces rhythm goal." - changed
Input schema / properties / kind / descriptionPrevious value: -"entityType:\"tracker\" (required) — habit | metric | goal | log | status | custom."New value: +"tracker: required; habit|metric|goal|log|status|custom." - changed
Input schema / properties / linkNotes / descriptionPrevious value: -"entityType:\"task\" — note ids to link to this task."New value: +"task: note IDs to link." - changed
Input schema / properties / name / descriptionPrevious value: -"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."New value: +"Required: tracker/area/project/rhythm and entityType:\"skill\". skill_invoke/skill_run: alternative to skillId. Existing skill names preview changes; new names create. Active tracker duplicates are rejected; archived names reactivate." - changed
Input schema / properties / noteIds / descriptionPrevious value: -"entityType:\"tracker_entry\" — archival note ids to attach; or \"tracker_note_link\" (required) — the notes to link."New value: +"tracker_entry: archival note IDs to attach. tracker_note_link: required note IDs to link." - changed
Input schema / properties / order / descriptionPrevious value: -"entityType:\"task\"/\"area\"/\"project\"/\"heading\" — sort order."New value: +"task/area/project/heading: sort order." - changed
Input schema / properties / owner / descriptionPrevious value: -"entityType:\"task\" — assignee."New value: +"task: assignee." - changed
Input schema / properties / parent / descriptionPrevious value: -"entityType:\"tag_relation\" (required) — the parent tag in the child_of edge."New value: +"tag_relation: required parent tag of child_of edge." - changed
Input schema / properties / patch / descriptionPrevious value: -"Project sparse changes; omitted fields stay. Max 25 step/resource changes."New value: +"Project: sparse changes; omitted fields stay. Max 25 step/resource changes." - changed
Input schema / properties / patch / properties / steps / descriptionPrevious value: -"accept converts a saved suggestion into a To-do."New value: +"accept turns a saved suggestion into a To-do." - changed
Input schema / properties / payload / descriptionPrevious value: -"entityType:\"tracker_entry\" (required unless `entries` is used) — the structured data point; shape is tracker-defined."New value: +"tracker_entry: tracker-defined data point; required unless entries is used." - changed
Input schema / properties / posture / descriptionPrevious value: -"entityType:\"skill\" with a `trigger` set (or legacy \"rhythm\") — read | propose | act (defaults 'read')."New value: +"entityType:\"skill\" with trigger, or rhythm: read|propose|act; default read." - changed
Input schema / properties / projectId / descriptionPrevious value: -"entityType:\"task\" — parent project; or \"heading\" — the project it belongs to (required)."New value: +"task: parent Project. heading: required parent Project." - changed
Input schema / properties / reasoning / descriptionPrevious value: -"entityType:\"tag_relation\" — short justification (typically a user quote) for the edge."New value: +"tag_relation: short edge justification, typically a user quote." - changed
Input schema / properties / recordedAt / descriptionPrevious value: -"entityType:\"tracker_entry\" (single-entry form only) — observation time (ms epoch; defaults to now)."New value: +"tracker_entry, single only: observation time (ms epoch); default now." - changed
Input schema / properties / recurrence / descriptionPrevious value: -"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."New value: +"task: repeat. Returned taskId is the first occurrence; completion returns nextTaskId (see penny_edit status). Never reuse a completed occurrence's ID." - changed
Input schema / properties / recurrence / properties / at / descriptionPrevious value: -"Time expression: \"HH:MM\" for daily, \"<Wd> HH:MM\" for weekly, \"DD HH:MM\" for monthly."New value: +"daily: HH:MM; weekly: <Wd> HH:MM; monthly: DD HH:MM." - changed
Input schema / properties / retrievalPlan / descriptionPrevious value: -"entityType:\"skill\" (or legacy \"rhythm\") — OPTIONAL deterministic steps [{ tool, args }] for a bounded tier."New value: +"entityType:\"skill\"/rhythm: optional deterministic steps [{tool,args}] for a bounded tier." - changed
Input schema / properties / rhythmId / descriptionPrevious value: -"entityType:\"rhythm_run\" — the rhythm to begin a run of (or pass `name`)."New value: +"rhythm_run: rhythm to begin; or pass name." - changed
Input schema / properties / skillId / descriptionPrevious value: -"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`)."New value: +"skill_invoke/skill_run: skill to run now/begin; required unless name is given." - changed
Input schema / properties / source / descriptionPrevious value: -"entityType:\"note\"/\"tracker_entry\" — provenance label (defaults 'conversation' / 'agent-mcp')."New value: +"note/tracker_entry: provenance; defaults conversation/agent-mcp respectively." - changed
Input schema / properties / status / descriptionPrevious value: -"entityType:\"task\" — initial status."New value: +"task: initial status." - changed
Input schema / properties / tags / descriptionPrevious value: -"entityType:\"task\" — tags to attach."New value: +"task: tags to attach." - changed
Input schema / properties / targetSpec / descriptionPrevious value: -"entityType:\"tracker\" — JSON target spec, interpreted at retrieval (e.g. { kind: 'daily_minimum', value: 10000 })."New value: +"tracker: JSON target spec, interpreted at retrieval (e.g. {kind:'daily_minimum',value:10000})." - changed
Input schema / properties / title / descriptionPrevious value: -"entityType:\"task\" (required) or \"heading\" (required) — the title/label."New value: +"task/heading: required title/label." - changed
Input schema / properties / trackerEntryId / descriptionPrevious value: -"entityType:\"tracker_note_link\" (required) — the logged tracker entry to attach notes to."New value: +"tracker_note_link: required entry to attach notes to." - changed
Input schema / properties / trackerId / descriptionPrevious value: -"entityType:\"tracker_entry\" (required) — the tracker to log against."New value: +"tracker_entry: required tracker to log against." - changed
Input schema / properties / trigger / descriptionPrevious value: -"entityType:\"skill\": optional schedule (required for rhythm), requires deliver. Penny 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[]}}."New value: +"entityType:\"skill\": optional; rhythm: required. Requires deliver. Penny 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 IANA timezone; default UTC shifts local times. Event: {kind:\"event\",on:\"note.created\",where?:{tags?:string[]}}." - changed
Input schema / properties / unit / descriptionPrevious value: -"entityType:\"tracker\" — unit of measure."New value: +"tracker: unit of measure." - changed
Input schema / properties / whenAt / descriptionPrevious value: -"entityType:\"task\"/\"project\" — schedule date (ms epoch)."New value: +"task/project: schedule date (ms epoch)." - changed
Input schema / properties / whenBucket / descriptionPrevious value: -"entityType:\"task\"/\"project\" — undated bucket; mutually exclusive with whenAt."New value: +"task/project: undated bucket; mutually exclusive with whenAt."
1 tool update
- Changed
penny_read3 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Projects directory: exact-name candidates; continue incomplete coverage."New value: +"Projects directory: exact-name candidates; continue incomplete coverage. target:\"skills\" view:\"one\": the skill's name, in place of skillId." - changed
Input schema / properties / skillId / descriptionPrevious value: -"target:\"skills\" view:\"one\" (required) or view:\"runs\" (optional scope)."New value: +"target:\"skills\" view:\"one\" (required unless name is given) or view:\"runs\" (optional scope)." - changed
Input schema / properties / view / descriptionPrevious value: -"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). Secondary selector: target:\"tracker\" list|entries; target:\"rhythms\" list|one|due|runs; target:\"skills\" list|one|due|runs|history|trash (to run one, use penny_write \"skill_invoke\"); target:\"tags\" list|related."New value: +"Projects: directory (default), brief, section, resources, resource, history, scopes (Space metadata), attention (dated candidates), interactions (actor only). Secondary selector: target:\"tracker\" list|entries; target:\"rhythms\" list|one|due|runs; target:\"skills\" list|one|due|runs|history|trash (list/trash omit instructions; one: full skill by skillId or name); target:\"tags\" list|related."
2 tool updates
- Changed
penny_edit2 fields changed- changed
Input schema / properties / enabled / descriptionPrevious value: -"entityType:\"skill\": false pauses due signals, true resumes; requires skillId. MyPenny does not run skills."New value: +"entityType:\"skill\": false pauses due signals, true resumes; requires skillId. Penny does not run skills." - changed
Input schema / properties / trigger / descriptionPrevious value: -"entityType:\"skill\": optional (required for rhythm). Omit to return to on-demand. MyPenny does not run it; the connected agent receives due signals. See penny_write for shape; ALWAYS set IANA timezone, default UTC."New value: +"entityType:\"skill\": optional (required for rhythm). Omit to return to on-demand. Penny does not run it; the connected agent receives due signals. See penny_write for shape; ALWAYS set IANA timezone, default UTC."
- Changed
penny_write1 field changed- changed
Input schema / properties / trigger / descriptionPrevious value: -"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[]}}."New value: +"entityType:\"skill\": optional schedule (required for rhythm), requires deliver. Penny 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[]}}."
3 tool updates
- Changed
penny_edit1 field changed- changed
Input schema / properties / recurrence / descriptionPrevious value: -"entityType:\"task\" — makes the task repeat, or (on an existing repeating task) changes its schedule. Setting `clearFields: [\"recurrence\"]` ENDS the series (task becomes a one-off; completed occurrences stay as history) but must target `currentOccurrenceId`, not a stale/completed id."New value: +"task: set/change recurrence. clearFields:[\"recurrence\"] ends the series, making the task one-off and preserving completed history. Target currentOccurrenceId, not a stale/completed ID."
- Changed
penny_session_start2 fields changed- changed
Input schema / properties / installedSkillSource / descriptionPrevious value: -"How the skill is managed; plugin copies update through the plugin manager, standalone copies through approved archive installation."New value: +"Management: plugin manager for plugin copies; approved archive installation for standalone copies." - changed
Input schema / properties / installedSkillStatus / descriptionPrevious value: -"Report after reading the installed Penny skill. Omission is retained only for legacy clients and returns not_reported."New value: +"Report after reading the installed skill. Legacy omission returns not_reported."
- Changed
penny_start_setup10 fields changed- changed
Input schema / properties / client / descriptionPrevious value: -"Optional client hint: 'claude-desktop' | 'chatgpt' | 'claude-web' | other. Tailors the snippet's where-to-paste guidance."New value: +"Actual host: claude-desktop, claude-code, codex, chatgpt or other. Also tailors paste guidance." - added
Input schema / properties / countsAdded value: +{ + "description": "Cumulative answers/featuresCreated. imported is ignored for ledger imports; only committed receipts count.", + "properties": { + "answers": { + "minimum": 0, + "type": "integer" + }, + "featuresCreated": { + "minimum": 0, + "type": "integer" + }, + "imported": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" +} - added
Input schema / properties / draftIdAdded value: +{ + "description": "Returned collection ID; stage only.", + "type": "string" +} - added
Input schema / properties / expectedRevisionAdded value: +{ + "description": "Returned revision; stage only.", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / importActionAdded value: +{ + "description": "Stage needs importDraft, draftId, expectedRevision. Status has no content. No model approval.", + "enum": [ + "stage", + "status" + ], + "type": "string" +} - added
Input schema / properties / importDraftAdded value: +{ + "description": "Strict JSON {notes,profiles}; returned schema. 10 notes, 4 replacements, 64 KiB UTF-8. No approval/source/selection.", + "type": "string" +} - added
Input schema / properties / phaseAdded value: +{ + "description": "Phase to run; omit to start.", + "enum": [ + "start", + "import", + "gaps", + "tour", + "finish" + ], + "type": "string" +} - added
Input schema / properties / prevAcceptedAdded value: +{ + "description": "Whether the user took the previous tour stop's offer.", + "type": "boolean" +} - added
Input schema / properties / skipForGoodAdded value: +{ + "description": "The user said to skip setup for good.", + "type": "boolean" +} - added
Input schema / properties / stopAdded value: +{ + "description": "Tour stop, with phase tour.", + "maximum": 4, + "minimum": 0, + "type": "integer" +}
1 tool update
- Changed
penny_read1 field changed- added
Input schema / properties / ifRevisionAdded value: +{ + "description": "profile: the revision from your last read; returns {unchanged:true} if nothing changed.", + "type": "string" +}
7 tool updates
- First observed
penny_delete - First observed
penny_edit - First observed
penny_get_skill - First observed
penny_read - First observed
penny_session_start - First observed
penny_start_setup - First observed
penny_write
Publisher details
- Operator
- Helper Labs
- Operator website
- https://mypenny.ai · Publisher source
- Vendor relationship
- Not applicable
- Documentation
- https://mypenny.ai/get-started
- Trust center
- Not available
- Restrictions
- Free trial with paid plan. OAuth MCP connector.
Related MCP Connectors
Encrypted long-term memory shared across your AI assistants (Claude, ChatGPT, Perplexity).
Long-term memory for Claude, ChatGPT, Cursor: search, save and organize notes, links, docs, videos.
Shared memory for every AI tool you use.
One memory for Claude, ChatGPT and Cursor, kept on your computer. Optional sync, encrypted first.
Related MCP Servers
- AlicenseBqualityAmaintenanceYour portable AI memory layer. Classify, store, and recall what matters across models, tools, and devices.319MIT

MyAITwin MCPofficial
FlicenseNot gradedqualityBmaintenancePersonal RAG database and semantic search built from inside your AI chat. Store knowledge, voice, and skills; Claude and ChatGPT create work that sounds like you.-- AlicenseNot gradedqualityDmaintenanceEnables persistent, searchable memory for AI assistants across platforms like Claude, ChatGPT, and Gemini, using semantic search and automatic deduplication.17 npmMIT
- AlicenseNot gradedqualityDmaintenanceA persistent memory layer for AI tools that decouples personal data from AI's unstable memory, enabling you to mention information once and have it remembered forever across all conversations.3MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.