# Build a Retention Cohort Report From PostHog

Yes. An agent runs weekly PostHog retention for the last eight signup weeks and writes which cohorts stayed and what they did first.

[Run this on Rush](https://cloud.getrush.ai/run/retention-cohort-report/posthog/).

## What the agent does

The run does not clone a repository. PostHog is the connection: POST /me/connections with type mcp, name posthog, url https://mcp.posthog.com/mcp and auth mode oauth. PostHog's auth server routes the sign-in to the US or EU region of the account you log into. authorize_url is opened by the key's creator while that person is signed in to the Rush console. When status is connected, the session names the connection. A key run is handed only the connections named on the body. Pending or unknown is 422 CONNECTION_NOT_READY.

The agent calls query-retention, which the tool list describes as run a retention query, for users who signed up in the last 8 weeks, one cohort per week. That is the table. It then calls query-retention-actors, list persons in a retention cohort, on the cohort that retained best at week 1 and the cohort that retained worst, and reads the events on those persons' first session. insight-create and insight-update exist on the same server; this prompt does not call them, so the project gains no new insight tile.

retention.csv is the cohort grid query-retention returned: signup week as the row, and the following weeks as columns. retention.md names the best and worst cohorts by the week-1 figure in that grid, then compares first-session events of people who were still around with people who were not, using the actors the second call listed. Event names come from the project. The file does not invent a funnel step the connection did not return. If AI data processing is off in the PostHog organization, the tools that need a model inside PostHog are unavailable; query-retention itself is a query, and the report says when a call was refused.

The catalog also exposes feature flags, experiments, error tracking and logs. This job does not read them unless a first-session event is a flag evaluation and the comparison needs the flag key to name it. The prompt stays on retention. Connecting and calling tools is free on PostHog's side; tools that use a model internally can bill as PostHog AI spend, which is why the prompt names the two query tools and does not ask for a generated insight.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Use the PostHog connection. Call query-retention for weekly retention of users who signed up in the last 8 weeks, and query-retention-actors for the best and worst week-1 cohorts. Do not call insight-create or insight-update. Write retention.csv with the cohort table and retention.md naming the best and worst cohorts and comparing the first-session events of retained and churned users. Use only events the queries return. Read only."
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The session's artifacts are retention.csv and retention.md, each with a name, a mime type and a url on api.prix.dev. The url downloads that file with no key until url_expires_at, about an hour. The next read of the session returns a new url. GET /o/{org}/sessions/{id}/artifacts/retention.csv with the key works as well. A webhook's result field keeps at most 16 KiB, so the CSV is fetched from the session.

The CSV is the grid: one row per signup week, cells for the weeks after. The markdown names the best and worst cohorts by the week-1 cell and lists the first-session events that differ between people still in the cohort and people who left, with the counts the actors query returned. It does not add a recommendation to change the product. It does not claim a percentage the table does not contain.

A reviewer checks that the eight rows match the eight signup weeks, that best and worst are the actual week-1 extremes, and that every event name in the comparison appears in the project's data via the transcript of query-retention-actors. The PostHog project is unchanged: no insight was created. The follow-up, if you want a saved insight later, is a new input on the same session after this turn finishes, not a write hidden in this one.

## Run it on every Monday morning

A Monday job you already schedule POSTs this body to https://api.prix.dev/o/{org}/sessions. The Idempotency-Key is the Monday's date, so a double fire returns the run already started. The same key with a changed prompt is 409 IDEMPOTENCY_CONFLICT. Omit resources. PostHog is not a GitHub repository, and the run does not need the GitHub App.

Set webhook_url on the key from an admin session. The key itself cannot set it. Rush POSTs run.completed when the turn ends, within about 30 seconds, with webhook-id, webhook-timestamp and webhook-signature. Reject a timestamp more than five minutes off. Store the CSV from the artifact url. If your endpoint fails, the same id is retried at 2, 4 and 6 minutes and then dropped; GET the session from session_url to pick up the file.

## Why run it on Rush?

Weekly retention is a query you can click in PostHog, and the first-session comparison is a second query you have to remember to run on the right cohorts. The agent runs query-retention and query-retention-actors in a sandbox and writes both files from those results. The session keeps the tool output, so the week you call the best cohort is the week the query returned, not a number typed into a doc.

Product, growth and support can each want the same grid on Monday. They are separate sessions, each with its own sandbox, up to max_concurrent on the key (default 4, then 429). The sandbox parks at the end of the turn, costs nothing while parked, and remains for 7 idle days. A follow-up message can ask for one cohort's actors to be listed in full without paying the eight-week query again.

## Frequently asked questions

### Will it create a PostHog insight or change a dashboard?

No. The prompt names query-retention and query-retention-actors and tells the agent not to call insight-create or insight-update. The project stays as it was. The files are artifacts on the Rush session.

### Which region is queried?

The account you sign in with. PostHog's MCP auth sends you to the US or EU region for that account. A project in the other region is a different login and a different connection. Name the connection that matches the project.

### What if signup is not a person property we track?

Say what counts as signup in the prompt: an event name, or a person property and its date. The agent should not guess a created_at that the project does not have. If query-retention cannot filter on that, the report says which filter failed instead of returning an unrelated cohort.

### Do these calls cost PostHog AI credits?

PostHog's docs say connecting and calling MCP tools is free, and that some tools use a model internally and can bill as PostHog AI spend, only when AI data processing is enabled. This prompt stays on the two retention queries and does not ask for a generated insight. A refused call is written into the report, not papered over.
