# PostHog AI employee

Viktor works in PostHog for you. Ask in Slack or Microsoft Teams.

Viktor is an AI employee that connects to PostHog and helps you track product usage and feature adoption, running 300 PostHog actions for you like Exec, Alert get, and Action get. Ask in plain English from your workspace; Viktor does the work in PostHog and reports back. Viktor connects natively.

- Tool: PostHog
- Category: Analytics
- Connection: Managed connector (native integration)
- Actions available: 300
- Currently available in: Slack, Microsoft Teams, and Discord
- Page: https://viktor.com/integrations/posthog

## What can your AI employee do in PostHog?

Viktor connects to your PostHog account and completes work in it. He doesn't just answer questions about PostHog, he takes the actions on your behalf and delivers the finished result to your workspace.

Unlike workflow builders such as Zapier or Make, there is nothing to configure - no triggers to map, no workflows to maintain. You describe the outcome in plain English, and Viktor picks the right PostHog actions, chains them with the other 9,800+ tools he connects to, and asks for approval before anything sensitive runs.

### About PostHog

Product analytics and feature flags (US cloud)

### How a run works

1. **You ask in your workspace** - Describe what you need in plain English
2. **Viktor picks the actions** - Selects from 300 PostHog actions, chains them together
3. **Runs in PostHog** - Helps you track product usage and feature adoption - your real data.
4. **Reports back** - Delivers the finished result to your workspace

## Use PostHog from Slack and Microsoft Teams

Message Viktor in a Slack channel, a Microsoft Teams chat or a direct message. He opens PostHog, does the work and posts the result in the same thread, so nobody has to switch tabs.

He can also run PostHog work on a schedule, like a weekly PostHog summary posted to your team's channel. Anything sensitive waits for your approval before it runs.

## Security and permissions

- Native integration - Viktor handles authorization itself, never sees your password, and you can revoke access at any time.
- Review-first approvals: sensitive PostHog actions wait for your sign-off before they run.
- Isolated compute per team, encrypted in transit and at rest - and your data is never used to train models.
- SOC 2 Type 1 compliant, with Type 2 and ISO 27001 in progress.
- Viktor is not affiliated with or endorsed by PostHog.

## What can you ask Viktor to do in PostHog?

- "Pull this week's activation funnel from PostHog and flag the biggest drop-off."
- "Investigate why a key metric dropped in PostHog last week and report what you find."
- "Build a report on the new feature's adoption in PostHog and post it every Monday."
- "Watch PostHog for a spike in a key metric and alert me with context."

## How does Viktor work with PostHog?

1. Open Viktor in a supported workspace.
2. Connect PostHog natively - Viktor handles authentication.
3. Ask in plain English. Viktor runs the PostHog actions, chains them with your other tools when needed, and reports back. Sensitive actions wait for your approval.

## What can Viktor do in PostHog? (300 actions)

- **Action create** - Create a new action in the project. Actions define reusable event triggers based on page views, clicks, form submissions, or custom events. Each action can have multiple steps (OR conditions). Use actions to create composite events for insights and funnels.
- **Action delete** - Delete an action by ID (soft delete - marks as deleted). The action will no longer appear in lists but historical data is preserved.
- **Action get** - Get a specific action by ID. Returns the action configuration including all steps and their trigger conditions.
- **Actions get all** - Get actions in the project. Actions are reusable event definitions that can combine multiple trigger conditions (page views, clicks, form submissions) into a single trackable event for use in insights and funnels. Supports pagination with limit and offset, case-insensitive name filtering with search, filtering by creator with createdby (comma-separated user ids), filtering by tag with tags (a JSON-encoded array of tag names), and sorting with ordering. Projects can have thousands of actions, so pass limit plus the relevant filters rather than fetching every action at once.
- **Action update** - Update an existing action by ID. Can update name, description, steps, tags, and Slack notification settings.
- **Activity log list** - List recent activity log entries for the project. Shows who did what and when — feature flag changes, dashboard edits, experiment launches, etc. Supports filtering by scope, user, and date range.
- **Activity logs list** - List recent activity logs for the project. Shows who changed what and when — includes feature flag updates, insight creations, dashboard modifications, experiment launches, and other project changes. Use scope parameter to filter by resource type (e.g. "FeatureFlag", "Insight", "Dashboard", "Experiment", "Survey", "Cohort"). Use itemid to filter changes for a specific resource. Returns results ordered by most recent first. Each result includes: user (who performed the action with firstname and email), activity (e.g. "created", "updated", "deleted"), scope (entity type like "FeatureFlag"), itemid (ID of the affected resource), detail (structured JSON with name, shortid, and a changes array where each change has type, action, field, before, and after values), and createdat timestamp.
- **Add insight to dashboard** - Add an existing insight to a dashboard. Requires insight ID and dashboard ID. Optionally supports layout and color customization.
- **Advanced activity logs filters** - Get the available filter options for activity logs — scopes, activity types, and users that have logged activity. Useful for building filter UIs or understanding what kinds of activity are tracked.
- **Advanced activity logs list** - List activity log entries — who changed what and when (feature flag changes, dashboard edits, experiment launches, insight edits, etc.), with field-level diffs. Filter by scope, activity type, user, item, date range, and free-text search. Use this to audit a specific resource's history or to see what changed recently across the project.
- **Agent feedback** - Send feedback about anything PostHog to the PostHog team. Set feedbacktype to route it: product (any PostHog product or feature — insights, session replay, feature flags, the data warehouse, web analytics, error tracking, etc.; put the area in productarea), mcp (this MCP server itself — a tool, input schema, response format, error, or these instructions; set category), docs, or other. ALL sentiments are welcome via sentiment (positive/neutral/negative/mixed) — praise and feature requests are useful signal, not just problems. Good triggers: a confusing or broken product experience, a papercut that slowed the task down, a missing capability you worked around, a feature request, an unhelpful error, or something that worked really well. Keep summary to one sentence and write the free-text fields as clear, concise bullet points, quoting the product surface, tool name, parameter, or error text where possible. Include a concrete suggestedimprovement whenever you can name one. Do not include user PII or sensitive query content. The user can also ask you to send feedback directly (e.g. 'make a PostHog feedback for this'). IMPORTANT: submitting feedback does NOT mean your work is done — keep going and finish the user's task using the other available tools. This tool is a side channel to the PostHog team, not a way to end the conversation.
- **Agent resolve resource** - Fetch a builder playbook — a markdown guide for using the agent-platform authoring tools well, returned with the live, scope-aware tool surface for the operation. Resolve the relevant one BEFORE a non-trivial operation (editing/promoting a revision, wiring secrets, authoring an agent, debugging a session). Many agent-applications- tool descriptions name the playbook to read first. Pass either a bare id or its posthog://agent-platform/playbooks/<id> URI — the resource parameter enumerates the available playbooks. Returns { id, uri, title, content } where content is the full markdown plus the tool surface.
- **Alert create** - Create a new alert on an insight. Alerts can use either threshold-based conditions or anomaly detection. For threshold alerts: set condition (absolutevalue, relativeincrease, relativedecrease) and threshold configuration with bounds — at least one of lower or upper is required (omit detectorconfig). For anomaly detection: set detectorconfig with a detector type (zscore, mad, iqr, threshold, copod, ecod, hbos, isolationforest, knn, lof, ocsvm, pca) and parameters like threshold (sensitivity 0-1, default 0.9) and window size. Ensemble detectors combine 2+ sub-detectors with AND/OR logic. Requires an insight ID and at least one subscribed user.
- **Alert delete** - Delete an alert by ID. This permanently removes the alert and all its check history. Subscribed users will no longer receive notifications.
- **Alert get** - Get a specific alert by ID. Returns the full alert configuration including check results, threshold settings, detectorconfig (for anomaly detection alerts), and subscribed users. Check results include anomalyscores, triggeredpoints, and triggereddates for detector-based alerts. By default returns the last 5 checks. Use checksdatefrom and checksdateto (e.g. '-24h', '-7d') to get checks within a time window, and checkslimit to control the maximum returned (default 5, max 500). When date filters are provided without checkslimit, up to 500 checks are returned. Check history is retained for 14 days.
- **Alert simulate** - Run an anomaly detector on an insight's historical data without creating any alert or check records. Use this to preview how a detector configuration would perform before saving it as an alert. Requires an insight ID and a detectorconfig object with a type (zscore, mad, iqr, copod, ecod, hbos, isolationforest, knn, lof, ocsvm, pca, or ensemble). Optionally specify datefrom (e.g. '-48h', '-30d') to control how far back to simulate, and seriesindex to pick which series to analyze. Returns data values, anomaly scores per point, triggered indices and dates, and for ensemble detectors, per-sub-detector score breakdowns.
- **Alerts list** - List all insight alerts in the project. Returns alerts with their current state, threshold or detector configuration, timing information, and firing check history. Supports filtering by insight ID (insightid), fuzzy name search (search), and creator (createdby user UUID). Alerts can use either threshold-based conditions (absolutevalue, relativeincrease, relativedecrease) or anomaly detection via detectorconfig (zscore, mad, iqr, isolationforest, knn, etc.).
- **Alert update** - Update an existing alert by ID. Can update name, threshold, condition, config, detectorconfig, subscribed users, enabled state, calculation interval, and weekend skipping. Set detectorconfig to switch to anomaly detection (trends and SQL insights), or set it to null to switch back to threshold mode (threshold mode requires at least one of lower or upper in threshold.configuration.bounds). For SQL-insight alerts the config is HogQLAlertConfig (column, evaluation 'lastrow'/'firstrow'/'anyrow', labelcolumn). To snooze an alert, set snoozeduntil to a relative date string (e.g. '2h', '1d'). To unsnooze, set snoozeduntil to null.
- **Annotation create** - Create an annotation to mark an important change (for example, a deployment) on charts and trends. Provide a note in content, when it happened in datemarker (ISO 8601), and whether it is scoped to the current project or the whole organization. Optionally set an emoji to show in place of the default badge on the chart.
- **Annotation delete** - Soft-delete an annotation by ID. This hides the annotation from normal lists while preserving historical records.
- **Annotation retrieve** - Retrieve a single annotation by ID from the current project. Use this when you already know the annotation ID and want complete details.
- **Annotations list** - List annotations in the current project, newest first. Use this to review existing deployment markers and analysis notes before adding new annotations. Results are paginated (default 100 per page) — use limit and offset to page through, and search to filter by annotation content. Each row's createdby is trimmed to {id, email}.
- **Annotations partial update** - Update an existing annotation by ID. You can change its text (content), when it happened (datemarker, ISO 8601), its visibility scope (project or organization), or its emoji. Only the fields you provide are updated.
- **Apm attribute breakdown** - Group spans by one attribute's value — the "what is different about the bad spans?" tool.
- **Apm attributes list** - List available span or resource attribute names. Use attributetype "spanattribute" for span-level attributes or "spanresourceattribute" for resource-level attributes (e.g. k8s labels). Use this to discover available attribute keys before building filters.
- **Apm attribute values list** - List values for a specific span or resource attribute key. Use to discover what values exist for a given attribute before building filters.
- **Apm services list** - List distinct service names that have emitted trace spans. Use to discover available services before filtering spans by service name.
- **Apm spans aggregate** - Aggregate trace span statistics grouped by (servicename, name) over a date window.
- **Apm spans count** - Return a scalar count of trace spans matching a filter set. Use this as a cheap pre-flight before query-apm-spans — if the count is large, narrow the filters (or set excludeAttributes) before pulling rows.
- **Apm spans duration histogram** - Trace counts per logarithmic duration bucket — the latency distribution of requests.
- **Apm spans sparkline** - Span counts over time — a zero-filled time series for trend and spike analysis.
- **Apm spans tree** - Aggregate trace span statistics as a call tree — one row per (parentservice, parentname) → (servicename, name) edge.
- **Apm trace get** - Fetch all spans for a specific trace by its hex trace ID. Returns the full span tree for the trace including parent-child relationships, timing, status information, and each span's attributes map. Each span carries selftimenano — its duration not covered by child spans — so "where did the wall-clock go" is answered by sorting on it: a large selftimenano on a parent span is an uninstrumented gap, not time in any child. Use this to inspect a specific trace in detail after discovering it via the query tool. Set excludeAttributes to true to drop the per-span attributes map (which can hold multi-KB values like db.statement) and keep the payload compact.
- **Approval policies list** - List all approval policies configured for this project. Shows which actions require approval, who can approve, and bypass rules.
- **Approval policy get** - Get details of an approval policy including conditions, approver configuration, quorum requirements, and bypass rules.
- **Batch export create** - Create a new batch export. Typed destination config schemas are available for Databricks and AzureBlob destinations — both require a team-scoped Integration (use integrations-list to find one). Other destination types are permitted by the API but typically must be created via the PostHog UI because their credentials are stored in the destination config. Always specify the model field (events, persons, or sessions) — omitting it defaults to events but the field should be set explicitly.
- **Batch export delete** - Soft-delete a batch export. Stops all future scheduled runs and hides the export from list and get operations. Historic run records remain attached to the deleted export in the database.
- **Batch export get** - Get a batch export by ID. Returns full non-sensitive configuration including destination type and config, linked Integration id (for Databricks and AzureBlob), schedule, model, and the 10 most recent runs.
- **Batch exports list** - List batch exports in the project. Batch exports send event, person, or session data on a schedule to destinations like S3, Snowflake, BigQuery, Databricks, Azure Blob, Postgres, Redshift, or HTTP. Returns destination type, interval, paused state, and non-sensitive config; credentials are never exposed. Use batch-export-get with the ID for full details including latest runs, query, and filters.
- **Batch export update** - Partially update a batch export. Top-level fields (name, paused, interval, schema, filters) work for any destination type. Destination config updates are only typed for Databricks and AzureBlob destinations. Do not change the model field on an existing export — the destination table schema is created on the first run, so switching models causes errors unless the table name is also changed.
- **Business knowledge document window retrieve** - Returns a window of content chunks from a business knowledge document, centered around a specific ordinal. Use after searching knowledge to get more surrounding context for a specific result.
- **Cdp functions create** - Create a new function. Requires 'type' (destination, sitedestination, internaldestination, sourcewebhook, warehousesourcewebhook, siteapp, or transformation) and either 'hog' source code or a 'templateid' to derive code from a template. Provide 'inputsschema' to define configurable parameters and 'inputs' with their values. Use 'filters' to control which events trigger the function. Transformations run during ingestion and have an 'executionorder' field.
- **Cdp functions delete** - Delete a function by ID (soft delete). The function will no longer appear in lists or process events, but historical data is preserved.
- **Cdp functions invocations create** - Test-invoke a function with a mock event payload. Sends the function configuration and test data to the plugin server for execution and returns logs and status. Use 'mockasyncfunctions: true' (default) to simulate external calls like fetch() without making real HTTP requests.
- **Cdp functions list** - List all functions (destinations, transformations, site apps, and source webhooks) in the project. Returns each function's name, type, enabled status, execution order, template info, and filters (the event/property filter expression that gates the function). Filter by type (destination, sitedestination, internaldestination, sourcewebhook, warehousesourcewebhook, siteapp, transformation) and enabled status via query parameters. Pagination caps at 100 per page by default — pass limit=1000 (max 1000) when scanning for an existing function by alert id, and follow the next link if more pages exist.
- **Cdp functions logs retrieve** - Retrieve execution logs for a specific CDP function by ID. Returns log entries with timestamp, level (DEBUG, LOG, INFO, WARN, ERROR), and message. Use to debug why a destination or transformation is failing or not producing expected results. Supports filtering by log level, text search, time range (after/before), and pagination via limit.
- **Cdp functions metrics retrieve** - Retrieve execution metrics for a specific CDP function by ID. Returns time-series data showing success and failure counts over a configurable interval (hour, day, or week). Use to understand function health, identify failure spikes, and monitor delivery reliability. Supports breakdown by metric kind (success/failure) or name, and time range filtering.
- **Cdp functions partial update** - Partially update a function. Can enable/disable the function, change its name, description, source code, inputs, filters, mappings, or masking config. The 'type' field cannot be changed after creation. To delete a function, use the cdp-functions-delete tool instead.
- **Cdp functions rearrange partial update** - Update the execution order of transformation functions. Send an 'orders' object mapping function UUIDs to their new executionorder integer values. Only applies to functions with type=transformation. Returns the updated list of transformations.
- **Cdp functions retrieve** - Get a specific function by ID. Returns the full configuration including source code, inputs schema, input values (secrets are masked), filters, mappings, masking config, and runtime status.
- **Cdp function templates list** - List available function templates. Templates are pre-built function configurations for common integrations (Slack, webhooks, email, etc.) and transformations (GeoIP, etc.). Filter by type (destination, sitedestination, siteapp, transformation, etc.) via the 'type' query parameter. Results are sorted by popularity (number of active functions using each template).
- **Cdp function templates retrieve** - Get a specific function template by its template ID (e.g. 'template-slack', 'template-geoip'). Returns the full template including source code, inputs schema, default filters, and mapping templates. Use this to understand what inputs a template requires before creating a function from it.
- **Change request get** - Get a specific change request by ID, including the full intent, policy snapshot, approval votes, and current state.
- **Change requests list** - List approval requests (change requests) for the current project. Returns pending, approved, rejected, and expired requests with vote status and staleness info. Useful for understanding what governance actions are waiting for review.
- **Cohorts add persons to static cohort partial update** - Add persons to a static cohort by their UUIDs. Only works for static cohorts (isstatic: true).
- **Cohorts create** - Create a cohort (a saved group of persons). Two kinds.
- **Cohorts list** - List all cohorts in the project. Returns a summary of each cohort including id, name, description, count (person count), isstatic (cohort type), and createdat timestamp. To find a cohort by name, pass 'search' rather than listing everything and filtering client-side — it matches the cohort name with fuzzy trigram search (tolerates typos and partial words) and orders exact matches first. Use 'cohorts-retrieve' with the cohort ID to get full details including filters, calculation status.
- **Cohorts partial update** - Update an existing cohort's name, description, or filters. Changing filters on a dynamic cohort triggers recalculation. To soft-delete a cohort, set 'deleted: true'.
- **Cohorts retrieve** - Get a specific cohort by ID. Returns the cohort name, description, filters (for dynamic cohorts), count of matching users, and calculation status.
- **Cohorts rm person from static cohort partial update** - Remove a person from a static cohort by their UUID. Only works for static cohorts (isstatic: true). The person must exist in the project. Idempotent: removing a person who exists but is not a member of the cohort succeeds silently.
- **Comment count** - Get the count of comments, optionally filtered by scope and itemid.
- **Comment get** - Get a specific comment by ID including its content, rich content with mentions, and metadata.
- **Comments list** - List comments across the project. Filter by scope (Dashboard, FeatureFlag, Insight, etc.) and itemid to find discussions on specific resources. Returns comment content, author, and threading info.
- **Comment thread** - Get the full thread of replies for a parent comment. Useful for reading complete discussions on a resource.
- **Conversations tickets list** - List support tickets in the project. Supports filtering by status (new, open, pending, onhold, resolved), priority (low, medium, high), channelsource (widget, email, slack), assignee, date range, and search. Results are paginated and ordered by updatedat descending by default. Returns ticket metadata including status, priority, message counts, and timestamps.
- **Conversations tickets messages retrieve** - Return a support ticket's message thread, ordered chronologically. The response is paginated (default 50, max 200 per page) — use the limit and offset query params to page through long threads, and read count/next from the response envelope. Includes all messages from the customer, team members, and AI, as well as private internal notes. Each message contains authortype, authorname, content, and an isprivate flag indicating internal notes.
- **Conversations tickets reply create** - Post a reply or internal note to a support ticket. IMPORTANT: With isprivate=false (the default), the reply IS DELIVERED to the customer via the ticket's channel (email, Slack, Teams, or GitHub). Set isprivate=true to store an internal note visible only to team members.
- **Conversations tickets retrieve** - Get a specific support ticket by ID or ticket number. Returns full ticket details including status, priority, assignee, message count, channel info, person data, and session context.
- **Conversations tickets update** - Update a support ticket. Can change status (new, open, pending, onhold, resolved), priority (low, medium, high), assignee, SLA deadline, escalation reason, and tags. Assignee should be an object with type ('user' or 'role') and id, or null to unassign.
- **Create feature flag** - Create a feature flag in the current project.
- **Dashboard create** - Create a new dashboard. Provide a name and optional description, tags, and pinned status. Can also create from a template or duplicate an existing dashboard. The returned tiles omit insight results to save context — use dashboard-insights-run to fetch the actual data for each insight. To add widget tiles after creation, see dashboard-widget-catalog-list for available widget types and dashboard-widgets-batch-add to add them.
- **Dashboard create text tile** - Add a markdown text tile to a dashboard. Text tiles render as markdown blocks — useful as section headings, dividers, or annotations between insight tiles to give a dashboard structure. The desktop grid is 12 columns wide; a typical heading uses a thin full-width banner (e.g. layouts.sm = {x: 0, y: 0, w: 12, h: 1}). If layouts is omitted, the tile is placed using the default layout — use dashboard-reorder-tiles afterwards if you need precise placement.
- **Dashboard delete** - Delete a dashboard by ID. The dashboard will be soft-deleted and no longer appear in lists.
- **Dashboard delete tile** - Soft-delete a single tile (text, insight, widget, or button) from a dashboard. Behaves the same as the delete button in the UI — the underlying Insight, Text, ButtonTile, or widget row is preserved (so an insight that lives on multiple dashboards stays on the others), and the remaining tiles are automatically compacted upward to fill the gap left by the deleted tile (matching the dashboard grid's layout). Pass the DashboardTile id as tileid (use dashboard-get to look up tile IDs). To remove the whole dashboard instead, use dashboard-delete.
- **Dashboard get** - Get a specific dashboard by ID. Returns the full dashboard including all tiles with their insights, widget configurations, and layout information. Widget tiles include a widget object with widgettype and config but no live data — use dashboard-widgets-run with tile IDs from this response. Insight results, filters, and query metadata are omitted to save context — use dashboard-insights-run to fetch the actual data for every insight on the dashboard in one call, or insight-query for a single insight. Supports variablesoverride and filtersoverride query params; on this endpoint they affect only the merged filters and variables fields in the response (preview). To execute insights with the same overrides, pass the same query params to dashboard-insights-run.
- **Dashboard insights run** - Run all insights on a dashboard and return their results. Uses cached results by default (may be stale); set refresh to 'blocking' for fresh results. Set format to 'optimized' (default) for LLM-friendly text tables or 'json' for raw query results. Supports variablesoverride and filtersoverride query params to run insights with one-off overrides without persisting; see the parameter descriptions for the exact JSON shape required.
- **Dashboard reorder tiles** - Reorder tiles on a dashboard by providing an array of tile IDs in the desired display order. First, use dashboard-get to see current tile IDs. By default existing tile widths and heights are preserved; see the layout parameter to force a 2-column or full-width grid instead.
- **Dashboards get all** - List dashboards in the project. The optional search parameter runs a fuzzy match against name and description using Postgres trigram word similarity (handles typos, transpositions, and prefix-as-you-type) and returns results ranked by relevance — use it to find a specific dashboard by name rather than paging through every dashboard. search is capped at 200 characters; longer queries return a 400 error. Optional filters by tag and pinned status are also supported. Returns name, description, pinned status, tags, and creation metadata. Tiles and insights are not included — use dashboard-get to fetch a dashboard's tiles, then dashboard-insights-run to fetch the actual data for each insight.
- **Dashboards move tile partial update** - Move a tile from the source dashboard (path ID) to another dashboard. Provide todashboard (destination dashboard ID) and tile.id (tile ID from dashboard-get). Works for insight, text, and widget tiles; widget tiles require the dashboard-widgets feature flag on the project.
- **Dashboard tile copy** - Copy an insight, text card, or widget tile from one dashboard to another. The path dashboard ID is the destination. Provide fromDashboardId (source dashboard) and tileId (tile to copy). Widget tiles require the dashboard-widgets feature flag and are deep-cloned with a new widget row.
- **Dashboard update** - Update an existing dashboard by ID. Can update name, description, pinned status, tags, filters, and restriction level, and widget tile placement (layouts, showdescription). To change a widget's own settings (config, name, description), prefer dashboard-widgets-batch-update, which takes just a tileid per widget. You can also update widget tiles here by passing tiles with each tile's id and nested widget.id plus fields to change (config, name, description) from dashboard-get — the same PATCH path the UI uses. To add new widget tiles to this dashboard, use dashboard-widgets-batch-add instead. The returned tiles omit insight results to save context — use dashboard-insights-run to fetch the actual data for each insight.
- **Dashboard update text tile** - Update the markdown body, layout, or color of an existing text tile on a dashboard. Pass the DashboardTile id as tileid (use dashboard-get to look up tile IDs). Only the fields you provide are updated; omitted fields are left unchanged.
- **Dashboard widget catalog list** - List registered dashboard widget types with labels, descriptions, and per-type configschema. Use before dashboard-widgets-batch-add to pick a widgettype and shape config. Each type documents its own config keys under configschema (shared keys include limit, orderBy, orderDirection, dateRange, filterTestAccounts, and optional widgetFilters).
- **Dashboard widgets batch add** - Add widget tiles to a dashboard atomically via POST .../widgets/batch/ (1–10 tiles). Call dashboard-widget-catalog-list first for valid widgettype values and configschema. Pass widgets as an array of payloads (widgettype, config, optional name, description, layouts). Config shape is per widgettype (see catalog hints); widgetFilters when supported is a map of filter id to property filter entries. For a single tile, pass a one-element widgets array. Tiles stack at the bottom when layouts are omitted. Returns all created tiles; use dashboard-widgets-run to fetch live data. This only adds new tiles — to edit existing widget tiles, use dashboard-widgets-batch-update (no delete-and-re-add needed).
- **Dashboard widgets batch update** - Update the settings of existing widgets in place atomically (1–10), without delete-and-re-add. Edits widget settings only — config, name, and description. Pass widgets as an array of payloads, each identified by its DashboardTile tileid (use dashboard-get to look up widget tile IDs) plus the settings to change. Only the fields you provide per widget are updated; omitted fields are left unchanged. Optionally pass widgettype to get the typed config shape; widgettype is immutable. Config shape is per widgettype — see dashboard-widget-catalog-list. All updates succeed or fail together. Tile placement (layout, showdescription) is not changed here — use dashboard-update or dashboard-reorder-tiles for that. To add new widgets, use dashboard-widgets-batch-add; to remove one, use dashboard-delete-tile.
- **Dashboard widgets run** - Run live queries for dashboard widget tiles and return results. Requires the dashboard-widgets feature flag. Call dashboard-get first to find widget tile IDs (tiles with a widget field). Pass tileids as a comma-separated list. Each successful result is a widget-type-specific payload (see runwidgets OpenAPI response and dashboard-widget-catalog-list configschema). Returns per-tile errors when the caller lacks product access for a widget type (see requiredproductaccess on dashboard-widget-catalog-list). Not available on public/shared dashboard views.
- **Data warehouse data health issues retrieve** - Return all failed or degraded items across the data pipeline: materialized saved queries that failed, external data schemas in Failed or BillingLimitReached state, sources in Error state, failed batch exports, and disabled/degraded transformations. Each entry includes id, name, type (materializedview, externaldatasync, source, destination, transformation), status, error message, failedat, and url. Use this for a one-shot audit of what's broken in a project's data warehouse.
- **Data warehouse source connect link** - Return a secure browser link to connect a data warehouse source WITHOUT the user pasting secrets into the chat. The link opens a minimal page rendering the source's full connection form — the user authorizes via OAuth or enters credentials there, whichever the source offers — and the page stores the connection details encrypted and temporarily; it does NOT create the source. This is the preferred, secure way to collect credentials: share the returned connecturl with the user, wait for them to confirm they're done, then find the stored credential via 'data-warehouse-stored-credentials-list' (filter by sourcetype, newest first) and call 'data-warehouse-source-setup' with {'credentialid': '<uuid>'} in the payload. Stored credentials are single-use and expire after 24 hours. Never ask the user to paste raw database passwords, API keys, or OAuth tokens into the chat.
- **Data warehouse source setup** - Reach for this the moment a user wants to analyze data PostHog doesn't store — Stripe revenue, Hubspot or Salesforce CRM, Zendesk tickets, Shopify orders, or their own Postgres/MySQL/BigQuery/Snowflake database. Connect an external data source and start importing it into queryable warehouse tables in a single call. Validates credentials, discovers all available tables, enables them with sensible sync defaults (incremental where supported to keep ongoing cost low), and creates the source — no 'schemas' array required. For webhook-capable sources (e.g. Stripe) a webhook is auto-registered after creation: check the 'webhook' key in the response — on success webhook-capable tables sync in real time (including webhook-only tables like Stripe Discount); on failure (e.g. the API key can't create webhooks) tables keep the polling defaults and webhook-only tables stay disabled. If 'webhook.pendinginputs' is non-empty, ask the user for those values and submit them via 'external-data-sources-update-webhook-inputs-create'. Use this for revenue (Stripe), CRM (Hubspot, Salesforce), support tickets (Zendesk), e-commerce (Shopify), and your own databases (Postgres, MySQL, BigQuery, Snowflake). Discover required credential fields per sourcetype with 'external-data-sources-wizard'. Prefer references over raw secrets in the payload: pass {'credentialid': '<uuid>'} referencing the connection details the user stored via the 'data-warehouse-source-connect-link' page (discover ids with 'data-warehouse-stored-credentials-list'); stored credentials are deleted once the source is created. For an already-connected OAuth integration you can instead pass its integration id key (e.g. {'hubspotintegrationid': 123}). NOTE: this enables EVERY discovered table — ideal for small fixed schemas (Stripe, Zendesk) but on a large production database (a Postgres/MySQL/BigQuery/Snowflake with many tables) it syncs them all, which can be costly and noisy. When the user wants only specific tables, or non-default sync types per table, use 'external-data-sources-create' instead.
- **Data warehouse stored credentials list** - List credentials the user stored via the 'data-warehouse-source-connect-link' page that haven't been consumed yet. Returns metadata only (credentialid, sourcetype, createdat, expiresat) — never the secrets themselves. Newest first; filter by sourcetype. After the user confirms they've finished the connect page, take the newest credentialid for the source type and call 'data-warehouse-source-setup' with {'credentialid': '<uuid>'} in the payload. Stored credentials are single-use — they are deleted as soon as setup consumes them — and expire after 24 hours if never used.
- **Debug mcp ui apps** - Debug tool for testing MCP Apps SDK integration. Returns sample data displayed in an interactive UI app with component showcase. Use this to verify that MCP Apps are working correctly.
- **Delete feature flag** - Soft-delete a feature flag by ID in the current project.
- **Demo mcp ui apps** - Demo tool for testing MCP Apps SDK integration. Returns sample data that is displayed in an interactive UI app. Use this to verify that MCP Apps are working correctly.
- **Desktop file system canvas partial update** - Publish the React source for a freeform canvas (a "dashboard" item on the desktop surface). The id is the canvas/dashboard id. Pass the COMPLETE single-file React source in code — each call replaces the live code and appends a new version to the canvas's history. This is how a canvas-generation task saves its result; do not write a local file.
- **Desktop file system create** - Create a new channel (folder) on the desktop surface. Pass a slash-delimited path (parent folders are created automatically) and type: folder. A blank instruction set is created for the channel automatically; use the desktop-file-system-instructions-partial-update tool to fill it in.
- **Desktop file system instructions partial update** - Publish a new version of a channel's markdown instructions, describing what the channel contains. The id is the channel (folder) id. Each call creates a new version. To erase a channel's instructions, publish empty content — this clears the text while keeping the instruction set in place (the instruction set itself cannot be deleted).
- **Desktop file system instructions retrieve** - Get the latest markdown instructions for a channel (desktop folder).
- **Desktop file system list** - List channels and items on the desktop surface. Filter with query params such as type (e.g. "folder"), parent, path, depth, or search.
- **Desktop file system retrieve** - Retrieve a single channel or item on the desktop surface by id.
- **Docs search** - Use this tool for any PostHog questions to search the documentation. If the user's question mentions multiple topics, search for each topic separately and combine the results. It relies on a hybrid (semantic + full-text) search, so phrase your query in natural language. Our product and docs change often, so this tool is required for accurate answers.
- **Early access feature create** - Create a new early access feature. A feature flag is automatically created unless featureflagid is provided. Stage determines whether opted-in users get the feature enabled.
- **Early access feature destroy** - Delete an early access feature by ID. Clears enrollment conditions from the linked feature flag but does not delete the flag itself.
- **Early access feature list** - List early access features in the current project. Returns name, stage, description, linked feature flag, and creation date for each feature.
- **Early access feature partial update** - Update an early access feature by ID. Changing the stage automatically updates the linked feature flag's enrollment conditions.
- **Early access feature retrieve** - Get a single early access feature by ID. Returns full details including the linked feature flag configuration.
- **Elements stats retrieve** - Counts of autocapture clicks, rage clicks, and dead clicks grouped by page element, ordered by count. Each result carries the parsed element chain (tag, text, href, attributes) of the clicked element. Filter by date range, event types, URL or other event/person properties, and the project's internal-test-account filters. This powers heatmap/clickmap views; use it to answer "what do users click most" and "which elements get rage or dead clicks". Responses can be very large on busy projects — always pass a small limit (e.g. 100) and paginate with offset if you need more results.
- **Endpoint create** - Create a new API endpoint from a HogQL or insight query. The name must be URL-safe (letters, numbers, hyphens, underscores, starts with a letter, max 128 chars). Materialization is auto-enabled if the query is eligible.
- **Endpoint delete** - Delete an endpoint by name. The endpoint is soft-deleted and its materialized views are cleaned up.
- **Endpoint get** - Get a specific endpoint by name. Returns the full endpoint configuration including query definition, version info, materialization status, and column types. Supports ?version=N to retrieve a specific version.
- **Endpoint logs** - Retrieve execution logs for an endpoint by name. Each run emits one entry with a timestamp, level (INFO or ERROR), and a message whose extra data is in key=value tokens (path=materialized|inline|ducklake, cache=hit|miss, durationms=, rows=, version=, error=). Filter by level (e.g. "ERROR"), text search (e.g. "cache=miss"), time range (after/before), a specific execution (instanceid), and limit (max 500). Use to debug why an endpoint failed, timed out, missed cache, or returned unexpected row counts.
- **Endpoint materialization status** - Get lightweight materialization status for an endpoint without fetching full endpoint data. Returns whether materialization is possible, current status, last run time, and any errors. Supports ?version=N.
- **Endpoint openapi spec** - Get the OpenAPI 3.0 specification for an endpoint. Returns a JSON spec that can be used with SDK generators like openapi-generator or @hey-api/openapi-ts to create typed API clients. Supports ?version=N to generate a spec for a specific version.
- **Endpoint run** - Execute an endpoint's query and return results. Uses materialized results when available, otherwise runs inline. For HogQL endpoints, variable keys must match codename values. For insight endpoints with breakdowns, use the breakdown property name as the key.
- **Endpoints get all** - Get all API endpoints in the current project. Endpoints expose saved HogQL or insight queries as callable API routes. Returns name, description, query, active status, current version, and materialization info for each endpoint.
- **Endpoints last execution times** - Get the most recent execution time per endpoint (endpoint-level, personal API key calls only). Pass an array of endpoint names; returns rows shaped [name, lastexecutedat]. Endpoints never called are omitted from the response. Use this for a quick endpoint-level recency check during an audit; for per-version usage or history, query the querylog table with execute-sql.
- **Endpoints materialization preview** - Preview the materialization transform for an endpoint before enabling it. Returns the transformed HogQL, detected range pairs, and aggregate re-aggregation info, plus a rejection reason if the query is not eligible. Supports an optional version body param. Read-only — does not enable materialization.
- **Endpoint update** - Update an existing endpoint by name. Can update the query (auto-creates a new version), description, data freshness, active status, and materialization. Pass version in body to target a specific version for non-query updates.
- **Endpoint versions** - List all versions for an endpoint, in descending order (latest first). Each version contains the query snapshot, description, data freshness, last execution time, and materialization status at that point in time.
- **Engineering analytics ci failure logs** - The thinned CI failure logs for a pull request, grouped by failed job — reach for this to answer "why did this PR's CI fail". Each failed job returns its failure region (the error lines plus surrounding context, with "... N lines omitted ..." markers) as ordered lines, and every line carries its original 1-based line number in the full pre-thinning log so you can locate it in the raw GitHub log. The PR is resolved to ALL its workflow runs across every push (via the pullrequests association, not the latest commit), so earlier pushes' failures are included too. logsavailable is false when CI hasn't failed, the logs aged out of the short Logs retention, or a fork PR has no run association to resolve. Use pr-runs or workflow-jobs for the run/job metadata behind these logs.
- **Engineering analytics flaky tests** - Backend tests ranked by flakiness signal over a window (datefrom default -7d, maximum 30 days), from the per-test CI spans. A test qualifies by passing on an automatic retry at least minrerunpasses times (default 1) OR failing on at least minfailedprs distinct pull requests (default 3). Use this for "which tests are flaky right now" and to pick quarantine candidates. Read the counts as absolute signal, never rates — fast passing runs are not emitted, so there is no honest denominator. rerunpassedcount only flows from CI lanes running with retries enabled; in other lanes a flake surfaces as a plain failure, which failedprcount catches. xfailedcount > 0 means the test is already quarantined but still failing. nodeid is a best-effort reconstruction (no '.py' suffix, the file/class boundary folded into '/'), so convert before using it as a pytest selector.
- **Engineering analytics pr cost** - Estimated CI dollar cost of one pull request, summed over the jobs of all its workflow runs, with breakdowns per workflow (byworkflow) and per run (byrun). Reach for this instead of summing runner minutes by hand: the estimate already classifies runners (billable self-hosted Linux vs free GitHub-hosted), applies the per-vCPU price ladder, and excludes non-Linux and provider-hosted jobs. jobsavailable is false when the job-level source isn't synced yet — every figure is then zero/null, so check it before trusting a $0.00. estimatedcostusd is null (not zero) when nothing was costable, and unsettledjobs counts billable jobs still running that are left out of the estimate.
- **Engineering analytics sources** - The team's connected GitHub data warehouse sources, oldest first, each with its id, repo (owner/name), and table prefix. Call this first when a team may have more than one GitHub source, then pass a chosen id as sourceid to the pull-requests, workflow-health, ci-cards, or pr-lifecycle tools to read that specific source. With a single source you can skip it — the other tools default to the oldest connected source.
- **Engineering analytics workflow jobs** - The jobs of a single workflow run attempt, each with its status, conclusion, wall-clock durationseconds, runner tier (runnerprovider / runnerlabel), and estimatedcostusd. Use this to see where a run spent its time and money job-by-job, or to find the slow or expensive job in a run. Scoped to one runattempt (the latest unless you pass runattempt) so a re-run's attempts don't merge. estimatedcostusd is null for free GitHub-hosted, non-Linux, or unfinished jobs. Returns an empty list when the job-level source isn't synced yet.
- **Engineering analytics workflow runner costs** - One workflow's estimated CI cost broken down by runner tier over a window (datefrom default -30d), highest spend first. Each row is a tier (provider + runnerlabel) with its jobcount, billableminutes, and estimatedcostusd. Use this for "which runner tier drives this workflow's CI bill" and to spot oversized runners. Billable self-hosted Linux tiers carry a cost; github-hosted and non-Linux rows are null. Returns an empty list when the job-level source isn't synced yet.
- **Entity search** - Search for PostHog entities by name or description. Can search across multiple entity types including insights, dashboards, experiments, feature flags, notebooks, actions, cohorts, event definitions, and surveys. Use this to find entities when you know part of their name. Returns matching entities with their IDs and URLs.
- **Error details** - Use this tool to get the details of an error in the project.
- **Error tracking alerts create** - Create an error tracking alert that fires when an issue is created, reopened, or starts spiking. An alert is a HogFunction with type=internaldestination whose filters.events references one of the three error-tracking lifecycle events. The events themselves are the trigger — there is no threshold or evaluation window to configure.
- **Error tracking alerts delete** - Delete an error tracking alert by ID (soft delete). The alert stops firing immediately, but the HogFunction row and its execution history are preserved. To re-enable a deleted alert, the user must re-create it; partial-update with enabled=true will not resurrect a soft-deleted alert.
- **Error tracking alerts list** - List error tracking alerts in the project. Pass type=internaldestination and inspect each entry's filters.events for one of $errortrackingissuecreated, $errortrackingissuereopened, or $errortrackingissuespiking to identify alerts. The same endpoint backs cdp-functions-list, so non-error-tracking destinations are also returned — filter client-side by event id. Pagination defaults to 100 per page; pass a higher limit (e.g. 1000) when scanning for an existing alert by trigger and channel.
- **Error tracking alerts partial update** - Partially update an error tracking alert. Use to enable or disable an alert, rename it, change the destination channel/URL, or adjust the Slack message body. The type field cannot be changed after creation. To delete an alert, use error-tracking-alerts-delete. To change the trigger event, set filters.events to a list with the new event id — but consider creating a new alert instead so the old one's history is preserved.
- **Error tracking assignment rules create** - Create an error tracking assignment rule for the current project. Provide filters to match incoming errors and an assignee with type (user or role) plus the matching user ID or role UUID.
- **Error tracking assignment rules list** - List error tracking assignment rules for the current project. Returns rules in evaluation order with their filters, assignee, and disabled state. Supports pagination with limit and offset.
- **Error tracking bypass rules create** - Create a rate limit bypass rule for the current project. Exception events matching the rule skip both the project-wide and per-issue exception rate limits and are always ingested. Provide filters with at least one condition — empty match-all rules are rejected; to stop rate limiting entirely, update the rate limits via error-tracking-settings-update instead. Keep filters scoped to the specific errors that must never be dropped: bypassed events are ingested and billed even during error spikes, so a broad rule can cause unbounded volume.
- **Error tracking bypass rules list** - List rate limit bypass rules for the current project. Exception events matching a rule skip the project-wide and per-issue exception rate limits. Returns rules in evaluation order with their filters and disabled state. Supports pagination with limit and offset.
- **Error tracking bypass rules update** - Update a rate limit bypass rule's filters by ID. Omit filters to leave them unchanged. Editing the rule also clears any auto-disable state so the rule is re-enabled. Broadening filters exempts more exception events from rate limiting, which can increase ingested (and billed) volume during error spikes — keep them scoped to the specific errors that must never be dropped.
- **Error tracking external references create** - Create a new external issue in GitHub, GitLab, Linear, or Jira, then link it to a PostHog error tracking issue as an external reference. This tool does not link an existing external issue by URL or key. Provide the error tracking issue id as issue, the connected integration as integrationid, and a config object with provider-specific fields.
- **Error tracking grouping rules create** - Create an error tracking grouping rule for the current project. Provide required filters, and optionally set assignee and description for the issues this rule creates.
- **Error tracking grouping rules list** - List error tracking grouping rules for the current project. Returns rules in evaluation order with their filters, optional assignee, description, and linked issue when available.
- **Error tracking grouping rules update** - Update an error tracking grouping rule's filters by ID. Omit filters to leave them unchanged. Editing the rule also clears any auto-disable state so the rule is re-enabled.
- **Error tracking issues list** - List all error tracking issues in the project. Returns issues with id, status, name, first seen timestamp, and assignee info.
- **Error tracking issues merge create** - Merge one or more error tracking issues into an existing target issue. Provide the target issue as id and the issues to merge into it as ids.
- **Error tracking issues partial update** - Update an error tracking issue. Can change status (active, resolved, suppressed), assign to a user, or update description.
- **Error tracking issues retrieve** - Get a specific error tracking issue by ID. Returns full issue details including status, description, volume, and metadata. After retrieving an issue, consider using query-session-recordings-list with an event filter for $exception to find session recordings of users who hit this error.
- **Error tracking issues split create** - Split one or more fingerprints out of an existing error tracking issue into new issues. Provide the source issue as id and the fingerprints to split as fingerprints, where each entry includes a required fingerprint and optional name or description.
- **Error tracking recommendations list** - List error tracking recommendations for the current project. Each row is a server-computed suggestion with a fixed type and a type-specific meta payload.
- **Error tracking settings get** - Get the error tracking ingestion settings for the current project. Returns the project-wide and per-issue exception rate limits, where each ratelimitvalue is the maximum events ingested per bucket and each ratelimitbucketsizeminutes is the bucket window. A null ratelimitvalue means no limit is set. Read these before updating so you can preserve the fields you don't intend to change.
- **Error tracking settings update** - Update the error tracking ingestion settings for the current project. Only the fields you include are applied; omitted fields keep their existing values. Use this to set the project-wide rate limit (projectratelimitvalue events per projectratelimitbucketsizeminutes) and the per-issue rate limit (perissueratelimitvalue events per perissueratelimitbucketsizeminutes). Set a ratelimitvalue to null to remove that limit. WARNING: exception events above a rate limit are dropped at ingestion and cannot be recovered. Lowering a limit silently discards volume — confirm the threshold with the user before reducing it.
- **Error tracking suppression rules create** - Create an error tracking suppression rule for the current project. WARNING: matching errors are suppressed indefinitely — dropped at ingestion and will not appear as issues until the rule is disabled or deleted. Scope filters tightly to the exact exception type, message, URL, or properties you want gone. Do NOT create match-all rules (omitting filters) or broad rules — they silently swallow unrelated errors and cause data loss that is hard to detect after the fact. If unsure, set samplingrate below 1.0 so only a fraction of matches are dropped (e.g. 0.5 drops half) rather than all of them. Confirm with the user before creating any rule that could match more than one distinct error.
- **Error tracking suppression rules list** - List error tracking suppression rules for the current project. Returns rules in evaluation order with their filters, sampling rate, and disabled state. Supports pagination with limit and offset.
- **Error tracking suppression rules update** - Update an error tracking suppression rule by ID. Only the fields you include in the request body are applied; omitted fields keep their existing values. Supports updating filters and samplingrate. WARNING: broadening filters will start dropping additional events at ingestion silently. Keep filters tightly scoped to the exact errors you want gone. Prefer raising samplingrate to dampen volume over widening the match. Confirm with the user before changing a rule's filters in a way that could match more than one distinct error.
- **Error tracking symbol sets download retrieve** - Get a presigned download URL for a source map symbol set by ID. The URL expires after one hour. Use it immediately, and do not echo it back unless the user explicitly asks. If you only have a symbol set reference, call error-tracking-symbol-sets-list with the exact ref first.
- **Error tracking symbol sets list** - List source map symbol sets for the current project. Supports pagination plus filtering by exact ref or upload status (valid, invalid, or all) and sorting with orderby. Each result includes hasuploadedfile so you can tell whether the download tool will work.
- **Error tracking symbol sets retrieve** - Get a source map symbol set by ID. If you only have a symbol set reference, call error-tracking-symbol-sets-list with the exact ref first.
- **Evaluation config get** - Retrieve the team's evaluation configuration, including the active LLM provider key used to run llmjudge evaluations and remaining trial credits. Call this before creating an llmjudge evaluation to verify the team has either trial credits available or an active provider key configured — without one, llmjudge runs will fail. Returns trial limits, the active provider key (or null if on trial credits), and timestamps.
- **Evaluation config set active key** - Assign the LLM provider key used to run llmjudge evaluations team-wide. Pass keyid (UUID of an existing provider key whose state is 'ok'). Switching the active key affects every llmjudge evaluation that doesn't pin its own key. The key must already be in the 'ok' state — if it isn't, ask the user to validate it from the PostHog UI before retrying.
- **Evaluation create** - Create a new LLM evaluation. For 'llmjudge' type, provide evaluationconfig.prompt and modelconfiguration (provider + model). For 'hog' type, provide evaluationconfig.source (Hog code returning a boolean). When enabled, the evaluation runs automatically on new $aigeneration events. Results appear as '$aievaluation' events.
- **Evaluation delete** - Soft-delete an LLM evaluation. The evaluation stops running and is hidden from list views. Historical evaluation results ($aievaluation events) are preserved.
- **Evaluation get** - Get a specific LLM evaluation by its UUID. Returns the full evaluation configuration including type, config, output type, enabled status, and model configuration.
- **Evaluation judge models** - List the provider+model combinations supported for llmjudge evaluations. Pass a provider query parameter (one of openai, anthropic, gemini, openrouter, fireworks, azureopenai) and optionally keyid to scope the list to deployments reachable with a specific provider key (mainly relevant for azureopenai). Each entry returns the model id and whether it is available on PostHog trial credits. Call this before creating an llmjudge evaluation when the user has not specified a model, so a valid provider+model combination is chosen.
- **Evaluation report create** - Create an evaluation report configuration. Reports summarize recent evaluation runs (using AI).
- **Evaluation report delete** - Soft-delete an evaluation report configuration. The report stops firing and is hidden from list views; historical report runs are preserved. Equivalent to calling evaluation-report-update with deleted=true — that update path is the canonical way to soft-delete and is the only option when you also want to change other fields in the same call.
- **Evaluation report generate** - Immediately trigger an AI-generated evaluation report for this report config. Enqueues a Temporal workflow that analyzes recent evaluation runs and delivers the report to configured targets (email or Slack). Returns 202 on success. Duplicate requests within the same minute are coalesced — only one report is generated. Rate-limited by dailyruncap.
- **Evaluation report get** - Get a specific evaluation report configuration by UUID. Returns the full config including frequency, delivery targets, trigger thresholds, and schedule settings.
- **Evaluation report runs list** - List the run history for a specific evaluation report config. Each run record includes the generated report content, the evaluation period covered, delivery status ('pending', 'delivered', 'failed'), and any delivery error details.
- **Evaluation reports list** - List all evaluation report configurations for the current project. Optionally filter by evaluation UUID using the 'evaluation' query param. Each report config controls how and when evaluation summary reports are generated and delivered (email or Slack).
- **Evaluation report update** - Partially update an evaluation report configuration. Toggle enabled/disabled, update delivery targets (email or Slack), or switch frequency between 'everyn' and 'scheduled'. For 'everyn' mode set triggerthreshold (10–10000) and optionally cooldownminutes (60–1440); for 'scheduled' mode set rrule and startsat. Set deleted=true to soft-delete the config.
- **Evaluation run** - Manually trigger an evaluation run for a specific $aigeneration event. Enqueues a Temporal workflow that asynchronously executes the evaluation and stores the result as a '$aievaluation' event. Returns a workflowid and status "started". Pair with execute-sql to query results: SELECT FROM events WHERE event = '$aievaluation'.
- **Evaluations get** - List all LLM evaluations for the current project. Optionally filter by name/description search or enabled status. Evaluations automatically score $aigeneration events for quality, relevance, safety, and other criteria. Two types are supported: 'llmjudge' (LLM scores outputs against a prompt) and 'hog' (deterministic Hog code). Results are stored as '$aievaluation' events.
- **Evaluation test hog** - Test Hog evaluation source code against a sample of recent $aigeneration events without saving. Returns per-event results (pass/fail/N/A), reasoning, and input/output previews. Use this to validate Hog code before creating or updating a 'hog' type evaluation.
- **Evaluation update** - Update an existing LLM evaluation (partial update). Toggle enabled/disabled, update the evaluation config (prompt or Hog source), or change the model configuration.
- **Event definitions list** - List all event definitions in the project with optional filtering. Can filter by search term.
- **Event definition update** - Update event definition metadata. Can update description, tags, mark status as verified or hidden. Use exact event name like '$pageview' or 'usersignedup'.
- **Exec** - SKILLS FIRST — this server is the authoritative source of PostHog agent skills. Before answering any PostHog product or data question — including questions about PostHog's own behavior, warnings, thresholds, or internals — run learn -s "<task keywords>" here and load the matching skills. Never answer such questions by cloning, grepping, or web-searching PostHog source or docs: they may not match this instance.
- **Execute sql** - Executes HogQL — PostHog's variant of SQL that supports most of ClickHouse SQL. "HogQL" and "SQL" are used interchangeably.
- **Experiment archive** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment calculate running time** - Estimate the recommended sample size and how many days an experiment needs to run to detect an effect. This is a stateless statistical calculation — it does not read or modify any experiment, so it works for planning before an experiment exists.
- **Experiment copy to project** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment create** - RULES (follow before calling).
- **Experiment delete** - Delete an experiment by ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Always confirm by name before deleting.
- **Experiment duplicate** - Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment end** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment get** - Get a single experiment by ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first.
- **Experiment get all** - DEPRECATED: renamed to experiment-list. This alias forwards to experiment-list and will be removed. Call experiment-list directly with the same arguments.
- **Experiment holdouts create** - Create a holdout group — a reserved slice of users excluded from experiment exposure, used as a held-back baseline. Requires name and a non-empty filters array. Link experiments to it afterwards by passing the returned id as holdoutid on experiment-create or experiment-update. Note that you can't change which holdout an experiment points to once that experiment is running; the holdout itself stays editable (see experiment-holdouts-partial-update, whose edits cascade to all linked experiments).
- **Experiment holdouts destroy** - Delete a holdout group by ID. Use experiment-holdouts-list first if you don't have the ID, and always confirm by name before deleting.
- **Experiment holdouts list** - List the experiment holdout groups in the current project. A holdout reserves a stable slice of users who are excluded from experiment exposure, so you can measure the long-term effect of all experiments against a held-back baseline. A holdout is NOT a feature flag — it is a separate object that experiments reference via holdoutid.
- **Experiment holdouts partial update** - Update a holdout group's name, description, or filters by ID. Use experiment-holdouts-list first if you don't have the ID.
- **Experiment holdouts retrieve** - Get a single experiment holdout group by ID, including its name, description, and filters array (the held-out population definition). Use experiment-holdouts-list first if you don't have the ID.
- **Experiment launch** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment list** - List experiments in the current project. This is the primary tool for resolving experiment references — load the finding-experiments skill for guidance on searching by name, status, recency, or description.
- **Experiment pause** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment reset** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment results get** - Get experiment metric results and exposure data in one call. Each row in metrics.primary.results and metrics.secondary.results carries a self-describing metric summary: uuid, name (the label users see in the experiment UI), metrictype, goal, and source — inline for metrics defined on the experiment, shared for metrics attached via a saved metric. For shared rows, savedmetricid and savedmetricname identify the underlying saved metric; both are null for inline rows. Rows are ordered to match the experiment UI (primarymetricsordereduuids / secondarymetricsordereduuids). A row whose underlying metric query failed is kept with data: null so positions stay aligned with the ordered UUIDs — check data === null to detect failures. The raw source surfaces (experiment.metrics, experiment.metricssecondary, experiment.savedmetrics) are preserved on the response for callers who want to audit them, but you do not need to reconcile them yourself — the result rows already merge inline and shared. UI-only bulk fields are stripped from each data payload: clickhousesql, hogql, the legacy insight visualization payload, and the per-funnel-step session samples — stepsessions is removed from baseline, each variantresults entry, and from baseline / variants[] inside every breakdownresults entry. Statistical fields (sum, sumsquares, stepcounts, numberofsamples, credibleintervals, per-breakdown stats, etc.) are preserved. Only works with new experiments (not legacy ExperimentTrendsQuery / ExperimentFunnelsQuery).
- **Experiment resume** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment saved metrics create** - Create a reusable shared metric. Requires name (unique per project, case-insensitive) and query (kind='ExperimentMetric', metrictype one of 'mean', 'funnel', 'ratio', 'retention'). Optional: description, tags.
- **Experiment saved metrics destroy** - Delete a shared metric by ID. REQUIRES EXPLICIT USER CONFIRMATION — confirm by name first, and warn that any experiments using it will lose access.
- **Experiment saved metrics list** - List shared metrics in the current project. Returns paginated results with id, name, description, query, createdat, updatedat, tags.
- **Experiment saved metrics partial update** - Partially update a shared metric. Only name, description, and query are mutable. Edits propagate to every experiment the metric is attached to — REQUIRES EXPLICIT USER CONFIRMATION before changing query or name on a metric attached to running experiments.
- **Experiment saved metrics retrieve** - Get a single shared metric by ID. Returns the full query JSON (metrictype, source, math, filters, etc.). If you don't have the ID, call experiment-saved-metrics-list first.
- **Experiment ship variant** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment stats** - Get aggregate experiment velocity statistics for the current project. Returns: launchedlast30d (experiments launched in the last 30 days), launchedprevious30d (the 30 days before that), percentchange between the two periods, activeexperiments (currently running count), and completedlast30d (experiments ended in the last 30 days). No parameters needed.
- **Experiment timeseries results** - Get day-by-day experiment results for a specific metric. Requires metricuuid and fingerprint as query parameters (both available from the experiment's metrics array — each metric has a uuid and the fingerprint is computed from its configuration).
- **Experiment unarchive** - Requires an experiment ID. If you don't have the ID, load the finding-experiments skill to resolve the user's reference first. Load the managing-experiment-lifecycle skill for preconditions and side effects.
- **Experiment update** - RULES (follow before calling).
- **External data schemas cancel** - Cancel a currently running sync job for a specific table schema. If no sync is running, returns an error. Use 'external-data-schemas-list' to check which schemas have status 'Running' before calling this.
- **External data schemas delete data** - Delete the synced table data from PostHog but keep the schema entry. The schema remains visible in the source and can be re-synced. Use this to clear stale or corrupt data before triggering a fresh sync.
- **External data schemas incremental fields create** - Re-inspect the source for a single table schema and return the currently available incremental fields, detected primary keys, column list, and which sync methods (incremental/append/cdc/webhook) are available. Use this when the source schema has changed, an incremental field has been dropped, or the user wants to switch to a different incrementalfield/synctype on an existing schema. The operationid is externaldataschemasincrementalfieldscreate but semantically this is a read-only refresh.
- **External data schemas list** - List all table schemas across all data warehouse sources. Each schema represents one table being synced from an external source. Returns the schema name, sync status, sync frequency, incremental field configuration, lastsyncedat, and latest error. Use this to see which tables are actively syncing and their health. To check one table's freshness, pass search with the table/schema name to narrow to that schema. Column definitions are omitted here — use external-data-schemas-retrieve for a single schema's columns.
- **External data schemas partial update** - Update a table schema's sync configuration. Can change sync type, sync frequency, incremental field, primary key columns, CDC table mode, and enable/disable the schema.
- **External data schemas reload** - Trigger a sync for a single table schema using its configured sync method (incremental, full refresh, append, or CDC). Use this to manually sync a specific table without triggering all tables in the source.
- **External data schemas resync** - Trigger a full resync for a table schema, discarding all previously synced data and re-importing from the source. This cancels any running sync first, then resets the pipeline state. Use this when data is corrupt or out of sync.
- **External data schemas retrieve** - Get a single table schema by ID. Returns full details including sync status, sync frequency, incremental field, latest error, and the associated source and table metadata.
- **External data sources check cdc prerequisites create** - Validate that a live Postgres database meets Change Data Capture prerequisites — logical replication enabled (wallevel=logical), replication slot available, publication present, and required permissions. Postgres-only. Returns {valid, errors[]}. Use this before configuring a schema with synctype=cdc, or to diagnose why an existing CDC sync has started failing.
- **External data sources connections list** - List external data sources that can be used as a connectionId when running execute-sql against an external source (direct-query Postgres and MySQL connections). Returns a lightweight id, prefix, and engine for each — unlike external-data-sources-list, it does not include warehouse import sources or table schemas. Use this to discover valid connectionId values.
- **External data sources create** - Low-level create for a data warehouse import source when you need to hand-pick tables and sync types. For most cases prefer 'data-warehouse-source-setup', which validates credentials, discovers tables, applies sensible sync defaults, and creates the source in one call. Use this advanced path only for fine-grained control. The 'schemas' array is NOT a top-level argument — it goes INSIDE 'payload', alongside the credential fields: payload = {<credential fields…>, "schemas": [...]}. Each schemas entry has: name, shouldsync (bool), synctype (incremental/fullrefresh/append), and optionally incrementalfield, incrementalfieldtype, and primarykeycolumns. Build the entries from the rows returned by 'external-data-sources-db-schema' first. Sources back queryable warehouse tables for revenue (Stripe), CRM (Hubspot, Salesforce), support (Zendesk), and your own databases (Postgres, MySQL, BigQuery).
- **External data sources create webhook create** - For sources that support real-time webhook ingestion (currently Stripe), create the HogFunction handler and register the webhook URL with the external service using the source's stored credentials. Requires at least one schema on the source with synctype='webhook' and shouldsync=true. Returns the webhookurl, success flag, and any error. NOT idempotent — each successful call registers a new endpoint on the external service, so retrying after a network error or calling twice can create duplicate webhook endpoints (e.g. duplicate Stripe webhook endpoints delivering the same events twice). Always check webhook-info-retrieve first and only re-call if exists: false. For Stripe the signingsecret is auto-captured from the Stripe API response and stored securely; if auto-registration fails (e.g. the API key lacks webhook permissions), the user must create the webhook manually in Stripe and submit the signingsecret via update-webhook-inputs.
- **External data sources db schema** - Validate credentials against a remote source and return the list of tables available to sync (works for database sources like Postgres/MySQL and SaaS sources like Stripe/Hubspot alike). Pass sourcetype and credential fields in the payload object. Each table entry includes: table name, incrementalavailable, appendavailable, cdcavailable, supportswebhooks, detectedprimarykeys, availablecolumns (name/type/nullable), rows estimate, and incrementalfields (candidate timestamp/integer columns for incremental sync). Use this BEFORE external-data-sources-create so the user can pick a synctype per table. Returns 400 with a message if credentials are invalid.
- **External data sources delete webhook create** - Unregister the webhook with the external service and delete the PostHog HogFunction that was handling it. Any webhook-type schemas under the source will stop receiving real-time events. The source and its schemas are preserved — only the webhook is removed. After deletion, schemas can be switched to a polling synctype (incremental/fullrefresh) via external-data-schemas-partial-update, or a new webhook can be created with create-webhook.
- **External data sources destroy** - Delete a data warehouse source and all its table schemas, synced tables, and sync schedules. This is a soft delete. Any running syncs are cancelled first. This cannot be undone — the source must be recreated to resume syncing.
- **External data sources jobs** - List sync job history for a data warehouse source. Returns jobs sorted by most recent first, with status, duration, rows synced, and errors. Supports optional filtering by date range (after/before as ISO timestamps) and by schema name.
- **External data sources list** - Check what external data is already connected before answering any revenue, billing, subscription, CRM, support-ticket, or product-database question — call this first so you JOIN against an existing source instead of telling the user the data isn't available. Lists every configured import source with its type (Postgres, Stripe, Hubspot, etc.), connection status, prefix, schemas, latest error, and last sync timestamp. If nothing relevant is connected, offer to set one up with 'data-warehouse-source-setup'. Per-schema column definitions are omitted to keep the payload small — to look up a single table's sync status by name use external-data-schemas-list with a search, and to see a table's columns use external-data-schemas-retrieve.
- **External data sources partial update** - Update an existing data warehouse source's prefix (table name prefix in HogQL) or description. Cannot change the sourcetype or accessmethod after creation. Avoid sending new connection credentials inline here — to rotate or fix credentials, point the user at 'data-warehouse-source-connect-link' so they re-enter them securely in their browser rather than pasting secrets into the chat.
- **External data sources preview resource** - Read a small live sample of rows for one resource (table) of a Custom REST source, so you can verify the manifest's dataselector, primarykey, and incremental cursorpath against real data BEFORE creating the source. Only sourcetype 'Custom' is supported. Pass sourcetype, a payload object ({manifestjson, plus the credential for the manifest's auth type — authtoken | authapikey | authpassword}), the resourcename to sample, and an optional limit (1–50, default 10). Returns {rows, rowcount, columns (name + inferred JSON type), error}. Manifest, validation, and SSRF problems return 400; a live fetch failure returns 200 with error set and empty rows. Use external-data-sources-db-schema first to list the resource names and detected cursors.
- **External data sources refresh schemas** - Fetch the latest table list from the remote database and create schema entries for any new tables found. This is a metadata refresh — it does NOT move or sync any data (use 'external-data-sources-reload' for that). Use this after adding new tables to a source database to make them available for syncing.
- **External data sources reload** - Trigger a sync for all enabled table schemas in the source using each table's configured sync method. If the source uses direct query mode, this refreshes the schema metadata instead.
- **External data sources repair cdc create** - Repair change data capture on a source whose replication slot or publication was lost — use when 'external-data-sources-cdc-status-retrieve' shows slotexists=false or publicationexists=false, or the source reports a CDC error about a missing slot. Recreates the replication resources from the stored CDC config, resets every active CDC schema to a fresh snapshot (a full re-sync — changes made while the slot was gone cannot be recovered), and resumes the paused sync schedules. Refuses with a 400 if CDC looks healthy (both slot and publication exist) so it cannot accidentally force a re-sync, and with a 409 if a repair is already running. Safe to retry after a failure. Returns {success, schemasreset}.
- **External data sources retrieve** - Get a single data warehouse source by ID. Returns full details including source type, connection status, prefix, all table schemas with their sync statuses, latest error, and last sync timestamp.
- **External data sources update webhook inputs create** - Update the webhook-specific inputs on an already-created webhook — for example when a signing secret has been rotated on the source side, or when the webhook was registered manually and the signingsecret needs to be supplied. Only accepts keys defined in the source type's webhookFields (e.g. Stripe's signingsecret). Fails if no webhook has been created for this source yet — call create-webhook first.
- **External data sources webhook info retrieve** - Return webhook state for a source: supportswebhooks (is this source type webhook-capable), exists (has a webhook been created), webhookurl (the PostHog endpoint the external service should POST to), schemamapping (external event type → PostHog schema id), and externalstatus (what the remote service reports about the webhook — enabledevents, status, createdat, error). Use this to check whether a webhook is healthy and whether the external registration is still valid.
- **External data sources wizard** - Use this whenever the user needs data PostHog doesn't capture natively — revenue and payments (Stripe, Chargebee), CRM contacts and deals (Hubspot, Salesforce), support tickets (Zendesk), e-commerce orders (Shopify), ad spend, or their own application/production database (Postgres, MySQL, BigQuery, Snowflake) — or when a HogQL query fails because the table doesn't exist yet. Importing turns that data into queryable warehouse tables you can JOIN against product events. Returns the configuration metadata for every supported source type: the required fields (host, port, database, credentials, etc.), field types, and OAuth flows, so you know what a connection needs. ALWAYS pass 'sourcetype' with the specific kind(s) you need (comma-separated, e.g. 'Postgres,Stripe') — the unfiltered response describes every source and is very large (hundreds of KB). Only omit 'sourcetype' if you genuinely need to enumerate every available type. To actually connect a source, prefer 'data-warehouse-source-setup'.
- **External data sync logs** - Get sync job logs for a data warehouse table schema. Returns log entries from the logentries ClickHouse table, filtered by schema ID and optionally by a specific job's workflowrunid. Use external-data-sources-jobs to find job IDs and workflowrunids. Supports filtering by log level (DEBUG, INFO, WARNING, ERROR) and message search.
- **Feature flag get all** - Get feature flags in the current project. Supports list filters including search by feature flag key or name (case-insensitive), then use the returned ID for get/update/delete tools.
- **Feature flag get definition** - Get a feature flag by ID.
- **Feature flags activity retrieve** - Get the audit trail for a specific feature flag by ID. Returns a paginated list of changes including who made changes, what was changed, and when. Use limit and page query params for pagination.
- **Feature flags bulk delete create** - Soft-delete multiple feature flags in one call. Provide either ids (explicit list of flag IDs) OR filters (same shape as the list endpoint, e.g., search, active, type, tags), but not both. WARNING: filters can match an unbounded number of flags. Preview matches via the list endpoint before calling this with filters, and prefer explicit ids whenever the user has named specific flags. Flags linked to active experiments, early access features, or that other flags depend on are skipped and reported in errors. Returns deleted (with each flag's rollout state at deletion time) and errors arrays.
- **Feature flags bulk keys create** - Resolve feature flag IDs to their string keys in one call. Pass ids as a list of integer flag IDs. Returns keys as a mapping of stringified ID to key for the IDs that exist in this project. Useful when you have IDs from another tool (e.g., dependent flags, scheduled changes) and need the keys for downstream calls.
- **Feature flags bulk keys retrieve** - Resolve feature flag IDs to their string keys in one call. Pass ids as a list of integer flag IDs. Returns keys as a mapping of stringified ID to key for the IDs that exist in this project. Useful when you have IDs from another tool (e.g., dependent flags, scheduled changes) and need the keys for downstream calls.
- **Feature flags bulk update tags create** - Add, remove, or replace tags on multiple feature flags in one call. Provide ids (up to 500), an action ('add', 'remove', or 'set'), and a list of tag names. Returns updated (per-flag final tag list) and skipped (flags missing or without edit permission, with reason).
- **Feature flags copy flags create** - Copy a feature flag from one project to other projects within the same organization. Provide the flag key, source project ID, and a list of target project IDs. Optionally copy scheduled changes with copyschedule. Returns lists of successful and failed copies.
- **Feature flags dependent flags retrieve** - Get other active feature flags that depend on this flag. Use this to understand flag dependency chains before making changes to a flag's rollout conditions or disabling it.
- **Feature flags evaluation reasons retrieve** - Debug why feature flags evaluate a certain way for a given user. Provide a distinctid and optionally groups to see each flag's evaluated value and the reason for that evaluation (e.g. conditionmatch, noconditionmatch, disabled).
- **Feature flags my flags retrieve** - List all feature flags in the current project along with their evaluated value for the authenticated user (the API key owner). Each item includes the flag definition and its current value (boolean for simple flags, variant key string for multivariate flags, false if disabled). Optionally pass groups as a JSON object to evaluate group-based flags.
- **Feature flags status retrieve** - Check the health and evaluation status of a feature flag by ID. Returns a status (active, stale, deleted, or unknown) and a human-readable reason explaining the status. The status reflects recent evaluation (whether the flag was called), NOT rollout completeness. To determine whether a flag is fully rolled out / GA, use the returned rollout object: effectivelyfullrollout (true when targeted to everyone with no conditions), hastargetingconditions, maxrolloutpercentage, and ismultivariate.
- **Feature flags test evaluation create** - Test how a feature flag evaluates for a specific user at an optional point in time. Provides detailed reasoning about why the flag matched or didn't match, including condition analysis and person properties used in evaluation.
- **Feature flags user blast radius create** - Assess the impact of a feature flag release condition before applying it. Provide a condition object and optionally a grouptypeindex to see how many users would be affected relative to the total user count.
- **File download batch exports cancel create** - Cancel a running or starting on-demand file download export. When the status is not Starting or Running calling this will fail. Returns the status of the export after cancelling, which is always Cancelled.
- **File download batch exports create** - Start an on-demand batch export that prepares downloadable files for events, persons, or sessions. Provide dataintervalstart and dataintervalend as ISO 8601 datetimes; the interval must be at most one week. For events, include and exclude filter event names. Use file-download-batch-exports-retrieve with the returned id to poll until status is Completed, then follow the downloading-batch-export-files skill to download the files through the existing REST download endpoint.
- **File download batch exports retrieve** - Get the status of an on-demand file download export. Returns Starting or Running while the export is in progress, Completed with file IDs when files are ready, or a failed status with an error message. When status is Completed, use the downloading-batch-export-files skill to download each file through the existing REST download endpoint; the generated MCP download operation is intentionally not enabled because it is a redirect to the file body.
- **Generate app url** - Build a correct, clickable PostHog app URL for any page or entity — run info generate-app-url for the full catalog of path templates.
- **Get llm total costs for project** - Fetches the total LLM daily costs for each model for a project over a given number of days. If no number of days is provided, it defaults to 7. The results are sorted by model name. The total cost is rounded to 4 decimal places. The query is executed against the project's data warehouse. Show the results as a Markdown formatted table with the following information for each model: Model name, Total cost in USD, Each day's date, Each day's cost in USD. Write in bold the model name with the highest total cost. Properly render the markdown table in the response.
- **Get more tools** - Check for additional tools whenever your task might benefit from specialized capabilities - even if existing tools could work as a fallback.
- **Health issues get** - Fetches a single health issue by id so you can drill into what's wrong AND explain how to fix it. Alongside the issue's kind, severity, status, and check-specific payload, the detail view adds a human-readable title, a one-line summary of the problem, a link to the relevant page in PostHog, and remediation — fix-it guidance with two fields: remediation.human (how to fix it in the PostHog UI) and remediation.agent (how you should investigate it — often via other tools like execute-sql or docs-search — and, when the fix lives in the user's codebase, how to apply it directly, e.g. bump a PostHog SDK dependency, change a posthog.init option, or add a reverse-proxy route).
- **Health issues list** - Lists health issues detected across all of this project's PostHog health checks — outdated SDKs, data warehouse sync failures, missing web analytics events, ingestion warnings, reverse-proxy and web-vitals problems, and more. Each issue has a kind (which check found it), a severity (critical/warning/info), a status (active/resolved), and a check-specific payload with the detail. Filter by status, severity, kind, or dismissed state. Use when the user asks what's wrong with their PostHog setup, what alerts are firing, why data might be missing, or to drill into one category of problem.
- **Health issues summary** - Returns aggregated counts of active, non-dismissed health issues for the project, broken down by severity and by kind. Use for a quick overall health check before drilling into specifics with the list tool.
- **Heatmaps events** - Drill into the individual session interactions behind one or more heatmap coordinates. Pass points as a JSON array of the spots you want to inspect (the pointerrelativex / pointery values from heatmaps-list), plus the same page/date filters. Returns the underlying per-session interactions so you can open the session recordings that produced a hotspot.
- **Heatmaps list** - Aggregated heatmap interactions captured on a page. Filter by urlexact (one page) or urlpattern (regex across pages), a date window (datefrom/dateto, data is retained 90 days), and optionally a viewport range (viewportwidthmin/viewportwidthmax, CSS px) to isolate a device class. Set type to 'click' (default), 'rageclick', 'mousemove', or 'scrolldepth'. For clicks each result is a point — pointerrelativex (0..1 across the viewport), pointery (absolute pixels down the page), and a count; 'scrolldepth' returns reach buckets instead. For the click types the response also includes a fold summary — pctbelowfold (share of non-fixed interactions that landed below the user's initial viewport, i.e. required scrolling), belowfoldcount, totalcount, and the medianviewportheight (the typical fold line in CSS px) — so a high pctbelowfold flags engaged content sitting off the first screen. rageclick hotspots and shallow scroll depth are the strongest signals that something on the page is confusing or buried. Heatmaps only know coordinates, not what was clicked — cross-reference autocapture events on the same URL to name the elements, and use heatmaps-events to jump to the sessions behind a hotspot. Click results are returned hottest-first and capped at limit (default 500); busy pages have thousands of distinct coordinates, so the default page plus the fold summary is usually enough for analysis — raise limit or page with offset only if you need more, and check hasmore to know when the list is truncated.
- **Heatmaps saved create** - Create a saved heatmap for a page URL. For type 'screenshot' (the default) this enqueues a headless render of the page at each target width — poll heatmaps-saved-get until status is 'completed'; the rendered page (with data overlaid) is then viewable by the user in the PostHog UI. Provide widths (CSS px, 100-3000) to control which viewports are rendered, or omit it for sensible defaults. The URL must be exact — wildcards are not allowed.
- **Heatmaps saved get** - Get a single saved heatmap by its shortid, including per-width render status. Poll this after heatmaps-saved-create until status is 'completed'; the rendered page is then viewable by the user in the PostHog UI.
- **Heatmaps saved list** - List saved heatmaps for the project. A saved heatmap pins a page URL plus a set of viewport widths and (for type 'screenshot') renders the page so heatmap data can be overlaid on it. Filter by type, status, createdby, or a search substring on URL/name. The rendered page (screenshot with data overlaid) is viewable by the user in the PostHog UI.
- **Heatmaps saved regenerate** - Re-run screenshot generation for a saved heatmap of type 'screenshot' by its shortid. Clears the existing renders and re-renders at every target width; status returns to 'processing'. Use when a page has changed or a render failed.
- **Heatmaps saved update** - Update a saved heatmap by its shortid. Send only the fields to change — rename via name, change widths, or soft-delete by setting deleted: true (deletion goes through this update, not a destroy call). Changing the url of a 'screenshot' heatmap triggers a fresh render.
- **Hog flows logs retrieve** - Retrieve execution logs for a specific workflow by ID. Returns log entries with timestamp, level (DEBUG, LOG, INFO, WARN, ERROR), and message. Use to debug why a workflow is failing or not producing expected results. Supports filtering by log level, text search, time range (after/before), and pagination via limit.
- **Hog flows metrics retrieve** - Retrieve execution metrics for a specific workflow by ID. Returns time-series data showing success and failure counts over a configurable interval (hour, day, or week). Use to understand workflow health, identify failure spikes, and monitor execution reliability. Supports breakdown by metric kind (success/failure) or name, and time range filtering.
- **Hogql schema** - Return the HogQL catalog for the active project: every queryable table (PostHog, system, warehouse, view, materialized view, batch export, endpoint) keyed by name, with each table's fields, plus the join graph between data-warehouse tables. Call this once up front when building a HogQL query from scratch so you pick real table and column names on the first attempt instead of guessing. Cheap — no ClickHouse cost. Pass 'connectionId' to introspect a Postgres or DuckDB direct-query data warehouse source instead of the ClickHouse catalog (use external-data-sources-list to find ids).
- **Inbox report artefacts create** - Append an artefact to a signal report so it reads as a living document. Everything is append-only. Log types accumulate — codereference (a contiguous span of source lines, at most 20: filepath, startline, endline, contents, relevancenote; a single line is just startline == endline), commit (one commit that has already been pushed to a remote branch: repository, branch, commitsha, message — usually recorded automatically when you push via gitsignedcommit. Only create one yourself for a commit pushed to a remote by other means; never record a commit that is not on a remote branch — an unpushed or local-only commit is always a mistake), taskrun (associates a tasks.Task with the report — this IS the task↔report association: content.taskid defaults to your own task, product/type label the run and default to tasks/agentrun, and re-associating an already-linked task is idempotent, returning the existing entry), note (free-form: note). Status types are latest-wins — appending a new version supersedes the previous one as the report's canonical status: priorityjudgment (explanation, priority P0–P4), actionabilityjudgment (explanation, actionability, alreadyaddressed), safetyjudgment (choice), reposelection (repository, reason), suggestedreviewers (a list of {githublogin}). Status judgments are consequential, not advisory: the canonical priority/actionability steer what humans and agents pick up next, and PostHog's automation uses them when deciding which reports to act on. content is a JSON object matching the chosen type and is validated against its schema. Writes are attributed to your task automatically. Returns the created artefact including its id.
- **Inbox report artefacts delete** - Delete an artefact by its id when it is no longer correct or relevant. Deleting the latest row of a status type (e.g. priorityjudgment) reverts the report's canonical status to the previous version.
- **Inbox report artefacts list** - List every artefact on a signal report — the full picture of why it exists and what has been done about it: signalfinding entries (the evidence behind the report), status judgments (safety / actionability / priority, reposelection, suggestedreviewers — the newest row of each status type is the canonical status), and work-log entries (code references, commits, task runs, notes). Read this before re-judging a status or adding to the log.
- **Inbox report artefacts retrieve** - Get one artefact by id. Content is parsed (and suggestedreviewers enriched with PostHog user info) the same way as inbox-report-artefacts-list.
- **Inbox report artefacts update** - Replace the content of an existing artefact, addressed by its id, when new information supersedes it. The new content is validated against the artefact type's schema. Editing the latest row of a status type changes the report's canonical status; to re-assess while keeping history, append a new artefact instead.
- **Inbox reports bulk set state** - Transition many signal reports to the same state in one call — the bulk form of inbox-reports-set-state, for clearing or snoozing a batch of inbox reports without one request per report. Pass ids (1–100 report ids) and a state ('suppressed' to dismiss, 'potential' to snooze/restore); the optional dismissalreason (same canonical codes as the single-report tool), dismissalnote, and snoozefor apply to every id. Each id is processed independently, so the whole call returns 200 even on partial failure: inspect results (one entry per id, in request order) and the transitionedcount / skippedcount / failedcount / notfoundcount summary. An id whose transition isn't allowed from its current status comes back as skipped (the single-report 409) while the rest still go through.
- **Inbox reports list** - List signal reports for the current project. A signal report is a cluster of related observations (signals) that PostHog has aggregated into a single issue or trend. Reports surface in the Inbox. Supports filtering by status (potential, candidate, inprogress, pendinginput, ready, resolved, failed, suppressed), free-text search across title and summary, sourceproduct (e.g. errortracking, sessionreplay), suggestedreviewers (PostHog user UUIDs), and taskid (only reports associated with that task — pass your own task id to see which reports you are already working against). For picking up work, filter to ready — earlier statuses are still moving through the pipeline, and pendinginput reports are waiting on a human. Each report's full work log — signal findings (evidence), judgments, and log entries — is readable via inbox-report-artefacts-list; read it before acting on a report. Results are paginated and ordered by '-issuggestedreviewer,status,-updatedat' by default.
- **Inbox reports retrieve** - Get a single signal report by ID. Returns the full report including title, summary, status, priority and actionability judgments, signalcount, totalweight, source products, and the URL of the implementation PR if one has been opened. The report's full work log — signal findings (evidence), judgments, and log entries — is readable via inbox-report-artefacts-list; read it before acting on the report. The raw underlying signals require a HogQL query (see the 'signals' skill). If you do any work prompted by this report — even research — first associate your task with it by appending a taskrun artefact via inbox-report-artefacts-create. Report lifecycle is pipeline-managed — don't try to drive it: act on ready reports; pendinginput means the report is waiting on human input, so surface it to a human rather than acting on it yourself.
- **Inbox reports set state** - Transition a single signal report to a new state. Use 'suppressed' to dismiss the report from the inbox (the user has reviewed it and decided no action is needed), or 'potential' to snooze/restore it back into the pipeline for later review. Optionally include a dismissalreason — a canonical code from the inbox UI (alreadyfixed, reportunclear, analysiswrong, wontfixintentional, wontfixirrelevant, other), so it renders as a labelled chip rather than a raw string. alreadyfixed is a snooze, not a dismissal: pair it with state='potential'. Use other plus a dismissalnote (free-form text, up to 4000 chars) for anything that doesn't fit a code. Both are persisted as a DISMISSAL artefact on the report so the rationale survives later transitions. Returns 409 if the transition is not allowed from the report's current status. To transition several reports at once, use inbox-reports-bulk-set-state instead of calling this per report.
- **Inbox reports update** - Edit the human-facing title and/or summary (description) of a signal report, addressed by id. Both fields are optional — pass only the ones you want to change, but supply at least one. Use this to clarify a report's title or rewrite its summary when you understand the underlying issue better than the auto-generated text does. Every other field (status, weights, priority/actionability judgments) is managed by the signals pipeline and cannot be set here — change a report's state with inbox-reports-set-state and its judgments by appending artefacts with inbox-report-artefacts-create. Returns the full updated report.
- **Inbox source configs create** - Create a signal source config for the current project, switching an inbox signal source on. A source ties a sourceproduct to a sourcetype and an enabled flag. Valid sourceproduct values: sessionreplay, llmanalytics, github, linear, zendesk, conversations, errortracking, pganalyze, signalsscout, logs. Valid sourcetype values: sessionanalysiscluster, evaluation, evaluationreport, issue, ticket, issuecreated, issuereopened, issuespiking, crosssourceissue, alertstatechange. To surface AI observability evaluation report findings in the inbox, create sourceproduct=llmanalytics, sourcetype=evaluationreport. The Signals scout source is ON BY DEFAULT — scout findings reach the inbox with no config row needed. The only reason to create a sourceproduct=signalsscout, sourcetype=crosssourceissue row is to OPT OUT: create it with enabled=false (the per-scout emit flag is set separately via signals-scout-config-update). There is at most one config per (sourceproduct, sourcetype) per project; if one already exists, update it instead. Enabling the sessionanalysiscluster source requires the organization to have approved AI data processing.
- **Inbox source configs list** - List the configured signal sources for the current project. A signal source ties a product (e.g. errortracking, sessionreplay, github, linear, zendesk) and a sourcetype to an enabled flag and configuration. The 'status' field reflects the current state of the underlying data import or workflow (running, completed, failed) when applicable.
- **Inbox source configs partial update** - Partially update an existing signal source config by ID — typically to flip its enabled flag on or off, or to adjust its config. Only the fields you pass are changed. To turn the Signals scout source off for a project, set enabled=false on its signalsscout / crosssourceissue config. Enabling the sessionanalysiscluster source requires the organization to have approved AI data processing.
- **Inbox source configs retrieve** - Get a single signal source config by ID. Returns the full record including sourceproduct, sourcetype, enabled flag, configuration JSON, and current status of the underlying data import or workflow.
- **Inbox source configs update** - Replace an existing signal source config by ID (full update — sourceproduct and sourcetype are required; enabled and config are optional and keep their current values if omitted). Prefer inbox-source-configs-partial-update when you only need to flip enabled or tweak config. Enabling the sessionanalysiscluster source requires the organization to have approved AI data processing.
- **Ingestion warnings list** - Lists the project's ingestion warnings — events or person/group updates that were ingested with problems (oversized messages, rejected person merges, invalid data) — grouped by warning type. Each entry has the warning's category (e.g. 'size', 'merge', 'event') and severity ('info'/'warning'/'error'), the total count and a sparkline over the requested time range, and the most recent sample warnings with the affected eventuuid, distinctid, personid, or groupkey. Defaults to the last 24 hours; since/until accept ISO datetimes or relative durations like '-7d' (data is retained for 90 days). Narrow with category, type, or severity, free-text search with q (matches warning type and details, e.g. a distinct ID), and raise samples (up to 50) to see more affected events per type. Use when the user asks why events are missing or dropped, why person merges fail, or generally whether their event ingestion is healthy.
- **Insight create** - Create a new saved insight from a name and query definition. Test queries with query-trends / query-funnel / query-retention / query-paths / query-stickiness / query-lifecycle first to confirm the shape, then save. Returns insight metadata only — after creating, call the insight-query tool with the returned shortid if you want to see the computed results.
- **Insight create from query** - Create an insight from a query that you have previously tested with 'query-run'. You should check the query runs, before creating an insight. Do not create an insight before running the query, unless you know already that it is correct (e.g. you are making a minor modification to an existing query you have seen).
- **Insight delete** - Soft-delete an insight by ID. The insight will be marked as deleted and no longer appear in lists.
- **Insight get** - Fetch a saved insight by its numeric id or 8-character shortid. Returns the insight metadata and query definition, but NOT the query results. To retrieve the actual data, call the insight-query tool with the same identifier. Optionally accepts variablesoverride and filtersoverride to apply one-off overrides to the returned query definition without mutating the saved insight.
- **Insight query** - Execute a saved insight's query and return results. THIS IS THE ONLY WAY TO RETRIEVE INSIGHT RESULTS — the insights-list, insight-get, insight-create, and insight-update tools all return metadata and query definitions but never the actual data. Call insight-query whenever the user asks to see, analyze, summarize, or compare data from a saved insight, and immediately after creating or updating an insight if they want to verify the output. Supports two output formats: 'optimized' (default) returns a human-readable summary from server-side formatters ideal for analysis, while 'json' returns the raw query results. Optionally accepts variablesoverride and filtersoverride to run the insight with one-off overrides without mutating the saved definition.
- **Insights activity retrieve** - Audit trail for a single insight by numeric id. Returns a paginated list of every change made to it (created, edited, deleted, restored), including who made each change and which fields changed. The full before/after diff blobs are omitted to keep responses agent-friendly — to inspect the current state of the insight after a change, call insight-get with the insight's shortid. Paginate with limit and page.
- **Insights all activity retrieve** - Project-wide audit trail of changes to all insights, most recent first. Returns who created, edited, deleted, or restored each insight and which fields changed. Useful for surfacing what people (or agents) have been working on recently. The full before/after diff blobs are omitted to keep responses agent-friendly — drill into a specific insight with insights-activity-retrieve (or insight-get for current state). Paginate with limit and page.
- **Insights get all** - Get all insights in the project with optional filtering. Can filter by saved status, favorited status, or search term.
- **Insights list** - List saved insights in the project with optional filtering by favorited status or search term. Returns metadata only (name, description, tags, dashboards, ownership) — NOT the query results. To retrieve the actual data for any insight in the list, call the insight-query tool with its shortid or numeric id.
- **Insights trending retrieve** - Returns the most-viewed insights in the project, ranked by view count over the last N days (default 7). Use this to surface the insights that matter most to the team — the ones people actually open. Each result includes standard insight metadata plus viewcount and up to 3 recent viewers. Returns metadata only — call insight-query with the returned shortid to fetch the actual data for any of them.
- **Insight update** - Update a saved insight by numeric id or shortid. Can update name, description, query, tags, favorited status, and dashboards. Returns insight metadata only — after updating the query, call the insight-query tool with the same identifier if you want to see the recomputed results.
- **Integration delete** - Permanently delete an integration by ID. This removes the connection to the third-party service. Any features relying on this integration (alerts, workflow destinations, etc.) will stop working.
- **Integration get** - Get a specific integration by ID. Returns full integration details including kind, display name, error status, and creation metadata. Does not expose sensitive credentials or raw configuration.
- **Integrations channels retrieve** - List the Slack channels available for a Slack integration. Slack-only — non-Slack integration ids return an error (400 if the integration is otherwise visible, 404 if it isn't). Returns each channel's id, name, isprivate, ismember, isextshared, and isprivatewithoutaccess flags; use ismember to avoid picking channels the bot can't post to. Results are cached for 1 hour (no force-refresh exposed via MCP). Use this to find a channelid when wiring up Slack delivery for an alert — pass the channel id into the cdp-functions-create inputs.channel.value field. Requires the Slack integration's id; use integrations-list (filter by kind=slack) to find it.
- **Integrations github repos retrieve** - List the repositories accessible to a GitHub integration (by integration ID). Serves the cached repository list from the GitHub App installation. Supports search (case-insensitive name match), limit (default 100, max 500), and offset query parameters. Returns repository id, name, and fullname (owner/repo) plus a hasmore flag. Use this to validate that a repository is accessible to the integration before referencing it (e.g. when creating a GitHub data warehouse source).
- **Integrations jira projects retrieve** - List Jira projects available through a connected Jira integration. Use integrations-list with kind=jira first to find the integration id, then pass a returned project key as config.projectkey when creating an error tracking external reference.
- **Integrations linear teams retrieve** - List Linear teams available through a connected Linear integration. Use integrations-list with kind=linear first to find the integration id, then pass a returned team id as config.teamid when creating an error tracking external reference.
- **Integrations list** - List all third-party integrations configured in the current project. Returns each integration's type (kind), display name, non-sensitive configuration, error status, and creation metadata. Common kinds include slack, github, hubspot, salesforce, and various ad platforms. Sensitive credentials (access tokens, secrets) are never serialized.
- **List errors** - Use this tool to list errors in the project.
- **Llma clustering config get** - Retrieve the team's clustering event-filter configuration for automated AI observability clustering. New scheduled clustering should usually use clustering jobs, but this remains useful when auditing existing automation.

## Viktor uses PostHog together with

- [Slack](https://viktor.com/integrations/slack)
- [Gmail](https://viktor.com/integrations/gmail)
- [Google Sheets](https://viktor.com/integrations/google-sheets)
- [HubSpot](https://viktor.com/integrations/hubspot)
- [Notion](https://viktor.com/integrations/notion)
- [Salesforce](https://viktor.com/integrations/salesforce)

## More Analytics integrations

- [PostHog (EU)](https://viktor.com/integrations/posthog-eu)
- [Sentry](https://viktor.com/integrations/sentry)
- [Mixpanel](https://viktor.com/integrations/mixpanel)
- [Akeneo](https://viktor.com/integrations/akeneo)
- [IPGeolocation](https://viktor.com/integrations/ipgeolocation)
- [Tricentis qTest](https://viktor.com/integrations/tricentis-qtest)
- [Amplitude](https://viktor.com/integrations/amplitude)
- [Mixpanel (Service Account)](https://viktor.com/integrations/mixpanel-service-account)

## FAQ

### Does Viktor integrate with PostHog?

Yes. PostHog is one of the 9,800+ tools Viktor connects to, as one of Viktor's native, deepest integrations. Once connected, anyone on your team can put Viktor to work in PostHog from their workspace - no workflow builder, no code.

### How do I connect PostHog to Viktor?

Ask Viktor in your workspace to connect PostHog. It's one of Viktor's native integrations, so Viktor handles authorization itself and starts working right away. Setup takes about two minutes, and you can revoke access at any time.

### What can Viktor do in PostHog?

Viktor can run 300 PostHog actions, including Exec, Alert get, and Action get - and chain them with other tools in a single request. In practice that means Viktor helps you track product usage and feature adoption. If a task spans several actions, Viktor plans the sequence itself and reports back when the work is done.

### Do I need to build workflows for PostHog?

No. Viktor isn't a workflow builder - there are no triggers to map and nothing to maintain. You ask for the outcome in plain English in your workspace, and Viktor decides which PostHog actions to take, runs them, and reports back.

### Is my PostHog data secure with Viktor?

Yes. Viktor connects to PostHog natively, runs in an isolated environment per team, and never trains models on your data. Sensitive actions wait for your approval, and you can revoke access at any time. Viktor is SOC 2 Type 1 compliant, with Type 2 and ISO 27001 in progress.

### How much does the PostHog integration cost?

Nothing extra - every integration, including PostHog, is available on every plan. You can start free with up to $100 in credits, no credit card required; the Team plan is $100 a month.

### Can Viktor use PostHog together with my other tools?

Yes - that's the point. Viktor connects to 9,800+ tools and works across them in a single run: he can pull data from PostHog, cross-reference it with another tool - for example Slack or Gmail, and deliver the finished result in your workspace.

## Get started

Viktor is free to start - up to $100 in credits, no credit card required. All 9,800+ integrations are included on every plan. Sign up at https://viktor.com or browse all integrations at https://viktor.com/integrations.
