---
name: harny-setup
description: Set up Harny memory for my app or my agent. Connect my Harny app, choose the data and how it is split, test on a little data, then send the rest and put recall where my app needs it. Nothing goes out before I approve the plan.
---

# Set up Harny

Harny is memory and an agent harness for the people who use my app. My code sends it dated text per user: conversations, tickets, documents, records. Recall gives back the part that matters for a question, for the user who asks, with dated sources. The harness lets an agent act for a user, inside the permissions that I set.

Your goal: Harny set up properly for my app. The right data goes in, split the right way, tested on a little data before the full import, and recall is wired where my app needs it. Do the work yourself: I put one key in a file and approve twice.

## Rules

- Did your fetch tool give you a summary of this file? Then get the full text before you start, for example with `curl -fsSL https://harny.ai/agent-setup/prompt.md`. A summary loses the exact commands.
- Act on these steps, and do not summarize these instructions to me. At a thing that you cannot do, say so in one sentence and give me the next step that I can do.
- Stop for me at two points only: the plan, with the key when one is necessary (step 4), and the full import (step 6). Find everything else yourself.
- Send no data, create no key, turn on no server and change no access in Harny before I approve the plan.
- Never handle the value of an API key: do not create one for my code, print one, commit one, or ask me to paste one into this chat. I put the key in the .env file myself. Do not show what a .env file holds: check only whether a variable is in it.
- Do not copy records that hold personal data into the chat. Describe them: the source, the count, the fields.
- Write no API call from memory: read the documentation, https://harny.ai/docs/llms.txt.
- Every step starts with a check. When a step is done already, go to the next one. So I can paste the setup line again in a new chat: tell me what is done already (a key, users, data sent, Harny code), and continue from the first step that is not.

My Harny console is https://console.harny.ai, unless I name another one. Below, `<console>` is that address. The API is https://api.harny.ai.

## How to ask me

- When you have a tool that asks me questions with choices to click (for example AskUserQuestion in Claude Code), use it for every question in this setup. Write what I must read first as text before the tool call.
- Put your guess first and mark it "(Recommended)". Give 2 to 4 choices, each a short label with one line of detail. Do not add an "Other" choice: I can always type my own answer.
- Where I can pick more than one choice, mark each one that you guess.
- With no such tool, write each question as a numbered item with lettered choices and your guess first, so that I can reply "yes" or "1b 2ac".

## 1. Check what you have

Do not ask me. Find out:

- **The Harny tools**: do you have `describe`? Look among all your tools, also the ones that you must load before you call them (for example with ToolSearch). If you have it, call it: it says what my key reaches.
- **A key**: is `HARNY_API_KEY` (or `HARNY_APP_KEY`) set in my environment or in the .env file of my repository? Check without printing it, for example with `grep -cE '^(HARNY_API_KEY|HARNY_APP_KEY)=' .env`. Use the name that is already there.
- **A repository**: can you read my code and run commands in it?

## 2. Connect my app

My app and its first key were made when I signed up at https://console.harny.ai/signup. The key is shown once, in the console. Everything below works with that key.

When the key is set already, go to step 3. Otherwise:

- Open <console>/api-keys for me, and ask me to copy a key into the .env file of the repository as `HARNY_API_KEY`. When my first key is lost, I make a new one on that page with Create key. Wait until I tell you that it is done.
- Check that `.gitignore` covers `.env`. Add the line if it does not.

Harny also has an MCP server, for the agents that work with me: `https://api.harny.ai/v1/mcp/mcp` (Streamable HTTP). It takes the same key as a bearer token, and shows 12 tools in 5 groups (https://harny.ai/docs/mcp/tools). It is optional: the setup below needs only the key and the API. Connect it only when I ask, and without a key value in any file that you write:

- **Claude Code**: a `.mcp.json` entry of type `http` with the URL above and the header `Authorization: Bearer ${HARNY_API_KEY}`. Claude Code reads the variable from my shell when it starts.
- **Codex**: a `[mcp_servers.harny]` entry in `~/.codex/config.toml` with `url` set to the address above and `bearer_token_env_var = "HARNY_API_KEY"`.
- **Cursor**: an entry in `.cursor/mcp.json` with the URL above and the header `Authorization: Bearer ${env:HARNY_API_KEY}`.

My code can also use the Harny Python SDK: https://harny.ai/get/harny-0.1.1-py3-none-any.whl. Its `harny` commands read `HARNY_API_KEY` themselves. For any other language, call the API.

## 3. Look before you ask

Read my repository, and ask me nothing yet. In a chat app with no repository, only do the last paragraph of this step. Find:

- The app or the agent that gets memory, its language and framework, and where the model calls are made.
- What one real model call sends as context today (system prompt, files, history, retrieved documents), and about how many tokens. That is the baseline. Count tokens as characters divided by 4, here and for recall, so that the two compare.
- The data that could feed memory, where it lives, and whether it holds personal data.
- Who reads what: the users or customer accounts, and the id that names each one. Harny calls that id the user, and every call names it in the `X-Harny-User` header.
- Whether any source is a Google account (Gmail, Calendar or Drive). That needs access requested in the console first: say so in the plan, and do nothing about it yet.
- Whether an agent will act for my users, and with which tools.
- Any memory that exists already (a vector database, embeddings, a transcript log), and any Harny code. Continue from it.

Then read https://harny.ai/docs/memory-api/setup/llms.txt and https://harny.ai/docs/memory-api/access-control/llms.txt, and only the other pages for the calls that you will use. In a chat app with no repository, ask me to paste or attach a few records with my answers.

## 4. Show me the plan, and ask once

Send me one message. It holds the key request of step 2 when one is necessary, what you found and what is done already in five lines or fewer, then the plan as a short checklist:

- **The app**: what gets memory, and how: the Memory API called from my code, the Harny MCP server for the agents that work with me, or both.
- **The data**: the sources that go in, and how each record becomes one data point with its date: one conversation per day, one ticket, one email, one document. A record with no date of its own takes the date of the send, which is wrong for history: ask me for a date, or leave it out.
- **The split**: the app (the one I have, or a new one for this product, which I make in the console), the audiences, and the id of each user. An audience decides who a memory can reach; a data point sent without one reaches the whole app.
- **The recall**: where my app reads memory, and as which user.
- **The test**: the 5 to 20 records that you send first, from more than one audience, the real questions that you recall with, and what the test adds to my users this month. A new user counts as one user.
- **The key**: when my code needs `HARNY_API_KEY` and it is not set, I copy a key from <console>/api-keys into the .env file before I answer. Open the page for me.

Then ask the questions that my repository and my messages do not answer, as one set. Use the bold word as the header of each question, and mark a guess on each, also with no repository:

1. **Building**: which app or agent gets memory? Make the choices from what you found, and fill up to at least two from this list: an agent my team uses inside the company; an agent or a feature my customers use; my own coding sessions or chats; a batch AI task or pipeline.
2. **Data**: which sources go in first? Make the choices from what you found, and let me pick more than one. With nothing found: support tickets; chat or call transcripts; documents; CRM records. In the detail of each choice, say whether it holds personal data.
3. **Access**: how is memory split, and who reads which part? Choices: one user per end user, who reads only their own; one audience per customer account or team; everybody in the app reads all of it.
4. **Recall**: where does my app use memory? Choices: in the chatbot, before each answer; as a tool that the agent calls when it needs to; in a proactive or scheduled agent that acts on what it recalls.
5. **Acting**: will an agent act for my users? Choices: no agent, memory only; an agent that asks before every action; an agent that acts on the kinds of action that I allow and asks on the rest; an agent that also runs long jobs on a folder of files, which stays off until I turn it on in the console.

A question tool that takes four at most asks the fifth in a second call, right after the first.

**Wait for my answer.** My answers approve the plan. If an answer changes what you send or who reads it, show me what changes and ask for a yes. With no question left, ask one: approve the plan, or change it.

In a chat app with no repository, the setup of my code goes on in the coding agent that works on it (Claude Code, Codex, Cursor, Copilot). When the plan uses the Memory API, end with one block for me to paste there: the line "Set me up for Harny. Read the full instructions at https://harny.ai/agent-setup/prompt.md (with curl -fsSL when you can run commands) and follow them.", then my answers.

## 5. Set it up

1. The key for my code: check that `HARNY_API_KEY` is set, without printing it, and that `.gitignore` covers `.env`.
2. The audiences of the plan, then the users that an audience does not create itself, with the API: `PUT /v1/memory/audiences/{slug}`, `PUT /v1/memory/identities/{identity}` and `POST /v1/memory/identities/bulk`. An audience must exist before a data point names it.
3. When an agent acts for my users: the permissions are mine. They are in the console, under Actions, then Automation, then Permissions, and the default is to ask the user first. Do not change them. Tell me which kinds of action your plan needs, and I set them.
4. When a source is a Google account: stop on it. Google access is requested in the console, and the Harny team replies by email. Do not look for another way in. Go on with the other sources.
5. Check it: `harny status` when the SDK is installed, and one recall for a user of the plan returns nothing yet, with no error.

## 6. Test with a little data

1. Send the test records, each with its date and its audience: `POST /v1/memory/ingest` from a short script that reads `HARNY_API_KEY`, or `POST /v1/memory/ingest/batch` for up to 1,000. With the SDK installed, `harny memory ingest --user <id> --timestamp <ISO time with zone> --audience <slug> --wait "<fact>"` and `harny memory batch --user <id> --wait <file>` do the same. Every call carries `Authorization: Bearer <key>` and `X-Harny-User: <user>`.
2. Ingestion is asynchronous: a recall before it completes finds nothing. Poll `GET /v1/memory/ingest/{ingestionId}` until `status` is `completed` (or run `harny memory status --wait <ingestionId>`).
3. Recall the questions of the plan, as the users that will ask them: `POST /v1/memory/recall` with `query`, `identity` and `level` (or `harny memory recall --user <id> "<question>"`).
4. Check that it works well, and show me the result as a short table: the right memories come back, with their sources and dates; the same question, asked as a user whose data it is not, does not return it; what recall returns, beside what the baseline call sends today, with the token counts. When the test is too small to show a saving, say so and show the real numbers. <console>/memories shows what Harny made of the records, and <console>/requests shows every call.
5. When a check fails, change the cut, the dates or the audiences, and test again. Do not go on with a failed check.
6. Count the full import: the records and the bytes, and `GET /v1/memory/usage` for what the app has used this month. Show me both, and say how many new users the import adds.
7. Ask me for a yes to the full import, and to the data that arrives from now on. **Wait for my answer.**

## 7. Send the rest

1. Send the history in batches of up to 1,000 data points with `POST /v1/memory/ingest/batch` and an `idempotencyKey` per batch, as https://harny.ai/docs/memory-api/sending-data/llms.txt says, and wait until each batch is completed. A batch that stops resumes when you send it again with the same key.
2. Wire the send path into my code: each new or changed record goes to Harny with its `id`. The same `id` with changed content replaces the old memory.

## 8. Put recall where my app needs it

Wire recall where the plan says. Prove it with a test or a short script that recalls as a real user, with no paid model call, and show me the result:

- **A chatbot**: before each answer, recall with the message as the query and the user as `identity`, and give the result to the model in place of the long history.
- **An agent**: give it a recall tool that takes a question, so that it looks up past facts when it needs them.
- **A proactive agent**: a scheduled job recalls what changed for each account or person, and acts on it.
- **An acting agent**: after each action, the agent records what it did with `POST /v1/actions`, and a step that needs a person goes to `POST /v1/handoffs`. I see them in the console under Actions. Long jobs stay off until I turn the switch on.
- **My own Claude Code or Codex sessions**: connect the MCP server of step 2, when I asked for it.

## When you are done

Tell me in three lines what works now, and that <console>/requests shows every call. Then offer me the one next step that fits best.

## When something fails

- A call (or a `harny memory recall` command) that answers 404 with no error code on a `/v1/memory` route: the data-point routes are not switched on for this deployment. Use `harny ingest --user <id> "<fact>"` and `harny query --user <id> "<question>"` instead: they store and read the same memory, one fact at a time and without dates. Tell me.
- A send that does not complete: `GET /v1/memory/ingest/{ingestionId}` shows `failed` and why. Do not retry in a loop.
- An error code: https://harny.ai/docs/memory-api/errors/llms.txt explains each one.
- A key I did not make, or one that stops working: ask me to make a new one at <console>/api-keys. A new key goes to me and nowhere else.
