openpetswithchatandmcp/docs/claude-integration.md
OpenPets Dev 6ab3bb64d8 feat(rebrand): rename OpenPets to FamiliarOS and pets to familiars
- Rename all user-facing and technical identifiers from OpenPets/Pet to FamiliarOS/Familiar.
- Rename packages from @open-pets/* to @familiaros/*; rename install-pet/pet-format packages.
- Rename plugin IDs and directories from openpets.* to familiaros.*.
- Rename IPC namespace from openpets:* to familiaros:* and state filenames from openpets-* to familiaros-* with legacy migration.
- Rename source files (pet-window, built-in-pet, default-pet-controller, etc.) to familiar equivalents.
- Update locales (en, es-419, ja, ko, pt-BR, zh-Hans, zh-Hant) and tray/pet context menu strings.
- Add Familiar naming feature: preference, settings input, tray menu display.
- Update assets and packaging config; all desktop tests pass.
2026-06-17 01:42:08 +00:00

10 KiB

Claude integration

This document describes how FamiliarOS Desktop integrates with Claude Code, what files are configured, how Claude reaches the desktop app, and which Claude events trigger familiar reactions or speech.

Integration surfaces

Claude support has three related surfaces:

  1. MCP tools — Claude gets the familiaros_status, familiaros_react, and familiaros_say tools.
  2. Claude memory instructions — Claude is told when it should use those tools.
  3. Claude hooks — Claude lifecycle and tool events automatically trigger FamiliarOS reactions.

The desktop setup UI for these surfaces is implemented in apps/desktop/src/agent-setup.ts and exposed to the renderer through familiaros:agent-setup-snapshot and familiaros:agent-setup-action.

This document primarily describes Desktop user/global setup. The CLI also supports project-local Claude setup; see Project-local Claude setup.

Files managed by FamiliarOS

Claude MCP entry

The MCP entry is installed into Claude Code by running a Claude command shaped like:

claude mcp add --scope user familiaros -- npx -y @familiaros/mcp

If the user selected a specific familiar in the desktop setup UI, the command includes that familiar:

claude mcp add --scope user familiaros -- npx -y @familiaros/mcp --familiar <petId>

In local development or packaged desktop mode, FamiliarOS can use node <local-or-bundled-entry> instead of npx.

Packaged and local node <entry> commands require node to be available on Claude Code's PATH. Desktop setup reports an error instead of installing a bundled command if node --version cannot run from the agent environment.

Claude memory

FamiliarOS writes two user-level Claude memory files:

~/.claude/CLAUDE.md
~/.claude/familiaros.md

~/.claude/CLAUDE.md receives a managed import block:

<!-- FAMILIAROS:IMPORT:START -->
@~/.claude/familiaros.md
<!-- FAMILIAROS:IMPORT:END -->

~/.claude/familiaros.md receives the managed instruction block:

<!-- FAMILIAROS:START -->
## FamiliarOS

FamiliarOS MCP tools may be available.

Use FamiliarOS as a short visible status channel for meaningful coding progress:
- Use `familiaros_say` when starting, completing, blocking, or needing review on non-trivial work.
- Keep messages brief, user-facing, and non-sensitive.
- Do not include code, logs, secrets, URLs, or file paths.
- Use `familiaros_react` for small visual or emotional feedback.
- Use `familiaros_status` only when checking availability or the targeted familiar.
- Do not spam every internal step.
<!-- FAMILIAROS:END -->

The memory installer is idempotent. It updates only the managed blocks, avoids symlinks and unsafe files, writes private files, and uses atomic temp-file writes.

Claude hooks

Claude hooks are installed into:

~/.claude/settings.json

FamiliarOS-managed hook commands include this marker:

--familiaros-managed

The normal published hook command is:

npx -y @familiaros/claude hook --familiaros-managed

If a familiar is selected:

npx -y @familiaros/claude hook --familiaros-managed --familiar <petId>

FamiliarOS installs the command for these Claude hook events:

UserPromptSubmit
PreToolUse
PermissionRequest
Notification
Stop
StopFailure

Each hook entry is a Claude command hook with a short timeout and async execution enabled:

{
  "type": "command",
  "command": "npx -y @familiaros/claude hook --familiaros-managed",
  "timeout": 3,
  "async": true,
  "asyncRewake": false
}

FamiliarOS backs up settings.json before changing it and removes only hooks containing the --familiaros-managed marker.

Project-local Claude setup

The @familiaros/cli package can configure a project-local Claude integration from a project directory:

familiaros configure --agent claude --familiar <petId>

Project-local setup differs from Desktop user/global setup:

  • It uses claude mcp add-json familiaros ... --scope local from the target project directory.
  • It writes hooks to <project>/.claude/settings.local.json.
  • Hook commands include both --familiaros-managed and --project-local.
  • Project-local hook entries use timeout: 10, async: true, and asyncRewake: false.
  • The MCP and hooks are always configured with a selected --familiar <petId>.

When a global FamiliarOS Claude hook runs, it checks whether the current Claude project already has a project-local FamiliarOS hook. If it finds one, the global hook does not send a duplicate reaction. This avoids double familiar events when both global Desktop setup and project-local CLI setup exist.

Project-local files live inside the project and may be committed depending on the user's repository policy. They can contain the selected familiar id.

Runtime path

When Claude calls an FamiliarOS tool or when a Claude hook fires, the runtime path is:

Claude Code
  -> @familiaros/mcp or @familiaros/claude hook
  -> @familiaros/client
  -> FamiliarOS desktop local IPC discovery file
  -> FamiliarOS desktop IPC socket/pipe
  -> default familiar controller or explicit agent familiar controller

The desktop app writes a discovery file such as:

macOS: ~/Library/Application Support/FamiliarOS/runtime/ipc.json
Windows: %APPDATA%/FamiliarOS/runtime/ipc.json
Linux: $XDG_RUNTIME_DIR/familiaros/ipc.json, or ~/.config/FamiliarOS/runtime/ipc.json fallback

That file contains the IPC endpoint and a per-run token. Clients must send that token with every request.

MCP tools

Claude sees these tools when the MCP server is configured:

Tool Purpose Desktop IPC method
familiaros_status Check whether FamiliarOS is reachable and which familiar is targeted. status
familiaros_react Set a short reaction on the target familiar. familiar.react
familiaros_say Show a short safe speech bubble, optionally with a reaction. familiar.say

familiaros_say is validated before it reaches the desktop app. Messages must be short, single-line, and must not look like code, logs, secrets, URLs, or file paths.

Familiar targeting

If the MCP server or hook command was configured without --familiar, events target the desktop default familiar.

If it was configured with --familiar <petId>, the process asks the desktop app for a lease. A valid installed non-default familiar opens as an explicit agent familiar window. Missing, invalid, broken, built-in, or default familiar requests fall back to the default familiar.

Explicit leases expire after a short TTL unless refreshed. When the last explicit lease for a familiar expires or is released, FamiliarOS clears and closes that agent familiar window.

Claude hook reaction and speech mapping

Claude hooks are decorative and best-effort. They must not block, approve, deny, or change Claude's behavior. If FamiliarOS is closed or IPC is unavailable, the hook exits successfully and silently.

Claude event Trigger condition Reaction Speech bubble
UserPromptSubmit User submits a prompt to Claude. thinking, throttled. None.
PreToolUse Tool name is Edit, Write, or MultiEdit. editing None.
PreToolUse Tool name is Bash and command text looks test-like. testing None.
PreToolUse Tool name is Bash and command text does not look test-like. None. None.
PreToolUse Any other tool. None. None.
PermissionRequest Claude asks for approval. waiting Approval needed, throttled with a short cooldown.
Notification Claude emits a notification hook event. None. None.
Stop Claude finishes a response. success, throttled. None.
StopFailure Claude stop/finalization fails. error One error-pool message, throttled.
Unknown event Event is not recognized. None None.

Test-like Bash detection is intentionally coarse and private. It may inspect only a bounded command string to classify the reaction. The command text is never sent to speech.

Claude hooks do not use the left/right walking animations or the running reaction. The running-right and running-left sprite rows are reserved for familiar drag/move motion, and generic Bash/shell activity is silent by default. Hook reactions use quieter phase changes instead: editing maps to the generic active-work row, thinking maps to review, waiting/testing maps to waiting, success maps to jumping, and errors map to failed.

Hook speech pools

When a hook is allowed to speak, it chooses one static local message from the matching pool:

Category Possible messages
thinking Thinking it through, Let me check, On it, Working it out
success Done, That worked, All set, Nice, finished
error Something failed, Needs another look, Hit a snag, Not quite there
permission Approval needed

Speech is throttled by category so hooks do not spam bubbles. Current speech cooldowns are:

Category Cooldown
permission 3 seconds
thinking, success, error 20 seconds each

Normal thinking and success hooks no longer speak, so their speech pools are retained for shared/static message support but are not used by Claude's default quiet hook policy. Reaction-only hooks are also deduped, with the same reaction suppressed for about 10 seconds.

Throttle state stores only speech-category and reaction timestamp keys, never prompts, commands, tool input, output, code, logs, or transcripts.

Safety rules

  • Hook stdout stays empty so Claude does not ingest accidental context.
  • Hook errors are swallowed unless debug logging is enabled.
  • Hook debug logs sanitize path-like values. MCP/client-side validation separately rejects secret-looking speech.
  • Speech is static and local; it does not include model-generated text.
  • Tool input and command text are used only for coarse reaction classification.
  • Managed setup refuses unsafe symlinks and non-regular files. Claude memory files also have an oversized-file safety limit before FamiliarOS edits them.