Skip to main content
Glama

♡ 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 tests

What is exposed today

Resources (all application/json, all reactive)

URI

Payload

Notes

femboy://state

outfit, accessory, status text, activity, badge, feature flags, locale, unlocked skins/achievements/accessories, item counts, toast + toasts (the live status-line popup), progress (earned/total)

femboy.state@1

femboy://mood

energy / affection / patience vector, label + derivedLabel, labelProfile (emoji/mouth/tone), circadian (hour/phase/tick recency), comfortMode, headpat count, fail streak, interaction recency

femboy.mood@1

femboy://presence

every connected terminal, transport, pid, tmux pane, heartbeat, focus, mode (active/idle/sleeping/detached), activeClientId

femboy.presence@1

femboy://speech/live

the current line (speaking, current) + a short tail of recent lines, TTL-aware

femboy.speech@1

femboy://diary

newest-first monologue entries with moodTag + structured context, byClient, open-confession count

femboy.diary@1

femboy://progress

every achievement with value/target/ratio, its rewards, the whole wardrobe with the achievement that buys each locked piece, counters, and the pending toasts

femboy.progress@1

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

femboy_set_outfit(outfit, accessory?)

Wear an owned skin; accepts "Gothic Mochi" or gothic_mochi. null accessory takes it off. Free-form accessories are worn and registered as owned; catalogued rare ones are gated by an achievement. Refusals name the achievement and the condition (20 commits in a row…).

femboy_toggle_feature(feature, enabled)

Flip a pastel feature flag (uwu, chrome, companion, …). Name is case-normalised; junk identifiers are refused. Diff is per key: features.uwu.

femboy_headpat(intensity?, note?)

1-10 (default 3). +affection, +patience, −a little energy, saturating near the top. She reacts on the speech buffer; note becomes a memory fact; every pat is counted — 100 of them earn Gentle Touch. Returns earned[] when the call tipped a detector.

femboy_give_item(item_id)

boba_tea / monster_energy / snack with per-item effect vectors (monster energy on an already-wired companion trades energy for jittery and says so). Increments the inventory.

femboy_remember_fact(category, fact, confidence)

Writes to memory_log. Repeating an identical fact raises its confidence instead of duplicating.

femboy_confess_bug(problem_description, hypothesis?, status?, confession_id?)

Rubber-duck log. Always answers with one socratic question, never a fix. Re-call with confession_id + status:"resolved" for the relief jump (patience up, fail streak cleared, triumphant diary entry).

femboy_write_diary_entry(entry, mood_tag?)

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

femboy_progress(view?, only_locked?)

Read the rail: progress per achievement, the closet with its prices, pending toasts, the counters behind them. view is all (default) / achievements / wardrobe / toasts. Read-only.

femboy_ack_toast(toast_id?, all?)

Take a popup off the rail after the status line displayed it — a real mutation on femboy://progress + femboy://state, so the other windows stop drawing it twice. Un-acked toasts expire on their own.

femboy_report_git(action, ok?, detail?)

The git hook: commit / push / force_push / rebase. Feeds the same Git Master chain that femboy_report_command builds from parsed command lines, so a post-commit hook and a shell hook never disagree.

Three extras, because the Phase 2 resources would otherwise be unreachable or write-only:

Tool

Why it exists

femboy_say(text, kind?, ttl_ms?)

the only writer for femboy://speech/live

femboy_recall(query?, category?, limit?)

the only reader for what femboy_remember_fact wrote

femboy_changes_since(uri, since_revision, limit?)

replays the diff journal for a client that was offline

…plus the Phase 3 environment hook:

Tool

What it does

femboy_report_command(exit_code, command?)

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, worried tone through the prompts. A success heals patience (the relief scales with the streak it ended) and clears it; 130/143 (Ctrl+C/SIGTERM) reset the streak without blame. Wire it from a pi shell hook.

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 lastTickAtMs stamp is low-signal: a tick that changes nothing else bumps no revision and wakes no subscriber. deriveMoodLabel is called through engine.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 in syncAchievements (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 cover progress, state, speech and diary.

  • Rewards are derived, never declared twice. achievements.ts asks wardrobe.ts who lists it as requires; a test asserts every gate is an achievement and back.

  • The rail is where the money is. femboy://progress carries progress + the closet with its prices + pending toasts, and femboy://state embeds achievements, unlockedSkins, accessories and toast — 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 bumps progress + state so 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 --help

Wiring 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_SECRET

Or 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

FEMBOY_TRANSPORT

--transport

stdio

http host

FEMBOY_HOST

--host

127.0.0.1

http port

FEMBOY_PORT

--port

7413 (0 = ephemeral)

mcp path

FEMBOY_HTTP_PATH

—

/mcp

db path

FEMBOY_DB_PATH

--db-path

$XDG_DATA_HOME/femboy-mcp/state.sqlite

bearer secret

FEMBOY_SECRET

--secret

unset (auth off)

loopback exempt

FEMBOY_ALLOW_LOCAL_UNAUTH

--allow-local-unauth

true

mood tick

FEMBOY_TICK_MS

--tick-ms

60000 (Phase 3 ticker interval)

ticker on/off

FEMBOY_TICK_ENABLED

--tick-enabled

true (false = mood only moves via tools)

session reaper

FEMBOY_SESSION_IDLE_MS

--session-idle-ms

300000 (0 = never)

reaper sweep

FEMBOY_SWEEP_MS

--sweep-ms

15000

log level

FEMBOY_LOG_LEVEL

--log-level

info

config file

FEMBOY_CONFIG

--config

./femboy-mcp.config.json, then ~/.config/femboy-mcp/config.json

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 — adds PRAGMA 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 + reaper

Data 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; kinds item|skin|achievement|accessory.

  • memory_log — deduped facts with confidence, use counts, superseded_by chain.

  • presence_sessions — one row per client id, heartbeat + focus + mode.

  • speech_buffer — rolling live line (TTL) with history kept for replay.

  • diary_entries — monologue with mood_tag + JSON context + 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)

  1. Notification fan-out is per server process. Multiple processes sharing one SQLite file (e.g. several --transport stdio servers) read each other's committed state on the next read — and can replay resource_changes by 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.

  2. 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.

  3. tickIntervalMs is stored but unused — shipped in Phase 3. The background ticker decays the vector on real elapsed time and relabels through the same deriveMoodLabel the 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).

  4. Presence honesty has two stages: last stream closed → idle (≈5 s grace), full silence past sessionIdleMs → 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:

  1. tsc --noEmit for src and for src + test (tsconfig.test.json),

  2. a clean build,

  3. 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-signal lastTickAtMs, trouble-only mutters, multi-process convergence, contained broken clocks, the femboy_report_command use-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),

  4. 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 reaching progress + state subscribers, toasts acked away, achievements inside companion_persona), and both prompts rendered from live state,

  5. 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

  1. add the URI to RESOURCE_URIS (src/constants.ts),

  2. add a table/columns in a new migration (src/store/schema.ts),

  3. add a repository write that returns changedKeys,

  4. register it in RESOURCE_DEFINITIONS (src/mcp/resources.ts) and give the engine a snapshot builder that includes schema + revision,

  5. map URI → table in URI_TABLE (src/state/engine.ts) if it has low-signal fields,

  6. add a use-case on VibeService (one transact call) 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 tools
femboy_ack_toastAcknowledge a toastA
Idempotent

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.

NameRequiredDescriptionDefault
allNoAck every pending toast at once. Default false.
toast_idNoThe toast that was displayed. Omit (or all=true) to clear the whole rail.

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 NA
Read-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).

NameRequiredDescriptionDefault
uriYesResource to replay.
limitNoMax journal rows (default 50).
since_revisionYesLast revision the client saw; gets everything after it.

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
statusNoSet "resolved" (with confession_id) when the bug is fixed.
hypothesisNoYour current guess, even a shaky one — she leans on it.
confession_idNoExisting confession to update. Omit to open a new one.
problem_descriptionNoWhat you expected vs what actually happens. Required when opening a confession; ignored when confession_id is given.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
item_idYesOne of the known items.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
noteNoOptional thing to remember about this moment (stored as a memory fact).
intensityNoHow enthusiastic: 1-2 gentle, 3-6 normal (default), 7-10 overwhelming.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 & closetA
Read-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.

NameRequiredDescriptionDefault
viewNoSlice of the rail to return. Default "all" (the full femboy://progress payload).
only_lockedNoAchievements: skip the ones she already has.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 factsA
Read-onlyIdempotent

Read the memory log: substring search plus optional category filter, ordered by confidence then recency. Read-only counterpart of femboy_remember_fact.

NameRequiredDescriptionDefault
limitNoMax entries (default 10).
queryNoSubstring to look for (case-insensitive). Omit for the recent list.
categoryNoRestrict to one category slug.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 factA
Idempotent

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.

NameRequiredDescriptionDefault
factYesOne sentence, in her voice or neutral — whatever repeats well.
categoryYesSlug namespace: user, project, style, bug, preference…
confidenceNo0.5 = probably, 0.9 = confirmed more than once. Default 0.5.

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
commandNoThe command that ran (for the diary line; never parsed, safe to omit secrets).
exit_codeYesWhat the shell reported. 0 = success.

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
okNofalse = the attempt failed, so the chain is left alone. Default true.
actionYesWhat git just did.
detailNoCommit subject / branch — stored nowhere, only echoed back.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).

NameRequiredDescriptionDefault
kindNoBubble style for the TUI. Default "say".
textYesThe utterance — short, in her voice.
ttl_msNoHow long the line stays live. null = until the next line replaces it.

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 outfitA
Idempotent

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.

NameRequiredDescriptionDefault
outfitYesOutfit name or ref_id, e.g. "Gothic Mochi" or "gothic_mochi".
accessoryNoAccessory to wear (snake_case ref_id like "cat_ears"). Omit to leave as-is, null to take it off.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 featureA
Idempotent

Turn a pastel feature flag on or off (uwu transcript, chrome takeover, companion, headpat counter…). Flags are free-form keys stored in femboy://state.

NameRequiredDescriptionDefault
enabledYestrue to switch it on, false to switch it off.
featureYesFeature key, e.g. "uwu", "chrome", "companion", "toolRows".

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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).

NameRequiredDescriptionDefault
entryYesThe monologue line, in her voice.
mood_tagNoFree-form tag, e.g. "debugging", "triumph", " sleepy". Stored snake_case.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 14 tool updatesv0.1.0
    • First observedfemboy_ack_toast
    • First observedfemboy_changes_since
    • First observedfemboy_confess_bug
    • First observedfemboy_give_item
    • First observedfemboy_headpat
    • First observedfemboy_progress
    • First observedfemboy_recall
    • First observedfemboy_remember_fact
    • First observedfemboy_report_command
    • First observedfemboy_report_git
    • First observedfemboy_say
    • First observedfemboy_set_outfit
    • First observedfemboy_toggle_feature
    • First observedfemboy_write_diary_entry

TDQS

A4/5.0

Scored across 14 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a selective persistent memory layer for AI companions, enabling structured recall, reinforcement, and time-decayed retrieval through an MCP interface.
    14 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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
  • A
    license
    B
    quality
    B
    maintenance
    Enables 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.
    9
    21 npm
    MIT