# Ownhand: agent guide Ownhand writes text in this user's own voice, their **Hand**, fitted to where the text is going. It keeps every fact and removes AI tells. It learns from what the user actually sends, so the loop only works if you close it. ## Rules 1. Use the user's Hand on every call. If the user picked a default Hand when they connected, calls use it when you leave `profile_id` out. If a call says no Hand is selected, call `get_hand()` to list them, or `create_hand` once. Save the id to your memory. 2. Show the draft. Never send or post anything without the user's OK. 3. After the user acts on a draft, call `send_feedback` with exactly the text that went out. 4. Copy conversation context word for word. If you can't see the thread, ask the user to paste it. 5. Put only the user's own requests in `user_instructions`, such as "shorter". The Hand already holds their style. ## The loop | Step | Tool | |---|---| | Find the Hand | `get_hand()` | | Draft | `write(draft_text, profile_id, occasion, …)` returns `request_id` and `text` | | Show | Show `text` as is, and mention `unresolved` items if any | | Report | `send_feedback(request_id, verdict, final_text)` | ## Occasions Pick the occasion from where the text will be posted and who reads it. Leave it out if you can't tell. | Occasion | Use when | |---|---| | `chat_dm` | A direct message in Slack, Teams, or similar | | `chat_channel` | A post or thread reply in a shared channel | | `email_internal` | An email to a coworker | | `email_formal` | A senior person, a client, or an official | | `email_cold` | Someone who doesn't know the user | | `email_warm` | Someone the user already knows | | `proposal_cold` | A proposal to people who don't know the user | | `proposal_warm` | A proposal to people the user works with | | `pr_description` | A pull request description | | `review_comment` | A code review comment | | `docs` | Documentation or a README | | `status_update` | An update to a manager or a team | You can add `recipient_name`, `recipient_role`, and `familiarity` (`cold`, `warm`, `close`). Add them only when you know them. ## Replies Set `is_reply: true` and pass up to 30 recent messages as `context_messages`, oldest first: ```json [ {"author": "dana", "is_me": false, "text": "did the payments deploy go out?"}, {"author": "me", "is_me": true, "text": "not yet, waiting on ci"} ] ``` Ownhand measures how the user writes in this thread and matches it. Facts that appear only in the thread stay out of the rewrite. The thread is never stored. When `is_reply` is set and there's no context, the tool returns `status: "needs_context"` with a question to ask the user. ## Feedback | What the user did | Call | |---|---| | Sent it unchanged | `send_feedback(request_id, "approved")` | | Edited, then sent | `send_feedback(request_id, "edited", final_text="")` | | Didn't use it | `send_feedback(request_id, "rejected", was_sent=false, reason="")` | | Picked a variant | add `chosen_variant=` | When the user says why, pass their words as `reason`. A stated reason becomes a rule right away. A pattern you only observe needs to show up twice. Learning runs in the background, and the Hand's version goes up when it finishes. The user can pin or reject any rule with `update_hand`. ## New users Results tell you when setup is needed: `get_hand()` returns a `next_step` when the user has no Hand, or when their Hand has no samples yet. The `set_up_my_hand` prompt runs the whole setup. 1. Ask for 5 to 10 things the user wrote themselves, such as Slack messages, emails, or PR descriptions. Only things they sent. AI drafts don't count. 2. Call `create_hand(name, samples=[...], about_writer="")`. If they already have an empty Hand (for example one made when they connected), call `update_hand(profile_id, add_samples=[...])` instead. ## Errors | Error | What to do | |---|---| | `Authentication failed` / 401 | The sign-in expired or the API key was revoked. Ask the user to reconnect Ownhand in their MCP client. Setup for each client: https://ownhand.dev/connect | | `Profile not found` | Wrong id or a different account. Call `get_hand()`. | | 402 | Out of credit. Ask the user to add credit at the URL in the error (https://ownhand.dev/pricing explains how), then retry. Nothing was charged for the refused call. | | 429 | Too many requests. Wait for the time in the error, then retry. | | `unknown occasion` | Use a slug from the table. | | `unresolved` in a result | Show the draft anyway and mention the items. |