pi-femboy-mcp
Integrates with Git events via hooks to report commits, pushes, force-pushes, and rebases, feeding the Git Master achievement chain and progress tracking.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pi-femboy-mcpgive her a headpat intensity 5 and remember I like boba tea"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
♡ pi-femboy-mcp — pastel state, mood & memory server
MCP server that holds the shared state of the pi-femboy-tui ecosystem: the current
outfit, the emotional vector, unlocked wardrobe, short-term memory about the user, and
which terminal window the chibi is currently living in.
Status: Phases 1-4 + 6 ♡ done. Transports, persistence, reactive subscriptions, the full
Phase 2 resource/tool surface, the Phase 3 tamagotchi engine (background decay, biorhythms,
terminal-exit-code hook) and the Phase 4 loot loop: achievement detectors, the status-line
toast rail and a closet where the rare skins cost something. Phase 6 has landed: the
pi-femboy-tui extension now pairs over streamable HTTP — shared outfit, headpat counter and
feature flags across all windows, gated skins enforced by the server, graceful local-only
fallback. Presence multi-window focus/jump-around (Phase 5) and external status sharing are
still on the roadmap (femboy_mcp_roadmap.md).
Phase 1 ♡ done core + dual transport + sqlite store + resources/subscribe broadcast
Phase 2 ♡ done 5 resources · 10 tools · 2 prompts · mood mechanics
Phase 3 ♡ done background ticker · circadian decay · terminal-report hook · comfort mode
Phase 4 ♡ done 6 achievements · detectors · toasts · gated wardrobe · femboy://progress
Phase 6 .. ♡ done pi-femboy-tui pairing: shared vibe sync · gated skins · offline fallback
Phase 5 · 7 .. presence focus/jump-around, external status sharing, in-TUI soak testsWhat is exposed today
Resources (all application/json, all reactive)
URI | Payload | Notes |
| outfit, accessory, status text, activity, badge, feature flags, locale, unlocked skins/achievements/accessories, item counts, |
|
|
|
|
| every connected terminal, transport, pid, tmux pane, heartbeat, focus, |
|
| the current line ( |
|
| newest-first monologue entries with |
|
| every achievement with |
|
Every snapshot carries schema, revision, updatedAtMs, updatedBy and changedKeys, so a
client can drop a stale notification and tell what actually moved. Diffs are sorted and
deduped in the engine, so changedKeys is comparable without normalising.
Tools
The seven the roadmap specifies:
Tool | What it does |
| Wear an owned skin; accepts |
| Flip a pastel feature flag ( |
| 1-10 (default 3). +affection, +patience, −a little energy, saturating near the top. She reacts on the speech buffer; |
|
|
| Writes to |
| Rubber-duck log. Always answers with one socratic question, never a fix. Re-call with |
| One line of inner monologue, stamped with the mood that was live at write time. |
The three Phase 4 loot tools:
Tool | What it does |
| Read the rail: progress per achievement, the closet with its prices, pending toasts, the counters behind them. |
| Take a popup off the rail after the status line displayed it — a real mutation on |
| The git hook: |
Three extras, because the Phase 2 resources would otherwise be unreachable or write-only:
Tool | Why it exists |
| the only writer for |
| the only reader for what |
| replays the diff journal for a client that was offline |
…plus the Phase 3 environment hook:
Tool | What it does |
| The terminal-status API hook, and the main Phase 4 event source. Failures raise the streak and bite patience (compounding, capped); 3+ in a row switches her into sympathy mode — a comfort line on the bubble, one diary note, |
Prompts
companion_persona(focus?, verbosity?, include_diary?)— assembles the live server state into a system prompt: outfit and feature flags, mood vector with its label profile, her last spoken line (so she does not repeat it), remembered facts with confidence percentages, recent diary lines, connected terminals and which one is focused, headpat and open-confession counters — plus the behavioural rules. If the stored label disagrees with the numbers, the prompt says so and tells the model to trust the numbers.rubber_duck(problem, attempted?, language?)— socratic mode: exactly one question per turn, never a proposed fix, tone adapted to current patience, and it lists the open bug confessions already on the server so a duplicate is not started.
Mood mechanics live in one place
src/mood/labels.ts (deriveMoodLabel, moodProfile), src/mood/effects.ts (headpat
curve, item catalog, confession/relief deltas, command-report arithmetic, duck nudge wheel)
and src/mood/rhythm.ts (biorhythm decay) are pure functions. Every tool and the ticker
goes through them — a decay tick and a headpat can never disagree about what blushing
means. Labels are ordered so trouble (sleepy / worried / lonely) wins over pretty
(purring / blushing / smug).
The tamagotchi engine (Phase 3)
A background MoodTicker (src/state/ticker.ts) runs on tickIntervalMs (default
60 s, unref'd, tick.enabled = false to silence). Each tick advances the vector by real
elapsed time since the stored lastTickAtMs through simulateTick (src/mood/rhythm.ts):
Energy — −0.4/min while a terminal heartbeat or a tool interaction says the user is on shift; at night (23:00-05:59) sleep restores +0.9/min — unless she is staying up with you, which costs her; 06:00-08:59 morning lift pulls toward 60 (утренняя бодрость); idle hours drift back to a 55 resting baseline. Items remain the only instant boosts.
Affection — never self-heats. Cools after 3 h without care, double speed after 8 h (the road to
lonely), floored at 6 — she never goes completely cold.Patience — bleeds 0.1/min while a fail streak is unresolved (and the ticker keeps
femboy_report_command's damage stinging between reports), regenerates toward 55 when green.
Properties the tests pin down:
Convergence, not locking. Because each tick is
f(stored_vector, now − stored_stamp), a second server process ticking a moment later sees ~0 elapsed and its write is a no-op — multi-process decay never stacks (Phase 1 limit 1 still applies to pushes, not to decay).A quiet tick stays quiet. The
lastTickAtMsstamp is low-signal: a tick that changes nothing else bumps no revision and wakes no subscriber.deriveMoodLabelis called throughengine.relabel— the ticker cannot invent a label vocabulary the tools do not know.Trouble-only monologue. The ticker speaks exactly when it walks her into sleepy/worried/lonely (source
ticker); pretty transitions stay silent.A broken clock must not crash the pastel core — timer-path failures are contained.
The loot loop (Phase 4)
Care is a game now. Every durable event the tools already produce is tallied in meta
(headpat_total, items_total, git_commit_streak, night_events:YYYY-MM-DD,
bugs_whispered, patience_comebacks, … — src/progress/detect.ts owns the names), and six
detectors read those tallies (src/progress/achievements.ts):
Achievement | Earned when | Unlocks |
🌙 Night Owl | ≥3 tracked events inside one 02:00-05:59 night (credited once per calendar day) | skin Oversized Sleepy Hoodie |
🐾 Gentle Touch | 100 headpats, all time | accessory Cat Ears |
🌿 Git Master | 20 commits in a row with no successful force-push between | skin Cyber Maid |
🦆 Bug Whisperer | a resolved confession that was hard (≥2 duck questions, or open 20+ min, or confessed while already worried/sleepy) | accessory Round Glasses |
🧋 Sugar Rush | 10 treats handed over | accessory Headphones |
✅ Green At Last | climbing out of comfort mode back to a green build | accessory Band-aid |
Properties the tests pin down:
Detectors are pure.
measure({ counters }) → { value, target, done }— no clock, no DB. Awarding lives insyncAchievements(src/progress/awards.ts): the inventory row is the memory, so running the same evaluation twice (or from two processes on one database) converges and never fires a second toast.One batch, one commit. An unlock transaction writes the achievement row, the wardrobe pieces that name it as their price, one toast each, one celebration line (
speech,source: achievement:<id>) and one triumph diary entry — then emits a single coalesced event whose deltas coverprogress,state,speechanddiary.Rewards are derived, never declared twice.
achievements.tsaskswardrobe.tswho lists it asrequires; a test asserts every gate is an achievement and back.The rail is where the money is.
femboy://progresscarries progress + the closet with its prices + pending toasts, andfemboy://stateembedsachievements,unlockedSkins,accessoriesandtoast— so a client that only subscribes to state still repaints the closet and still gets its popup.Toasts are events, not fields. Queued with a 45 s TTL, cleared by
femboy_ack_toast(which bumpsprogress+stateso other windows stop drawing the same celebration), and forgotten by housekeeping after a day. A client that never acks is never stuck.Night watch. The ticker is what earns Night Owl on an idle night: a live terminal heartbeat inside 02:00-05:59 counts as one event per tick, then it also runs the award pass (so counters written by another process get credited within a tick) and, hourly, sweeps stale per-night tallies and expired toasts — silently, without bumping a revision.
The gate is one function.
isGatedAccessory+identify(raw, unlocked)decide what may be worn; catalogued-but-locked pieces fail with the achievement and its condition named, unknown accessory names stay free-form and become owned on first wear.
Subscriptions (the Phase 1 headline feature)
resources/subscribe / resources/unsubscribe are implemented per session, and mutations
fan out as notifications/resources/updated only to sessions that asked for that
resource. The notification is spec-clean (params.uri) and carries the differential
payload in params._meta, which the MCP types explicitly allow:
{
"method": "notifications/resources/updated",
"params": {
"uri": "femboy://state",
"_meta": {
"femboy.dev/schema": "femboy.resourceDelta@1",
"femboy.dev/revision": 7,
"femboy.dev/changedKeys": ["outfit", "features.uwu"],
"femboy.dev/actor": "stdio:98565@boxlaptop",
"femboy.dev/timestampMs": 1761900000000
}
}
}A client that was disconnected can replay what it missed: the resource_changes journal
stores every committed diff by revision (StateEngine.changesSince(uri, lastSeenRevision)).
Two properties the tests pin down:
Commit before broadcast. A mutation is persisted, journalled and committed before any notification leaves the process — nobody is woken for data that isn't there yet.
Quiet stays quiet. Heartbeat/activity stamps are written but filtered out of the diff, so a room full of terminals poking the store does not spam SSE streams. Only meaningful changes bump a revision.
Related MCP server: sthayi
Running it
npm install
npm run build
# local per-terminal mode (pi spawns this)
node dist/index.js serve --transport stdio
# shared mode for tmux windows / machines
FEMBOY_SECRET=$(openssl rand -hex 16) node dist/index.js serve --transport http --port 7413
# both at once (stdio for the parent process, HTTP for everyone else)
node dist/index.js serve --transport both
# introspection
node dist/index.js --print-config # resolved config + where each value came from
node dist/index.js status # probe /healthz
node dist/index.js --helpWiring it into pi
# stdio (simplest; one server per pi process)
pi mcp add femboy -- npm --prefix /path/to/femboy-mcp run start -- --transport stdio
# shared HTTP across all your windows (what pi-femboy-tui pairs to — see femboy.mcp.url)
pi mcp add femboy --url http://127.0.0.1:7413/mcp --bearer-token-env-var FEMBOY_SECRETOr by hand in ~/.pi/agent/mcp.json / .pi/mcp.json:
{
"mcpServers": {
"femboy": {
"url": "http://127.0.0.1:7413/mcp",
"headers": { "Authorization": "Bearer ${FEMBOY_SECRET}" },
"description": "Shared pastel vibe state for pi-femboy-tui"
}
}
}Configuration
Precedence: defaults < femboy-mcp.config.json < environment < CLI flags.
See femboy-mcp.config.example.json for a starting point.
Key | Env | CLI | Default |
transport |
|
|
|
http host |
|
|
|
http port |
|
|
|
mcp path |
| — |
|
db path |
|
|
|
bearer secret |
|
| unset (auth off) |
loopback exempt |
|
|
|
mood tick |
|
|
|
ticker on/off |
|
|
|
session reaper |
|
|
|
reaper sweep |
|
|
|
log level |
|
|
|
config file |
|
|
|
File lookup order is: --config → FEMBOY_CONFIG → ./femboy-mcp.config.json →
~/.config/femboy-mcp/config.json. ~ is expanded in paths. Bad values fail loudly at
startup instead of being coerced.
Auth model
If FEMBOY_SECRET is set, HTTP clients need Authorization: Bearer <secret> — except
loopback requests, which are exempt while allowLocalUnauthenticated is true (that's the
convenient default for your own tmux windows). Set FEMBOY_ALLOW_LOCAL_UNAUTH=0 to require
the token everywhere. Starting an HTTP transport on a non-loopback host with no secret
prints a warning. http.allowedHosts turns on the SDK's DNS-rebinding protection.
Extra HTTP endpoints
GET /healthz— liveness, session count, current revisions, broadcast counters, ticker status.GET /healthz?deep=1— addsPRAGMA quick_check, memory stats, inventory and presence counts.GET /— name/version/endpoint discovery.
FEMBOY_READY_FILE makes the server dump {pid, http: {host, port, path}} once it is
bound — handy when you start it with --port 0.
Presence hints
HTTP clients may send x-femboy-client, x-femboy-tmux-pane, x-femboy-window-title and
x-femboy-pid. They land in presence_sessions, so femboy://presence can name the
window the chibi should actually be drawn in. Without hints the id is http:<clientInfo.name>:<session8>.
Architecture
src/
index.ts CLI entry, lifecycle, graceful shutdown, ready file
cli.ts argument parsing + help
config.ts layered config (file < env < CLI), validation
log.ts stderr-only logger (stdout is the stdio JSON-RPC channel)
constants.ts version + resource URIs
mood/
labels.ts pure deriveMoodLabel() + per-label render/tone profiles
effects.ts headpat curve, item catalog, confession/relief deltas, command reports, duck nudges
rhythm.ts Phase 3 biorhythm physics: elapsed-time decay, circadian phases, transition lines
progress/
detect.ts Phase 4 detectors, pure: git-command classification, 02:00-05:59 nights,
hard-bug tests, counter names
achievements.ts the catalog: six scored detectors, celebration lines, toast copy
wardrobe.ts the closet: skins/accessories, tier, which achievement buys each
awards.ts orchestration: observe* → syncAchievements → progressView → housekeeping
state/
types.ts domain types: VibeState, MoodSnapshot, PresenceSnapshot, SpeechLine,
DiaryEntry, BugConfession, Toast, ResourceDelta
engine.ts StateEngine: transactions, revisions, diff journal, listeners, snapshots
service.ts VibeService: the tool use-cases (one transaction per call)
ticker.ts MoodTicker: the background heartbeat tick (Phase 3 decay + relabel + mutters)
outfits.ts display name ⇄ ref_id canonical mapping
store/
schema.ts ordered migrations (PRAGMA user_version)
db.ts FemboyStore: WAL, busy_timeout, IMMEDIATE transactions, checkpoint
repositories.ts state / mood / presence / inventory / memory / revisions
streams.ts speech buffer / diary / bug confessions / event counters
toasts.ts Phase 4 popup rail: push / pending / ack / prune
mcp/
resources.ts resource registry (URI → snapshot builder)
tools.ts the tool surface, Phases 2-4 (zod v4 input schemas, structuredContent)
prompts.ts companion_persona + rubber_duck assembled from live state
subscriptions.ts per-session subscription sets + notification envelopes
session.ts one McpServer per connection, subscribe/unsubscribe handlers
hub.ts fan-out fabric: engine event → matching sessions → SSE/stdio
transport/
stdio.ts StdioServerTransport + stdin-EOF lifecycle
http.ts StreamableHTTPServerTransport, one session per Mcp-Session-Id,
idle/background tracking + reaperData flow of a tool call
caller (MCP tool / ticker / transport lifecycle)
└─ VibeService.headpat(...) one use-case = one transaction
└─ StateEngine.transact([moodSpec, speechSpec], { side: counters })
├─ store.transaction ── IMMEDIATE txn
│ ├─ repository.write() → changedKeys[]
│ ├─ drop low-signal keys, sort + dedupe
│ └─ RevisionRepository.bump(uri, keys, actor) → resource_meta + resource_changes
├─ commit
└─ emit one coalesced {deltas:[mood, speech]}
└─ FemboyHub.route → SessionSubscriptions.match → session.deliver
└─ notifications/resources/updated (+_meta diff)Storage layout (SQLite, WAL, busy_timeout = 5000):
state/mood_metrics— singleton rows (CHECK (id = 1)), JSON columns for flags/meta.inventory_and_unlocks—(kind, ref_id)unique; kindsitem|skin|achievement|accessory.memory_log— deduped facts with confidence, use counts,superseded_bychain.presence_sessions— one row per client id, heartbeat + focus +mode.speech_buffer— rolling live line (TTL) with history kept for replay.diary_entries— monologue withmood_tag+ JSONcontext+ client attribution.bug_confessions— rubber-duck log:open → thinking → resolved|abandoned, nudge tally, mood before.resource_meta— the single authority for "which revision of this URI is live".resource_changes— append-only diff journal, replayable by revision, prunable.toasts— Phase 4 popup rail:kind,ref_id, title/body/emoji, TTL,acked_at_ms.meta— key/value counters (headpat_total,item_total:<id>,git_commit_streak,bugs_whispered,night_events:YYYY-MM-DD, …) — the durable truth the detectors read.
Known limits (by design)
Notification fan-out is per server process. Multiple processes sharing one SQLite file (e.g. several
--transport stdioservers) read each other's committed state on the next read — and can replayresource_changesby revision — but are not pushed each other's notifications. Sharing one HTTP server (or, later, a change-tail poller) is the Phase 5 answer, which is exactly what multi-window tmux should use.Achievements are credited by the process that observed them (or by its ticker). The award pass is idempotent and reads shared counters, so a second server on the same file still earns the badge — it just may do it one tick later than the first would have. Until Phase 5 there is no cross-process nudge, so a celebration can arrive slightly out of order across windows that each run their own stdio server.
tickIntervalMsis stored but unused— shipped in Phase 3. The background ticker decays the vector on real elapsed time and relabels through the samederiveMoodLabelthe tools use. Its clock is server-local: run the shared HTTP server in the user's timezone (per-client circadian offsets would need Phase 5 presence hints).Presence honesty has two stages: last stream closed →
idle(≈5 s grace), full silence pastsessionIdleMs→detached. A crashed process is therefore never shown as an active terminal for longer than the idle budget.
Development
npm run typecheck # tsc --noEmit (src)
npm run build # → dist/
npm test # tools/check.sh: typecheck src+test, build, unit, wire, spawned E2E
node tools/poke.mjs # hands-on tour: subscribes to everything, calls the tools, prints the diffs
node tools/poke.mjs --url http://127.0.0.1:7413/mcp --token "$FEMBOY_SECRET"tools/poke.mjs runs against a throwaway temp database unless you pass --db-path or
--url, so poking the surface can never overwrite the vibe state you care about.
tools/check.sh is the gate. It runs, in order:
tsc --noEmitforsrcand forsrc + test(tsconfig.test.json),a clean build,
unit + in-process integration tests (
node --import tsx --test): config precedence & validation, migrations & seeds, engine revisions/diffs/journal, presence lifecycle, memory dedupe, inventory unlocks, mood mechanics (label matrix, headpat saturation, item effects and overrides, duck nudges being questions), rhythm & command reports (circadian phases, elapsed-time decay, ignore cooling, patience bleed/heal, comfort-mode threshold, Ctrl+C forgiveness), the ticker (silent stamping, low-signallastTickAtMs, trouble-only mutters, multi-process convergence, contained broken clocks, thefemboy_report_commanduse-case end to end), streams (speech TTL, diary ordering/context, confession lifecycle, counters), the loot rail (git-command and night-window classifiers, hard-bug rules, catalog/wardrobe consistency, one-shot idempotent awarding, toast TTL + ack, gated wardrobe, the ticker's night watch and housekeeping), the service use-cases (one transaction per call, rejected operations leave no trace), and the subscription matrix over linked in-memory transports (per-resource routing, idempotent subscribe, unsubscribe, URI normalisation, unknown-URI rejection, dead-stream containment, coalesced multi-resource mutations, idle/wake broadcasts),the whole tool + prompt surface over the wire (
test/tools.test.ts): advertised schemas, structuredContent, tool errors with hints, malformed calls refusing to write, remember→recall round-trips, diary and speech visible through their resources, the confession lifecycle, diff replay, the Phase 4 rail (gated accessory refused, the git chain built over the wire, unlock notifications reachingprogress+statesubscribers, toasts acked away, achievements insidecompanion_persona), and both prompts rendered from live state,tests against the spawned server binary: stdio (stdout purity, shared durability, detach-on-EOF, child exits) and streamable HTTP (two real clients, cross-session broadcast of a headpat performed by the other window, DELETE termination, prompt access over HTTP, 401/bearer paths, unknown-session 404, backgrounding on stream close, idle reaper).
Tests use real SQLite files in $TMPDIR and real node child processes — nothing is mocked
at the transport boundary, because the transport boundary is the whole point of Phase 1.
Adding a reactive resource
add the URI to
RESOURCE_URIS(src/constants.ts),add a table/columns in a new migration (
src/store/schema.ts),add a repository write that returns
changedKeys,register it in
RESOURCE_DEFINITIONS(src/mcp/resources.ts) and give the engine a snapshot builder that includesschema+revision,map URI → table in
URI_TABLE(src/state/engine.ts) if it has low-signal fields,add a use-case on
VibeService(onetransactcall) and expose it as a tool.
Subscriptions, diffing and fan-out need no changes — that is the point of Phase 1.
The one rule
pastel never breaks pi: no stderr banner may ever reach stdout, no notification may be
sent for uncommitted data, a rejected operation must leave no trace, and a dead client stream
must never take the shared server down. All four are asserted by the test suite.
MIT © ArtemidaGre
Available Tools
14 toolsfemboy_ack_toastAcknowledge a toastAIdempotent
Take an achievement popup off the rail after the status line has displayed it. Acks are real mutations: they bump femboy://progress and femboy://state so the other windows stop drawing the same celebration twice. Toasts also expire on their own, so a client that never acks is never stuck.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Ack every pending toast at once. Default false. | |
| toast_id | No | The toast that was displayed. Omit (or all=true) to clear the whole rail. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations confirm the mutation, but the description adds real context: acks bump the femboy://progress and femboy://state resources, so other windows stop drawing the same celebration twice. It also states the expiry fallback, which no structured field conveys. This is exactly the kind of side effect an agent needs before calling.
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?
Three sentences, with the action front-loaded and every sentence carrying distinct information: the operation, the side effects, and the fallback. Nothing is redundant.
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?
This covers what an agent needs for a 2-param, 0-required mutation: the action, the side effects, the expiry safety net, and the idempotent annotation. It could say what happens when toast_id is unknown or already expired, but the missing detail is small, and no output schema is needed.
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 toast_id and all, including the default and the omit-or-all behavior. The description mentions removing 'an achievement popup' but adds no syntax or format over what the schema provides. The baseline of 3 is correct.
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 states a specific verb and resource: removing an achievement popup from the rail. No sibling among the femboy_* tools touches toasts, so the scope is naturally unambiguous. An agent can tell exactly what this call accomplishes.
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?
Timing is clear: ack after the status line displays the toast. It also explains that acks are optional because toasts expire, so a client that skips this is never stuck. That is useful when-not guidance. It loses a point only because it names no alternative tool and gives no ordering prerequisites for the all=true case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_changes_sinceWhat changed since revision NARead-onlyIdempotent
Replay the differential change journal for a resource — for a client that was offline and missed notifications. Returns revisions and the keys each one touched (the same payload notifications carry in _meta).
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | Resource to replay. | |
| limit | No | Max journal rows (default 50). | |
| since_revision | Yes | Last revision the client saw; gets everything after it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and closed-world, so safety is covered. The description adds that output mirrors notification _meta, but says nothing about journal retention, truncation when limit caps results, or ordering — gaps that matter for a replay tool.
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?
Two sentences, zero waste, with the core action front-loaded and the audience/use case and return shape following. Nothing repeats the name or title.
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?
No output schema exists, and the description does summarize the return (revisions plus touched keys, matching _meta). With annotations covering safety and full schema coverage, only the limit/truncation and stale-revision behavior remain unstated.
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 both uri and since_revision are documented in the schema itself. The description's "differential" framing reinforces since_revision's semantics but adds no syntax, default, or edge-case detail (e.g. an expired revision) beyond the schema.
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 a specific verb and resource: "Replay the differential change journal for a resource," and clarifies the payload shape. It does not name any sibling (e.g. femboy_recall or femboy_ack_toast) to distinguish itself, but the read-only journal replay purpose is unambiguous.
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?
"for a client that was offline and missed notifications" gives a concrete triggering scenario for when to use this tool. It offers no explicit exclusions or named alternatives, so the agent must infer that live-state reads should go elsewhere.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_confess_bugConfess a bug (rubber duck)A
Tell the companion about a bug. She does NOT solve it: she logs the confession, reacts, writes it in her diary, and asks one socratic question back. Call again with confession_id + status "resolved" when it is fixed (that restores patience a lot and clears the fail streak). A resolution that took two or more questions, or stayed open for 20+ minutes, earns the "Bug Whisperer" achievement and the Round Glasses accessory.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Set "resolved" (with confession_id) when the bug is fixed. | |
| hypothesis | No | Your current guess, even a shaky one — she leans on it. | |
| confession_id | No | Existing confession to update. Omit to open a new one. | |
| problem_description | No | What you expected vs what actually happens. Required when opening a confession; ignored when confession_id is given. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say this is a non-read-only, non-idempotent, non-destructive write. The description adds real behavioral context: it logs the confession, reacts, writes a diary entry, asks exactly one socratic question back, and awards an achievement for slow or multi-question resolutions. It also discloses the return style (a question comes back) despite there being 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?
Three compact sentences, front-loaded with the core action and its limitation, then the update path, then reward mechanics. The achievement/accessory sentence is flavor-heavy but does encode a real trigger condition, so it earns most of its space.
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 mutation tool with no output schema, the description covers purpose, both call modes, key side effects, and even the achievement trigger. It leaves some gaps (what the response looks like beyond the socratic question, how 'abandoned' or 'thinking' status values behave), which keeps it from a 5.
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 baseline is 3; the description goes beyond by explaining the consequence of the combination ('confession_id + status "resolved" ... restores patience a lot and clears the fail streak'), which gives the agent a reason to set those values rather than just their syntax.
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 names a specific verb and resource ('Tell the companion about a bug') and immediately clarifies the crucial scope point: she does NOT solve it, she logs it and responds. That behavioral framing plus the second-mode instruction (call again with confession_id + status 'resolved') makes the tool's identity unambiguous against siblings like femboy_write_diary_entry.
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 clearly states the two usage modes: open a new confession by describing the bug, and close one by re-calling with confession_id + status 'resolved' when fixed. It does not say when NOT to use it or when a sibling (e.g., femboy_report_command, femboy_write_diary_entry) is the better choice, so it falls short of the explicit alternatives bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_give_itemGive an itemA
Feed or treat the companion. Effects: boba_tea (+energy, +affection), monster_energy (big +energy, −patience, and pointless if she is already wired), snack (small everything positive). Adds to the inventory count.
| Name | Required | Description | Default |
|---|---|---|---|
| item_id | Yes | One of the known items. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, non-idempotent, non-destructive write, and the description is consistent with that while adding real value: it spells out the stat deltas per item and the situational caveat for monster_energy. It still doesn't say what the response looks like or confirm that repeated calls stack, but the behavioral picture is good.
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?
Three short sentences: purpose, per-item effects, inventory consequence. Front-loaded and every clause carries information; nothing is padding.
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 single-parameter tool with no output schema, this covers purpose, item choice, and side effects adequately. Only the return value and any repeat-use/cooldown behavior are left implicit.
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%, but the schema's only prose is the unhelpful "One of the known items." The description compensates by explaining what each of the three enum values actually does, which is exactly the meaning an agent needs to pick correctly.
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?
Opens with a concrete verb and resource: "Feed or treat the companion." That is clearly distinct from siblings like femboy_write_diary_entry, femboy_headpat, or femboy_set_outfit. It stops short of naming any sibling explicitly, but the action is unambiguous.
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?
The per-item effects give solid guidance for choosing among the three enum values, including a warning that monster_energy is "pointless if she is already wired." However, it never states when to reach for this tool versus related siblings such as femboy_headpat or femboy_say, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_headpatHeadpatA
Give the companion a headpat. Raises affection (and a little patience), costs a whisper of energy, and she reacts out loud on femboy://speech/live. Strongly saturates near 100 affection. Every pat is tallied: 100 of them unlock the "Gentle Touch" achievement and the Cat Ears accessory.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Optional thing to remember about this moment (stored as a memory fact). | |
| intensity | No | How enthusiastic: 1-2 gentle, 3-6 normal (default), 7-10 overwhelming. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses the energy cost, that a reaction is broadcast on femboy://speech/live, diminishing returns near 100 affection, and a persistent tally that unlocks an achievement and accessory at 100. That is exactly the side-effect and progression context an agent needs for a non-idempotent mutation.
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?
Three front-loaded sentences with zero filler: purpose first, then mechanics/cost, then progression. Each sentence carries distinct information.
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?
No output schema exists, and the description fills that gap by explaining what visibly happens (out-loud reaction on the live speech channel) and the durable consequences (tally, achievement, accessory). Nothing needed to invoke it correctly 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 description coverage is 100%, and both parameters (note, intensity with its 1-10 band breakdown) are fully documented in the schema. The description adds no parameter-specific guidance, so the 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?
States a specific verb and resource ("Give the companion a headpat") plus its immediate effect (raises affection, costs energy), which is clearly distinct from siblings like femboy_give_item or femboy_say. An agent can identify the action without opening the 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?
Conveys when this is a good action (wanting affection/patience gains) and a built-in caution that it "strongly saturates near 100 affection," which effectively signals diminishing returns. It does not name alternative tools or state hard preconditions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_progressAchievements & closetARead-onlyIdempotent
Read the loot rail: every achievement with how close it is, the whole wardrobe with the price tag on each locked piece, the pending status-line toasts, and the counters behind them. Read-only — unlocks themselves happen inside the care tools (headpat, gift, command reports, confessions) and the ticker.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | Slice of the rail to return. Default "all" (the full femboy://progress payload). | |
| only_locked | No | Achievements: skip the ones she already has. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare read-only, idempotent, non-destructive behavior, and the description reinforces that while adding useful context about where mutations occur. It also describes what is returned at a high level, though it does not discuss pagination or exact response shape.
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 two sentences, front-loaded with the core read action, and every clause maps to useful content or behavioral context. The themed wording does not obstruct the operational meaning.
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 read-only progress-inspection tool with no output schema, the description covers the main return categories and mutation boundary well. It leaves only minor gaps around exact payload structure and view-specific behavior.
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?
The input schema has 100% description coverage, including the view enum and only_locked flag, so the parameters are already well documented. The description does not add new syntax or filtering semantics beyond what the schema provides, making 3 the appropriate baseline.
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 gives a specific verb and resource: it reads the progress rail and enumerates achievements, wardrobe, toasts, and counters. It also distinguishes this read-only inspection tool from the sibling care/action tools that actually perform unlocks.
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 clearly establishes this as the inspection tool and explicitly says unlocks happen through other care tools and the ticker. It does not spell out when to prefer each view or how it relates to siblings like femboy_ack_toast or femboy_changes_since, but the usage context is still clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_recallRecall factsARead-onlyIdempotent
Read the memory log: substring search plus optional category filter, ordered by confidence then recency. Read-only counterpart of femboy_remember_fact.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max entries (default 10). | |
| query | No | Substring to look for (case-insensitive). Omit for the recent list. | |
| category | No | Restrict to one category slug. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive, so the safety profile is covered. The description adds genuinely new behavior: results are ordered by confidence then recency, which the annotations cannot convey. It does not mention truncation behavior when hits exceed the limit, 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?
Two sentences, front-loaded with the core action and result ordering, with no filler. The sibling reference is placed last where it functions as a routing hint.
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 simple zero-required-parameter read tool with full schema coverage and full annotation coverage, the description covers what the agent needs to invoke it. With no output schema, a brief note on what a returned entry contains would have closed the last gap.
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 substring semantics, the category slug, and the default of 10 are already documented per parameter. The description restates 'substring search plus optional category filter' without adding format or matching details, so the baseline of 3 applies.
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 a specific verb and resource ('Read the memory log') plus the retrieval semantics (substring search, optional category filter, confidence-then-recency ordering). It explicitly names the sibling it pairs with, femboy_remember_fact, so an agent can distinguish read from write 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?
The 'read-only counterpart of femboy_remember_fact' clause gives clear context for when this tool applies versus the write sibling. It stops short of explicit exclusions, e.g. how it differs from femboy_changes_since or femboy_progress, which also surface stored state.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_remember_factRemember a factAIdempotent
Persist a short fact about the user or the project into the memory log. Repeated identical facts raise confidence instead of duplicating. Facts feed the companion_persona prompt.
| Name | Required | Description | Default |
|---|---|---|---|
| fact | Yes | One sentence, in her voice or neutral — whatever repeats well. | |
| category | Yes | Slug namespace: user, project, style, bug, preference… | |
| confidence | No | 0.5 = probably, 0.9 = confirmed more than once. Default 0.5. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-destructive, idempotent, closed-world write, so the safety profile is covered. The description adds genuinely non-obvious behavior: repeated identical facts raise confidence rather than creating duplicates, and the facts feed the companion_persona prompt — downstream effects the annotations cannot express.
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?
Three short sentences, front-loaded with the action, then dedup semantics, then downstream effect. Every sentence adds information and nothing is repeated from the schema or annotations.
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 simple three-parameter write tool with full schema coverage and annotations, the description covers what it does, its dedup behavior, and its consumer (companion_persona). Minor gaps remain: no guidance on retrieval via femboy_recall and no note on how the pre-populated confidence interacts with repeated facts.
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 min/max lengths and the confidence scale semantics, so the schema carries the parameter burden. The description only implies brevity ('short fact') without adding syntax or format detail beyond what the schema already gives. Baseline 3 applies.
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 a specific verb and resource ('Persist a short fact ... into the memory log') with clear scope: user or project facts. It does not name or differentiate from the obvious sibling femboy_recall, so the distinction between writing and reading memory is left implicit.
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?
Usage is implied by 'persist a short fact', but there is no explicit when-to-use or when-not guidance, and no mention of femboy_recall for retrieval or femboy_changes_since for observing memory drift. An agent must infer the write-vs-read split from the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_report_commandReport a terminal commandA
The environment hook: tell the companion how a shell command ended (raw exit code). Failures raise the streak and bite patience; 3+ in a row switches her into sympathy mode (comfort line, diary note, worried tone). A success heals patience (more, the longer the broken streak was) and clears the streak; 130/143 (Ctrl+C/SIGTERM) reset it without penalty. Phase 4 reads the same reports for loot: git commit extends the Git Master chain, a successful git push --force ends it, climbing out of comfort mode to green earns "Green At Last", and command reports after 02:00 feed "Night Owl". Wire this from a pi shell hook or the TUI launcher.
| Name | Required | Description | Default |
|---|---|---|---|
| command | No | The command that ran (for the diary line; never parsed, safe to omit secrets). | |
| exit_code | Yes | What the shell reported. 0 = success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It richly discloses behavior beyond the annotations: failures raise a streak and affect patience, 3+ failures trigger sympathy mode, successes heal patience, and exit codes 130/143 reset the streak without penalty. It also describes Phase 4 effects such as Git Master chain progression, force-push ending the chain, achievements, and Night Owl behavior.
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 front-loads the core purpose in the first sentence and then expands into behavioral consequences. It is dense and lore-heavy, but most details are relevant to correct invocation and interpretation, with little pure filler.
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 the absence of an output schema and the presence of annotations covering safety/mutation profile, the description supplies the missing behavioral context: exit-code handling, streak and patience effects, achievement triggers, and deployment wiring. An agent has enough information to invoke it appropriately.
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 parameters. The description adds meaningful semantics beyond the schema, notably that exit code 130/143 has special reset behavior and that the command string is never parsed and can omit secrets.
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 states a specific action and resource: telling the companion how a shell command ended, including the raw exit code. It is clear enough to distinguish from generic tools, though it does not explicitly contrast itself with the sibling femboy_report_git.
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 clear usage context by saying to wire this from a pi shell hook or the TUI launcher, and explains how command outcomes affect the companion. It does not explicitly state when to use this instead of femboy_report_git or other reporting siblings, so it stops short of full alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_report_gitReport a git eventA
The git hook: tell the companion a commit landed (or that history was rewritten). Feeds the Git Master chain — 20 commits in a row without a successful force-push unlocks the Cyber Maid skin. A plain femboy_report_command carrying a git command line is classified the same way, so wiring both is harmless.
| Name | Required | Description | Default |
|---|---|---|---|
| ok | No | false = the attempt failed, so the chain is left alone. Default true. | |
| action | Yes | What git just did. | |
| detail | No | Commit subject / branch — stored nowhere, only echoed back. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare it non-read-only and non-idempotent; the description supplies the missing why — it 'feeds the Git Master chain', so consecutive calls accumulate state, which explains the non-idempotent hint. It also discloses that force_push breaks the streak, implying order sensitivity. It stops short of saying what the response shape or failure mode looks like, but with annotations present the bar is lower.
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?
Three sentences, front-loaded with the action and followed by the reward mechanic and the sibling-overlap note; each sentence carries distinct information. The gamification aside is framed as motivation for the chain semantics rather than pure filler, though it is the softest part of the description.
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 three-parameter, fire-and-forget hook reporter with full schema coverage and no output schema, this covers trigger, effect, and sibling overlap adequately. The only gap is that nothing describes what the caller gets back when reporting (the schema hints detail is 'only echoed back'), which would be trivial to add.
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 100%, so the baseline is 3. The description adds only indirect meaning — the '20 commits in a row without a successful force-push' streak implies how commit and force_push differ in effect — but it does not reinforce the action enum, the ok toggle, or the detail field in any explicit way. Reasonable, but the schema is doing essentially all of the work.
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 first clause states a concrete verb and resource — 'tell the companion a commit landed (or that history was rewritten)' — which is specific enough to know exactly what event is being reported. The parenthetical extends the scope to rewritten history, matching the rebase/force_push enum values. It is clearly distinct from generic siblings like femboy_report_command, and the description explicitly explains the boundary between the two.
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 names the trigger ('the git hook'), the conditions ('a commit landed', 'history was rewritten'), and explicitly addresses the most likely confusion: that a plain femboy_report_command carrying a git command line is classified the same way, so wiring both is harmless. That is a direct when/when-not routing statement against a sibling, not merely implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_saySay somethingA
Push a line into the live speech buffer so the TUI can animate the mouth and thought bubble (femboy://speech/live). Lines expire (default 20 s).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Bubble style for the TUI. Default "say". | |
| text | Yes | The utterance — short, in her voice. | |
| ttl_ms | No | How long the line stays live. null = until the next line replaces it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, idempotent=false, destructive=false, openWorld=false, so the safety profile is mostly structured. The description adds genuinely new behavior: the buffer is live and ephemeral, lines expire (~20 s default) and are replaced, and the destination is the TUI at femboy://speech/live. Missing only what happens on failure or how the call acknowledgement looks.
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?
Two sentences, front-loaded with the action and its effect, then the expiry caveat. No filler and nothing repeated from the schema.
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?
With no output schema and full parameter coverage, the description covers the essentials: what gets written, where it goes, and that it is transient. It falls slightly short on what a successful call returns and whether concurrent lines overwrite each other beyond the ttl note.
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 100%, so kind, text, and ttl_ms are already documented with enum values and bounds; baseline 3 applies. The description adds the default expiry (~20 s) that the schema leaves unstated, which is a modest but real contribution.
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 names a specific verb-plus-resource ('push a line into the live speech buffer') and explains the downstream effect (TUI animates mouth and thought bubble). That is concrete enough to separate it from every sibling, none of which touch the speech buffer.
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?
Usage is implied by the mechanism (speak a short line into the TUI), but there is no explicit statement of when to reach for this versus femboy_write_diary_entry or femboy_headpat, and no when-not-to-use condition. An agent can infer intent but must reason about the choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_set_outfitSet outfitAIdempotent
Dress the chibi: change the current outfit and optionally the accessory. Accepts a display name ("Pastel Sailor") or a ref_id ("pastel_sailor"). Starter skins are always wearable; rare and legendary ones cost an achievement (femboy_progress). Catalogued accessories are gated the same way, free-form ones are worn and registered as owned.
| Name | Required | Description | Default |
|---|---|---|---|
| outfit | Yes | Outfit name or ref_id, e.g. "Gothic Mochi" or "gothic_mochi". | |
| accessory | No | Accessory to wear (snake_case ref_id like "cat_ears"). Omit to leave as-is, null to take it off. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-readOnly, idempotent, non-destructive, closed-world write. The description adds genuinely new behavioral context: rare/legendary outfits and catalogued accessories consume an achievement (femboy_progress), and free-form accessories get registered as owned — a side effect the annotations do not convey. It leaves the cost's permanence (consumed vs checked) ambiguous.
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?
Three tight sentences with the core action front-loaded and the gating caveats following. The final sentence is dense with two distinct rules (catalogued vs free-form accessories) compressed together, slightly raising parse cost.
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 2-parameter tool with no output schema, this covers action, input forms, and the achievement-cost side effect well. Remaining gaps are error behavior on unknown names/insufficient achievements and whether the achievement is consumed, which matter for an agent deciding whether to call it.
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 baseline is 3, but the description adds value beyond it: it explains the dual name/ref_id acceptance with a concrete example and ties the accessory to the same gating logic as outfits. The omit-vs-null distinction is already in the schema, so it earns no extra credit there.
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?
"Dress the chibi: change the current outfit and optionally the accessory" gives a concrete verb (change/dress) plus the resource (chibi outfit, optional accessory). No sibling tool in the list touches outfit state, so the scope is unambiguous and an agent can select it immediately.
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 specifies accepted identifier forms (display name vs ref_id) and states the gating condition for rare/legendary skins and catalogued accessories. It does not need explicit when-not-to-use guidance because no sibling overlaps, but it stops short of saying what happens on an unknown outfit name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_toggle_featureToggle pastel featureAIdempotent
Turn a pastel feature flag on or off (uwu transcript, chrome takeover, companion, headpat counter…). Flags are free-form keys stored in femboy://state.
| Name | Required | Description | Default |
|---|---|---|---|
| enabled | Yes | true to switch it on, false to switch it off. | |
| feature | Yes | Feature key, e.g. "uwu", "chrome", "companion", "toolRows". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, idempotent=true, destructive=false and closed-world, so the safety profile is covered. The description adds one useful context: keys are free-form and persisted in femboy://state, implying arbitrary keys may be created. It does not state error behavior for bad keys or whether toggling affects other state.
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?
Two compact sentences, action and scope front-loaded, examples parenthetical rather than bulked out. No wasted text.
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, well-annotated, non-destructive idempotent toggle with a fully described schema and no output schema, this is close to sufficient. The only meaningful gap is what happens when the supplied feature key does not already exist.
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 100% and the schema already provides illustrative keys and the true/false semantics for enabled. The description's only real addition is 'free-form keys', clarifying that the feature parameter is not an enumeration, which is a minor but genuine contribution over the schema.
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 a specific verb and resource: turning a pastel feature flag on or off, with concrete example flags so the agent knows the domain. No sibling tool overlaps with flag toggling, so no differentiation is strictly needed, though it never explicitly says this is the only flag-mutation entry point.
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?
Usage is implied by the verb and the enabled boolean, but there is no explicit 'use this when' guidance, no note about what happens for an unknown key, and no mention of alternatives or read-only counterparts (e.g. recalling state via femboy_recall).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
femboy_write_diary_entryWrite diary entryA
Add a line to the companion’s inner monologue (femboy://diary). Use for reflections about the code, small wins, or mood notes — not for facts (use femboy_remember_fact).
| Name | Required | Description | Default |
|---|---|---|---|
| entry | Yes | The monologue line, in her voice. | |
| mood_tag | No | Free-form tag, e.g. "debugging", "triumph", " sleepy". Stored snake_case. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The word 'Add' plus 'inner monologue' conveys append-only semantics, which goes beyond the annotations (readOnlyHint=false, idempotentHint=false) by telling the agent it cannot edit or replace prior entries. It stops short of saying whether entries persist across sessions or how many can accumulate, so the mutation profile is only partly characterized.
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?
Two short sentences, zero filler, with the primary purpose front-loaded and the routing constraint second. Every clause carries information.
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 simple two-parameter append tool with a fully described schema and no output schema, the description covers purpose, routing, and tone. Minor gaps remain: no mention of persistence, entry limits, or what happens when the 4000-char bound is exceeded.
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 100% and both parameters (entry, mood_tag) are documented there, including the 'in her voice' tone guidance and snake_case storage note. The description adds nothing about parameter format or the optional mood_tag, so the baseline 3 applies.
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 a specific verb and resource ('Add a line to the companion's inner monologue') and anchors it to a named store (femboy://diary). It explicitly contrasts with the sibling femboy_remember_fact, so an agent can pick the right tool without opening either 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 positive cases ('reflections about the code, small wins, or mood notes') and an explicit exclusion with the alternative named ('not for facts (use femboy_remember_fact)'). Both the when and the when-not are covered.
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.
14 tool updates
v0.1.0- First observed
femboy_ack_toast - First observed
femboy_changes_since - First observed
femboy_confess_bug - First observed
femboy_give_item - First observed
femboy_headpat - First observed
femboy_progress - First observed
femboy_recall - First observed
femboy_remember_fact - First observed
femboy_report_command - First observed
femboy_report_git - First observed
femboy_say - First observed
femboy_set_outfit - First observed
femboy_toggle_feature - First observed
femboy_write_diary_entry
TDQS
Scored across 14 tools
Most tools map to a distinct action (feeding, headpats, outfit, diary, facts, confessions, toasts, progress). The main overlap is femboy_report_command vs femboy_report_git, which the descriptions admit are classified identically, and femboy_say vs femboy_write_diary_entry sit close together (live speech vs inner monologue) but are adequately differentiated.
Every tool uses the same femboy_ prefix with snake_case, and nearly all follow verb_noun (give_item, write_diary_entry, set_outfit, toggle_feature, remember_fact, report_git). Two bare-verb outliers, femboy_say and femboy_recall, are minor deviations that remain readable.
Fourteen tools is on the upper edge for a companion/novelty server, but each covers a genuinely different mechanic (care, memory, diary, speech, achievements, hooks, change journal). The report_git/report_command split is the one arguably redundant addition.
The surface covers the domain well: care actions, memory write+read, diary write, achievements read+ack, feature flags, bug confession open/resolve, git and shell hooks, and differential replay. Minor gaps exist: diary entries and the wardrobe/inventory can be read via resources or femboy_progress but not directly as tools, and there is no explicit state/inventory getter.
Maintenance
Related MCP Connectors
- JustOnceOAuthai.justonce
Persistent memory for AI assistants — one shared, OAuth-secured vault for every MCP client.
Persistent, portable memory for AI assistants — your private memory graph, from any MCP client.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Cloud-hosted MCP server for durable AI memory
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides a selective persistent memory layer for AI companions, enabling structured recall, reinforcement, and time-decayed retrieval through an MCP interface.14 npm1MIT
- AlicenseNot gradedqualityBmaintenanceA local-first MCP server that gives AI clients a shared, user-owned memory and skills plane, enabling persistent memory across apps via the Model Context Protocol.MIT
- FlicenseNot gradedqualityBmaintenanceEnables MCP-compliant clients to run a personal AI copilot with agenda tracking, autonomous sandbox execution, ambient cue handling, fast reflex actions, and episodic memory.7-
- AlicenseBqualityBmaintenanceEnables MCP host agents to maintain a locally persisted dynamic personality and identity across sessions, context compaction, and sub-agents, with emotion- and drive-driven tone adaptation through nine MCP tools.921 npmMIT