> ## Documentation Index
> Fetch the complete documentation index at: https://opensre.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PostHog (MCP)

> Connect PostHog's hosted MCP server so OpenSRE can query analytics, feature flags, error tracking, and HogQL during investigations

OpenSRE connects to PostHog's hosted [Model Context Protocol (MCP)](https://posthog.com/docs/model-context-protocol) server, exposing PostHog's products — product analytics, feature flags, error tracking, experiments, surveys, and HogQL queries — as tools the agent can call while investigating an incident.

This is distinct from the [PostHog REST integration](/docs/posthog), which only stores project credentials for the REST API. Use MCP when you want the agent to explore PostHog data directly during investigations. The onboarding wizard lists **PostHog** (REST) and **PostHog (MCP)** as separate choices — configure REST credentials with `opensre integrations setup posthog`.

## Tools

| Tool                 | What it does                                                                                 |
| -------------------- | -------------------------------------------------------------------------------------------- |
| `list_posthog_tools` | List the tools the connected PostHog MCP server exposes (compact, filterable)                |
| `call_posthog_tool`  | Call a named PostHog MCP tool (e.g. run a HogQL query, list feature flags, inspect an error) |

The agent typically calls `list_posthog_tools` first to discover what is available for your project, then `call_posthog_tool` with the chosen tool name and arguments.

The hosted PostHog MCP server exposes 240+ tools, each with a full input schema. Returning all of them at once is far larger than any model's context window, so `list_posthog_tools` returns a **compact, bounded listing** — tool names plus short descriptions, without schemas. To work with it efficiently:

* Pass `name_filter` (space- or comma-separated terms, e.g. `"events query sql"`) to narrow the list to relevant tools.
* Pass `include_schema=true` on a narrowed list to fetch the full input schema for the specific tool you intend to call.

To query events for a person or across a project, call `call_posthog_tool` with `tool_name="execute-sql"` and a HogQL query (e.g. `SELECT event, count() FROM events WHERE ... GROUP BY event`). There is no `search_events` tool.

## Prerequisites

* A PostHog account (US or EU — the hosted server routes you automatically)
* A PostHog **personal API key** created with the **MCP Server** preset. See [PostHog's personal API keys docs](https://posthog.com/docs/api/personal-api-keys).

<Info>
  OpenSRE defaults to **read-only** access (`x-posthog-read-only: true`) so investigations cannot mutate your PostHog project. Set `POSTHOG_MCP_READ_ONLY=false` only if you explicitly want the agent to perform writes.
</Info>

## Setup

### Option 1: Interactive CLI

```bash theme={null}
opensre integrations setup
```

Select **PostHog (MCP)** when prompted, then paste your personal API key. The setup uses the hosted Streamable HTTP transport; keep the default URL unless you have a reason to change it. To run a local server instead, set `POSTHOG_MCP_MODE=stdio` via environment variables (see below).

To skip the menu, name the service directly:

```bash theme={null}
opensre integrations setup posthog_mcp
opensre integrations verify posthog_mcp
```

### Option 2: Environment variables

Add to your `.env`:

```bash theme={null}
POSTHOG_MCP_MODE=streamable-http
POSTHOG_MCP_URL=https://mcp.posthog.com/mcp
POSTHOG_MCP_AUTH_TOKEN=phx_your_personal_api_key
POSTHOG_MCP_PROJECT_ID=12345          # optional, scope to one project
POSTHOG_MCP_ORGANIZATION_ID=          # optional, scope to one organization
POSTHOG_MCP_FEATURES=                 # optional, comma-separated feature filter
POSTHOG_MCP_READ_ONLY=true            # optional, default true
```

| Variable                      | Default                       | Description                                                          |
| ----------------------------- | ----------------------------- | -------------------------------------------------------------------- |
| `POSTHOG_MCP_AUTH_TOKEN`      | —                             | **Required** (hosted). Personal API key with the `MCP Server` preset |
| `POSTHOG_MCP_URL`             | `https://mcp.posthog.com/mcp` | MCP server URL (use `https://mcp-eu.posthog.com/mcp` to pin EU)      |
| `POSTHOG_MCP_MODE`            | `streamable-http`             | Transport: `streamable-http`, `sse`, or `stdio`                      |
| `POSTHOG_MCP_PROJECT_ID`      | —                             | Scope tools to a specific PostHog project                            |
| `POSTHOG_MCP_ORGANIZATION_ID` | —                             | Scope tools to a specific organization                               |
| `POSTHOG_MCP_FEATURES`        | —                             | Comma-separated feature filter (e.g. `flags,error-tracking`)         |
| `POSTHOG_MCP_READ_ONLY`       | `true`                        | Send the read-only header so the agent cannot mutate PostHog         |
| `POSTHOG_MCP_COMMAND`         | —                             | Command to launch a local MCP server (`stdio` mode only)             |
| `POSTHOG_MCP_ARGS`            | —                             | Arguments for the local MCP command (`stdio` mode only)              |

To run a local PostHog MCP server instead of the hosted endpoint, use `stdio` mode:

```bash theme={null}
POSTHOG_MCP_MODE=stdio
POSTHOG_MCP_COMMAND=npx
POSTHOG_MCP_ARGS=-y @posthog/mcp-server@latest
POSTHOG_MCP_AUTH_TOKEN=phx_your_personal_api_key
```

### Option 3: Persistent store

```json theme={null}
{
  "version": 1,
  "integrations": [
    {
      "id": "posthog-mcp-prod",
      "service": "posthog_mcp",
      "status": "active",
      "credentials": {
        "url": "https://mcp.posthog.com/mcp",
        "mode": "streamable-http",
        "auth_token": "phx_your_personal_api_key",
        "project_id": "12345",
        "read_only": true
      }
    }
  ]
}
```

## Verify

```bash theme={null}
opensre integrations verify posthog_mcp
```

A successful check connects to the MCP server and reports how many tools it discovered. If it fails, the most common cause is a missing or invalid personal API key — confirm the key was created with the `MCP Server` preset and that outbound HTTPS to `mcp.posthog.com` is allowed.

## Metric report (scheduled)

Deliver a per-metric PostHog analytics pulse to Telegram, Slack, or Rocket.Chat, on demand or on a schedule — coworker-style digests (what moved and why it matters), not a raw dashboard dump. Slack delivery needs a bot token (a webhook alone cannot honor `--chat-id`). This uses the headless **posthog-summary** skill path (schema discovery, then one bounded HogQL query per metric), not the investigation pipeline or generic `opensre cron` kinds. It requires the PostHog **MCP** integration above — the REST `posthog` integration alone cannot serve it.

| Command                                                                      | What it does                                         |
| ---------------------------------------------------------------------------- | ---------------------------------------------------- |
| `opensre posthog report run`                                                 | Run once and print the per-metric report to stdout   |
| `opensre posthog report run --period 30d --metrics "active users,pageviews"` | Run once for a custom window and metric focus        |
| `opensre posthog report schedule add`                                        | Schedule recurring delivery (cron + provider + chat) |
| `opensre posthog report schedule list`                                       | List PostHog report schedules                        |
| `opensre posthog report schedule run TASK_ID`                                | Run a scheduled report immediately                   |
| `opensre posthog report schedule remove TASK_ID`                             | Remove a schedule                                    |

Example — every Monday at 08:00 London time to Telegram:

```bash theme={null}
opensre posthog report schedule add \
  --cron "0 8 * * 1" \
  --tz Europe/London \
  --provider telegram \
  --chat-id "-1001234567890" \
  --period 7d
```

Example — same schedule to a Slack channel (`C…` member/channel id):

```bash theme={null}
opensre posthog report schedule add \
  --cron "0 8 * * 1" \
  --tz Europe/London \
  --provider slack \
  --chat-id C0123ABCD \
  --period 7d
```

Slack delivery needs `SLACK_BOT_TOKEN`. A `SLACK_WEBHOOK_URL` alone will not work here: a webhook always posts to the one channel it was created for, so it cannot honour `--chat-id`.

`--period` accepts a relative window (`24h`, `7d`, `30d`; default `7d`). Optional `--metrics` narrows the report to a comma-separated set instead of the default metric set.

The gateway daemon picks up scheduled reports automatically when it is running. If the LLM is unavailable, the run fails with an error (no deterministic fallback).

<Note>
  The report compares the current window against the previous comparable window per metric. Real zeros are reported as zeros; failed queries are called out as failures — never silently widened or fabricated, and never presented as zero when the query did not run.
</Note>
