> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to the Mixpanel MCP server

The Mixpanel MCP connector routes your AI agent's tool calls to Mixpanel's own MCP server through Scalekit. Each user signs in to Mixpanel once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 66 tools.

**Authentication:** OAuth 2.1/DCR
**Categories:** Analytics
**Tools:** 66: 37 read, 23 write, 6 destructive
**Users sign in with:** OAuth
**OAuth app:** Your own Mixpanel MCP server app
**Built by:** Vendor MCP
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=MIXPANELMCP)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Mixpanel MCP connection

   In **AgentKit > Connections**, create a Mixpanel MCP connection and copy its redirect URI. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

4. ### Register an OAuth app

   Mixpanel MCP server connections use your own OAuth app. Register one with Mixpanel MCP server and add the redirect URI you copied.

   Then enter the app's Client ID and Client Secret on the Mixpanel MCP connection.

5. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'mixpanelmcp'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Mixpanel MCP:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'mixpanelmcp_describe_cohort_schema',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "mixpanelmcp"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Mixpanel MCP:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="mixpanelmcp_describe_cohort_schema",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user signs in once. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'mixpanelmcp_describe_cohort_schema',
  toolInput: {},
  connector: 'mixpanelmcp',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="mixpanelmcp_describe_cohort_schema",
    tool_input={},
    connection_name="mixpanelmcp",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `mixpanelmcp_describe_cohort_schema`

Describe Cohort Schema · Read-only

Return the JSON schema for the `definition` field used by Create-Cohort and Update-Cohort.

Call this before writing a cohort definition for the first time in a session, so you know which fields are required for the grouped format versus the lower-level selector format.

The response has three parts:
- `definition`: the CohortDefinition JSON schema (the grouped/selector union).
- `grouped_filter_types`: per-type schemas and worked examples for the entries inside the grouped format's `groups[].filters[]` array (property, behavioral, and cohort_membership filters), which the base schema leaves opaque.
- `notes`: gotchas worth reading before authoring a definition.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_display_query`

Display Query · Read-only

Display the interactive chart widget for a previously-run query. Takes a query_id returned by Run-Query and render results in the MCP App visualization widget.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project the query was run against.
- `query_id` (`string`, required): The query_id returned by a previous Run-Query call.
- `workspace_id` (`string`, optional): Optional workspace the query was scoped to.

Example input: `{"project_id":1,"query_id":"<query_id>"}`

### `mixpanelmcp_explain_experiment_health_check`

Explain Experiment Health Check · Read-only

Diagnose why one of an experiment's automated health checks is failing (or confirm it is passing) and get a recommended next action. Covers two kinds of check, selected with health_check_kind.

Sample Ratio Mismatch (health_check_kind="srm") detects when the observed traffic split deviates from the configured allocation. First call Get Experiment with compute_exposures set to true, then pass p_value from the experiment's live SRM analysis (pass it through as null if SRM has not been computed yet — the tool returns a clear "SRM unavailable" message instead of an error), live_exposures (the per-variant exposure counts), and target_allocations (the configured per-variant traffic split).

Retrospective A/A bias check (health_check_kind="retro_a_a") runs per-metric statistical tests over the pre-experiment window to catch randomization or measurement bias. First call Get Experiment with compute_metrics set to true, then pass retro_aa_verdict (the live retro A/A block from that response, or null if it has not been computed yet, which is typical right after an experiment starts) and metric_names (a map of metric ID to display name, so the diagnosis can name the affected metrics instead of showing raw IDs).

The response explains what is failing (or confirms nothing is), lists likely causes ordered from most to least probable, and recommends a next action — for example pausing the experiment, investigating exposure tracking, restarting with bot filtering, enabling CUPED, or simply continuing. It also cites the relevant statistical trustworthiness principle (Kohavi's for SRM, Twyman's Law for retro A/A) when a check is failing.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `health_check_kind` (`string`, optional): No description. One of: `srm`, `retro_a_a`. Default: `srm`.
- `live_exposures` (`string`, optional): No description.
- `metric_names` (`string`, optional): No description.
- `p_value` (`string`, optional): No description.
- `retro_aa_verdict` (`string`, optional): No description.
- `target_allocations` (`string`, optional): No description.

Example input: `{}`

### `mixpanelmcp_find_duplicate_groups`

Find Duplicate Groups · Read-only

Find groups of duplicate or near-duplicate names in a Mixpanel project — both events and event properties. Returns clusters a user might want to merge in Lexicon (e.g. 'Add to Cart', 'add_to_cart', 'addToCart'; or 'from_date', 'from-date').

Returns a FormattedTable with columns:
  - suggested_name: the most-popular variant in the cluster — use this as the merge target.
  - entity_names: every variant in the group, in popularity order (includes suggested_name as the first entry).
  - entity_type: 'events' or 'event_properties'. Pass this value back to Merge-Group / Dismiss-Duplicate-Group.

Groups already merged or dismissed by the user are filtered out by the server. Empty `rows` means there is nothing actionable.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project to scan for duplicate or near-duplicate event and property names.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_business_context`

Get Business Context · Read-only

Call this FIRST, before any other Mixpanel tool whenever ANY of these are true:

1. It is the first substantive turn of the conversation about this org or project.
2. The user references a name, acronym, product, team, project nickname, event, property, or concept whose org-specific meaning you cannot verify just from the tool list. Examples that should trigger this: "show me MCP data", "how is ingest doing?", "the onboarding funnel", "Project Atlas".
3. You are about to guess which project_id, event name, or property to use based on a name in the user's request.

Example:
  User: "what project has sales data?"
  ❌ Wrong: jump to Get-Projects and pattern-match against project names.
  ✅ Right: call Get-Business-Context first, the org likely defines what "sales data" refers to (a product area, an internal acronym, a specific project).

Once you have called this in the current conversation for a given organization (and project, if applicable), do NOT call it again. The result is stable for the session; reuse the previously returned context on every subsequent turn — including follow-ups, drill-downs, refinements, and new questions about the same project. Re-call ONLY if:
  - The user asks about a different project_id whose context you have not yet fetched this conversation.
  - The user explicitly asks you to refresh or reload business context.
  - You called Update-Business-Context this conversation and need the new content.

What you get back:
- Specialized instructions on how to query data in this org
- How projects, events, and other entities are organized and named
- Business vocabulary and definitions (acronyms, internal product names, etc.)

Params:
 - project_id (int, optional): If provided, returns context for the project AND its organization. organization_id is not required in this case — the org is derived from the project.
 - organization_id (int, optional): Required when project_id is NOT provided. Call List-Organizations FIRST to obtain it. If List-Organizations returns exactly one org, use its id directly; if it returns more than one, ASK the user which org they mean before calling this tool.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `organization_id` (`string`, optional): Mixpanel organization ID. Required when project_id is not provided — call List-Organizations first to obtain it; if it returns exactly one org, use its id directly, otherwise ask the user which org they mean.
- `project_id` (`string`, optional): Mixpanel project ID. If provided, returns context for the project and its organization; organization_id is not required in this case.

Example input: `{}`

### `mixpanelmcp_get_cohort`

Get Cohort · Read-only

Retrieve a single Mixpanel cohort by ID.

Returns the cohort's metadata (name, description, member count, visibility, creator, and last-updated time) along with its filter criteria in the structured CohortDefinition format. Mixpanel tracks only the last-updated time; there is no creation timestamp for cohorts.

If the cohort's underlying definition contains filter shapes this tool does not yet model, the structured `definition` field is omitted (`null`), `unmodeled_clause_kinds` lists the unsupported shapes, and `definition_raw` returns the wire-format definition so you can still inspect the cohort's structure.

`workspace_id` is required here, unlike List-Cohorts, which lists cohorts project-wide when `workspace_id` is omitted.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `cohort_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`integer`, required): No description.

Example input: `{"cohort_id":1,"project_id":1,"workspace_id":1}`

### `mixpanelmcp_get_custom_property`

Get Custom Property · Read-only

Get a custom property by id, including its full definition (behavior or
display_formula + composed_properties).

Use this before Update-Custom-Property to see the current definition.
Custom property ids come from List-Properties (custom properties are
named '$custom_property:<id>').

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `custom_property_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"custom_property_id":1,"project_id":1}`

### `mixpanelmcp_get_dashboard`

Get Dashboard · Read-only

Set include_layout=True to get full layout with cell/row IDs (needed for Update-Dashboard).
Layout format: [[row_id, [[cell_id, type, extra], ...]], ...].

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `dashboard_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `include_layout` (`boolean`, optional): No description. Default: `false`.

Example input: `{"dashboard_id":1,"project_id":1}`

### `mixpanelmcp_get_events`

Get Events · Read-only

Get events for a Mixpanel project.

Two lookup modes (mutually exclusive):
- event_names: Look up specific events by exact name. Lightweight server-side filter.
- query: Search/discover events by substring match (case-insensitive). Fetches all events.

include_details: When True, return full event metadata (tags, description, display_name, verified, hidden, dropped) for each event.
Set to false if no details are needed, to keep the response compact.
tag: Filter to events that have this tag name.
verified/hidden/dropped: Filter by metadata status (True or False).

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `dropped` (`string`, optional): No description.
- `event_names` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `include_details` (`boolean`, optional): No description. Default: `false`.
- `query` (`string`, optional): No description.
- `tag` (`string`, optional): No description.
- `verified` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_experiment`

Get Experiment · Read-only

Get the full configuration for an experiment, including metadata, variants, metrics (with IDs, type, and direction), cached results, and the experiment's URL in the Mixpanel UI. Metric IDs are included in the response; use the List Metrics tool to look up saved metrics by name.

Set compute_exposures to true to refresh live exposure counts and Sample Ratio Mismatch (SRM) analysis. Set compute_metrics to true to refresh per-metric lift, confidence interval, p-value, and significance, plus the retrospective A/A health-check verdict. Both flags write the refreshed values back to the experiment's cache on the server and may trigger an automatic conclude transition, so treat them as an action rather than a passive read. Any non-fatal errors that occur while computing these values are returned alongside the results instead of failing the whole call. Either flag requires a workspace; when workspace_id is omitted, the project's default workspace is used automatically.

To turn the returned fields into a ship or no-ship decision, use the Get Experiment Results Interpretation Guidance tool.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `experiment_id` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `compute_exposures` (`boolean`, optional): No description. Default: `false`.
- `compute_metrics` (`boolean`, optional): No description. Default: `false`.
- `workspace_id` (`string`, optional): No description.

Example input: `{"experiment_id":"<experiment_id>","project_id":1}`

### `mixpanelmcp_get_experiment_results_interpretation_guidance`

Get Experiment Results Interpretation Guidance · Read-only

Returns best-practice guidance for interpreting Mixpanel experiment results and deciding whether to ship, iterate, or kill an experiment.

Call this tool when analyzing or reasoning about experiment results — including reviewing a concluded experiment, interpreting p-values, lift, or Sample Ratio Mismatch (SRM), or deciding whether to ship a variant. Treat the response as the canonical results-interpretation reference; use it before calling Update Experiment with action="decide".

Takes no input parameters. Equivalent to reading the guidance://experiments/results-interpretation MCP resource — offered as a tool for clients that don't read resources directly.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_get_experiment_setup_guidance`

Get Experiment Setup Guidance · Read-only

Returns best-practice guidance for designing a Mixpanel experiment before launch.

Call this tool when creating, configuring, or troubleshooting an experiment's setup — including writing a hypothesis, choosing metrics, sizing the sample, or picking a testing model. Treat the response as the canonical setup guidance; use it to propose or validate an experiment configuration before calling Create Experiment.

Takes no input parameters. Equivalent to reading the guidance://experiments/setup MCP resource — offered as a tool for clients that don't read resources directly.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_get_feature_flag`

Get Feature Flag · Read-only

Get full configuration for a specific feature flag.

Returns metadata, variants, rollout rules, experiment link, and UI URL.
For listing flags, use mixpanelmcp_list_feature_flags.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `flag_id` (`string`, required): Unique identifier of the feature flag to retrieve.
- `project_id` (`integer`, required): Mixpanel project ID the flag belongs to.
- `workspace_id` (`integer`, required): Mixpanel workspace ID that scopes this request.

Example input: `{"flag_id":"<flag_id>","project_id":1,"workspace_id":1}`

### `mixpanelmcp_get_feature_flag_lifecycle_guidance`

Get Feature Flag Lifecycle Guidance · Read-only

Returns best-practice guidance for managing a Mixpanel feature flag after creation — staged rollout, kill-switch, hygiene/cleanup, archival, exposure tracking, and experiment linkage.

Call this when the user is rolling out, monitoring, killing, archiving, or cleaning up an existing feature flag, or asking about exposure tracking or flag-to-experiment links. The response is the canonical lifecycle guidance document; follow it when reasoning about post-creation flag operations.

No input parameters. Equivalent to reading the `guidance://feature-flags/lifecycle` MCP resource — provided as a tool for clients that don't read resources directly.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_get_feature_flag_setup_guidance`

Get Feature Flag Setup Guidance · Read-only

Returns best-practice guidance for creating and configuring a Mixpanel feature flag.

Call this when the user is creating, configuring, or troubleshooting a feature-flag setup — including choosing the flag type (Feature Gate vs Dynamic Config vs Experiment-backed), naming the flag, defining variants, or deciding on initial rollout. The response is the canonical setup guidance document; follow it when proposing or validating feature-flag configuration.

No input parameters. Equivalent to reading the `guidance://feature-flags/setup` MCP resource — provided as a tool for clients that don't read resources directly.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_get_issues`

Get Issues · Read-only

Get all data quality issues for a Mixpanel project.
Returns rich context with human-readable descriptions, event/property names,
timestamps, and variance details.
Filter by event name, property name, issue type, status, date range, or search by description.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `event_name` (`string`, optional): No description.
- `issue_type` (`string`, optional): No description.
- `limit` (`string`, optional): No description.
- `offset` (`string`, optional): No description.
- `property_name` (`string`, optional): No description.
- `query` (`string`, optional): No description.
- `since_date` (`string`, optional): No description.
- `status` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_lexicon_url`

Get Lexicon URL · Read-only

Return a Mixpanel Lexicon transformations detail URL for an event or property. Provide either event or property along with project_id.

If workspace_id is omitted, the tool will choose the 'All project data' workspace. Use this when the user wants to change event/property metadata such as display name and description.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project that contains the event or property.
- `event` (`string`, optional): The event name to look up in Lexicon.
- `property` (`string`, optional): The property name to look up in Lexicon.
- `workspace_id` (`string`, optional): The workspace to scope the lookup to. Default: `0`.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_live_events`

Get Live Events · Read-only

Recent events streaming into a project, newest first, with event name,
time, and distinct ID. Use it to confirm newly instrumented events are
arriving, or to debug what just happened for one user.

Present the complete returned numbered Markdown table exactly as returned,
with columns # | Event | Time | Distinct ID. Render it as a table, without
a code fence. Include every row, preserving duplicates, row numbers, and
newest-first order. Time is formatted as YYYY-MM-DD HH:MM:SS in the
project's timezone, with daylight-saving time applied for each event.
Do not group events, calculate counts, add a Count column, collapse events
into "Other", truncate the listing, or replace it with a summary.
Do not add commentary, comparisons with previous results, or inferred
properties. Missing distinct IDs must remain marked as missing.
This tool only returns these three fields; changing filters or the limit
does not expose additional properties.

For event definitions, tags, or verified status use Get-Events; for counts,
trends, conversion, or paths use Run-Query. An event can exist in Get-Events
without arriving, and can arrive before Get-Events knows it.

An empty result means nothing has arrived yet, not a failure.

Params: project_id (int), workspace_id (int), event_names (list of exact names to
filter to), search (free text across properties, e.g. a distinct id or email),
limit (default 15, max 100), paging_window (days back, default and max 30),
from_date / to_date ("YYYY-MM-DD", default today in the project's timezone).

Read only: yes. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `project_id` (`integer`, required): No description.
- `workspace_id` (`integer`, required): No description.
- `event_names` (`string`, optional): No description.
- `from_date` (`string`, optional): No description.
- `limit` (`string`, optional): No description.
- `paging_window` (`string`, optional): No description.
- `search` (`string`, optional): No description.
- `to_date` (`string`, optional): No description.

Example input: `{"project_id":1,"workspace_id":1}`

### `mixpanelmcp_get_lookup_table`

Get Lookup Table · Read-only

Read a lookup table by id or name, or list all lookup tables.

Provide `data_group_id` or `name` to get one table's schema (columns),
row count, and a capped preview of its rows. Omit both to list every
lookup table in the project (metadata only) — useful for discovering
table names/ids. The `id` returned for each table is the `data_group_id`
you pass back to this tool or to Update-Lookup-Table.

The preview is capped by `preview_limit` (default 100) and may be smaller
than `row_count` — it is a sample, not the full table. Use it to inspect
the schema and existing values; to change rows, send only the rows you
want to add/overwrite (`upsert_rows`) or remove (`delete_keys`) to
Update-Lookup-Table, which applies the delta to the full table for you.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `data_group_id` (`string`, optional): No description.
- `name` (`string`, optional): No description.
- `preview_limit` (`integer`, optional): No description. Default: `100`.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_metric`

Get Metric · Read-only

Get the full definition of a saved metric.

Returns the metric's complete structure: the events it counts (or references, for a formula), any mathematical expression combining multiple metrics, property filters, and the aggregation method (for example, unique users or total count). Use this to inspect an existing metric, copy its definition as a starting point for a new one, or verify its configuration before referencing it in an experiment.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `metric_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.

Example input: `{"metric_id":1,"project_id":1}`

### `mixpanelmcp_get_project_token`

Get Project Token · Read-only

A project's Mixpanel tracking token — the value an SDK is initialized with to send
events to api.mixpanel.com/track. Use it when instrumenting tracking.

This is NOT the API Secret or a service account, which are what reading data OUT of
Mixpanel needs. Do not call this for those.

Reading the token needs project owner or admin access, so a permission error means
the user should ask an org admin rather than retrying. Treat the value as a
credential: give it to the user, and keep it out of files, logs, and commits.

Params: project_id (int).

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_get_projects`

Get Projects · Read-only

If you have not yet called Get-Business-Context this conversation, call it FIRST — it may resolve project nicknames, acronyms, or org-specific terms in the user's request and tell you which project to pick without listing them.

Get projects that are accessible to current user. Returns the project's id, name, workspaces and context. Use this and prompt the user to select a project from the available projects.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_get_property_values`

Get Property Values · Read-only

Get values for one or more properties, returned as a table.

properties: one or more property names. With a single property the
result is a one-column table of its distinct values. With multiple
Event properties the result has one column per property so you can
see which values co-occur on the same events. Prefer this over the
deprecated single-string 'property' alias.

property: DEPRECATED alias for a single-element 'properties'. Use
'properties' instead. Passing both 'property' and 'properties' with
conflicting values is an error.

result_mode (Event properties only):
- 'grouped' (default): deduped combinations of the property values
  with a 'count' column, sorted by count descending.
- 'expanded': one row per event occurrence, with a 'time' column,
  sorted by time. Use this to inspect raw, high-cardinality values
  (e.g. free-text) alongside their co-occurring properties.

limit: maximum rows to return (default 100, max 1000). When results
are truncated a trailing note row makes the cap explicit.
from_date / to_date (YYYY-MM-DD): query window for the returned
values. For the multi-property and expanded paths this defaults to
the trailing ~30 days; for the single-property distinct-values path,
omitting it falls back to the server's default trailing window.

For Event properties, the 'event' parameter is required. User
properties support only a single property in grouped mode.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `resource_type` (`string`, required): No description. One of: `Event`, `User`.
- `event` (`string`, optional): No description.
- `from_date` (`string`, optional): No description.
- `limit` (`integer`, optional): No description. Default: `100`.
- `properties` (`string`, optional): No description.
- `property` (`string`, optional): No description.
- `result_mode` (`string`, optional): No description. One of: `grouped`, `expanded`. Default: `grouped`.
- `to_date` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1,"resource_type":"Event"}`

### `mixpanelmcp_get_query_schema`

Get Query Schema · Read-only

Get the full instructions and JSON schema for building a full Mixpanel query. Call this to learn all available fields and options for the 'report' parameter in Run-Query.

report_type: 'insights', 'funnels', 'flows', or 'retention'.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `report_type` (`string`, required): The Mixpanel report type to fetch the query-building schema for. One of: `insights`, `funnels`, `flows`, `retention`.

Example input: `{"report_type":"insights"}`

### `mixpanelmcp_get_report`

Get Report · Read-only

Retrieve a saved report's metadata from a Mixpanel project. Optionally include the report results if it's a queryable report type.

Returns report metadata (id, name, type, creator info, timestamps) but NOT the query definition. To build a similar query, call Get-Query-Schema for the report type, then Run-Query.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `bookmark_id` (`integer`, required): The ID of the saved report (bookmark) to retrieve.
- `project_id` (`integer`, required): The Mixpanel project ID that contains the saved report.
- `skip_results` (`boolean`, optional): Whether to skip executing the report and only return its metadata. Default: `true`.

Example input: `{"bookmark_id":1,"project_id":1}`

### `mixpanelmcp_get_user_replays_data`

Get User Replays Data · Read-only

Get session replays information. Provide either a distinct_id (with from_date and to_date) to find all replays for a user, OR a list of specific replay_ids (up to 20) to analyze directly.

Optionally include event_properties (up to 5) to fetch specific property values for each event.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project to fetch session replays from.
- `distinct_id` (`string`, optional): The user's distinct_id to find replays for.
- `event_properties` (`string`, optional): Up to 5 event property names to include values for.
- `from_date` (`string`, optional): Start of the date range to search for replays.
- `replay_ids` (`string`, optional): Up to 20 specific replay IDs to analyze directly.
- `to_date` (`string`, optional): End of the date range to search for replays.

Example input: `{"project_id":1}`

### `mixpanelmcp_list_cohorts`

List Cohorts · Read-only

List all cohorts in a Mixpanel project.

Returns a lightweight list of cohort headers: ID, name, description, and member count. Use the optional `query` parameter to filter cohorts by name (case-insensitive substring match).

`workspace_id` is optional: omit it to list cohorts across the whole project, or pass one to scope results to a single workspace.

The returned `count` is frequently empty (`null`). Mixpanel suppresses cached member counts in non-global workspaces, and in projects with sensitive or classified properties, for callers without sensitive-data access. Call Get-Cohort on a specific cohort ID for an authoritative count and the full cohort definition.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `query` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_list_dashboards`

List Dashboards · Read-only

Prefer Search-Entities with entity_types=['dashboard'] instead, it offers more flexibility and efficiency.

Returns a list of all the dashboards in the project.
Use query to filter by title (case-insensitive substring match).

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `query` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_list_experiments`

List Experiments · Read-only

List and search experiments in a Mixpanel project. Filter by status, name (case-insensitive substring match), creator email, creation date, or tags. Use Get Experiment to fetch the full configuration for a specific experiment.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `created_after` (`string`, optional): No description.
- `creator_email` (`string`, optional): No description.
- `include_archived` (`boolean`, optional): No description. Default: `false`.
- `name` (`string`, optional): No description.
- `status` (`string`, optional): No description.
- `tags` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_list_feature_flags`

List Feature Flags · Read-only

List and search feature flags in a project.

Filter by status, key, name, creator, or creation date.
Use mixpanelmcp_get_feature_flag for full configuration.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): Mixpanel project ID to list feature flags for.
- `workspace_id` (`integer`, required): Mixpanel workspace ID that scopes this request.
- `created_after` (`string`, optional): Only return flags created after this timestamp.
- `creator_email` (`string`, optional): Only return flags created by this user.
- `include_archived` (`boolean`, optional): Whether to include archived feature flags in the results. Default: `false`.
- `key` (`string`, optional): Only return the flag with this exact key.
- `name` (`string`, optional): Only return flags whose display name matches this value.
- `status` (`string`, optional): Only return flags with this status.

Example input: `{"project_id":1,"workspace_id":1}`

### `mixpanelmcp_list_metrics`

List Metrics · Read-only

List all saved metrics in a Mixpanel project.

Returns each metric's ID, name, type, and description. Use this before creating an experiment to find an existing metric you can reuse instead of redefining it. Call Get-Metric on a specific metric ID for its full definition, and reference a metric by ID when configuring an experiment.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `query` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_list_organizations`

List Organizations · Read-only

Returns the organizations the current user belongs to.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs: none.

Example input: `{}`

### `mixpanelmcp_list_properties`

List Properties · Read-only

List properties for a Mixpanel project. Returns name and type by default.

Two lookup modes (mutually exclusive):
- names: Look up specific properties by exact name (max 100).
- query: Search/discover properties by substring match (case-insensitive).

resource_type: 'Event' for event properties, 'User' for user properties, or omit for both.
events: Scope to one or more events' properties (only valid with resource_type='Event' or omitted).

attributes: Extra attributes to include in the response. Valid values:
description, display_name, hidden, dropped, sensitive, example_value, merged, tags, events.
The 'events' attribute is only allowed when 'names' is provided —
it requires a specific set of properties to look up event associations for.
It is also expensive for large projects, so only request it when needed.
tag: Filter to properties that have this tag name.
hidden/dropped/sensitive: Filter by metadata status (True or False).

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `attributes` (`string`, optional): No description.
- `dropped` (`string`, optional): No description.
- `events` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `names` (`string`, optional): No description.
- `query` (`string`, optional): No description.
- `resource_type` (`string`, optional): No description.
- `sensitive` (`string`, optional): No description.
- `tag` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_run_experiment_pre_launch_checks`

Run Experiment Pre-Launch Checks · Read-only

Checks a draft experiment's configuration against nine known pre-launch pitfalls and returns a structured report of findings. Call this before launching an experiment, once the primary metrics, baseline rate, minimum detectable effect (MDE), cohort size, and other configuration values have been chosen, to confirm the setup is sound.

The checks it can report:
- Pre-experiment bias likely: retrospective A/A checking is enabled and a continuous-type primary metric is configured, but CUPED variance reduction is off.
- High variance without Winsorization: a continuous-type metric is configured but outlier capping (Winsorization) is off.
- Multiple primaries without Bonferroni correction: two or more primary metrics are configured with no Bonferroni multiple-testing correction.
- Underpowered, duration insufficient (blocker): expected exposures are less than half of the per-arm sample size the configured baseline rate and MDE require.
- Underpowered, duration marginal: expected exposures are between half and a full per-arm required sample size.
- Cohort too small (blocker): the configured cohort can't supply enough eligible users — per-arm target multiplied by the number of arms — for every arm to reach its target. Pass num_arms for experiments with more than two variants; it defaults to 2.
- Missing guardrails: no guardrail metrics are configured.
- Hypothesis/metric mismatch: the hypothesis text mentions an outcome (for example signup, conversion, retention, or revenue) that no configured primary metric name reflects.
- Primary lacks a leading indicator: a retention-type primary metric is configured with no conversion- or funnel-type secondary metric to serve as an earlier read on the same outcome. Pass secondary_metric_types and secondary_metric_count so this check can run; without them it is skipped.

Each finding carries a severity of blocker, warning, or fyi, and most carry a suggested fix (for example extending the duration, enabling CUPED, enabling Winsorization, enabling Bonferroni correction, adding a guardrail, resizing the cohort or sample, or reviewing metric alignment) that maps directly onto a follow-up Update Experiment call.

This tool only reports findings — it does not block experiment creation itself. Blocker-severity findings should be surfaced prominently before the user confirms launch, but Create Experiment and Update Experiment enforce the actual gate.

Findings are sorted with blockers first, then warnings, then informational notes. All inputs except target_sample_size are optional; any check whose required inputs are missing is silently skipped, so this tool can be called iteratively as configuration fields are filled in.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `target_sample_size` (`integer`, required): No description.
- `baseline_rate` (`string`, optional): No description.
- `bonferroni_enabled` (`boolean`, optional): No description. Default: `false`.
- `cohort_size` (`string`, optional): No description.
- `cuped_enabled` (`boolean`, optional): No description. Default: `false`.
- `expected_exposures` (`string`, optional): No description.
- `guardrail_metric_count` (`integer`, optional): No description. Default: `0`.
- `hypothesis_text` (`string`, optional): No description.
- `mde` (`string`, optional): No description.
- `num_arms` (`integer`, optional): No description. Default: `2`.
- `primary_metric_count` (`integer`, optional): No description. Default: `1`.
- `primary_metric_names` (`string`, optional): No description.
- `primary_metric_types` (`string`, optional): No description.
- `retro_aa_enabled` (`boolean`, optional): No description. Default: `false`.
- `secondary_metric_count` (`integer`, optional): No description. Default: `0`.
- `secondary_metric_names` (`string`, optional): No description.
- `secondary_metric_types` (`string`, optional): No description.
- `winsorization_enabled` (`boolean`, optional): No description. Default: `false`.

Example input: `{"target_sample_size":1}`

### `mixpanelmcp_run_query`

Run Query · Read-only

Run a single analytics query and return its results directly. Use this whenever the user requests a chart, a report, a metric, explore a behavior or root cause, or asks to "create a report".

Returns results to chain queries iteratively. Only use skip_results=true when building a dashboard or you won't use the results.

Report types:
- insights: Basic report, supports different chart types, trends, and metric aggregations.
- funnels: Conversion rates between sequential events within a time window. Requires at least 2 steps.
- flows: Most frequent user paths to or from events. Shows steps before/after/between events as a sankey or paths chart.
- retention: User engagement over time. Requires exactly 2 events: an initial action and a retention action.

For very simple insights queries, use this schema as the `report` parameter:
{
  "name": "string",
  "metrics": [
    {
      "eventName": "string",
      "measurement": {
        "type": "basic",
        "math": "total | unique"
      }
    }
  ],
  "chartType": "table | line | bar",
  "unit": "hour | day | week | month",
  "dateRange": {
    "type": "relative",
    "range": {
      "unit": "day | week | month",
      "value": "integer"
    }
  }
}

Breakdowns split results by a property. Each breakdown's property fields must be nested under a `metric` object (do NOT place `type`/`propertyName` at the breakdown's top level). For example, to split "All Events" into individual events by the "Event Name" property:
"breakdowns": [
  {"metric": {"type": "property", "propertyName": "Event Name", "resource": "event"}}
]

For more elaborated queries, with multiple events, filters, breakdowns, formulas or advanced measurements you must call Get-Query-Schema(report_type: 'insights'|'funnels'|'flows'|'retention') first to see the full schema for the `report` parameter.

Keep responses compact: prefer short date ranges (7-30 days) or coarser granularity (week/month), and avoid combining many breakdowns with fine-grained time series.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project to run the query against.
- `report` (`object`, required): The query definition object for the chosen report type.
- `report_type` (`string`, required): The kind of analytics report to run. One of: `insights`, `retention`, `funnels`, `flows`.
- `skip_results` (`boolean`, optional): Whether to run the query without returning its results. Default: `false`.
- `workspace_id` (`string`, optional): Optional workspace to scope the query to.

Example input: `{"project_id":1,"report":{},"report_type":"insights"}`

### `mixpanelmcp_search_entities`

Search Entities · Read-only

Search entities in a Mixpanel project: dashboards, reports, experiments, feature flags, metric trees, playlists, and heat maps.

query: can be empty to browse by sort order.
entity_types: set to include specific entity types. Values: insights, funnels, flows, retention, dashboard, launch-analysis, experiments, feature-flags, metric-trees, playlists, heat-maps.

- Use Get-Report to fetch full details for insights, funnels, flows, and retention types.
- Use Get-Dashboard to fetch full details for dashboards.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): The Mixpanel project to search within.
- `entity_types` (`string`, optional): Limit results to these entity types.
- `limit` (`integer`, optional): Maximum number of entities to return. Default: `25`.
- `query` (`string`, optional): Search text to match against entity names. Default: ``.
- `sort_by` (`string`, optional): How to order the search results.

Example input: `{"project_id":1}`

### `mixpanelmcp_search_prior_experiments`

Search Prior Experiments · Read-only

Search a project's past experiments for prior tests on the same feature, metric, or hypothesis, so you can check what was already learned before running a similar test again.

Pass whichever of metric_ids, flag_key, and hypothesis are already known for the experiment being planned — any single one is enough to get matches, and supplying more sharpens the ranking. Results combine three signals: overlap between the metric IDs, similarity between flag keys (exact, case-insensitive, substring, or shared-token match), and overlap between hypothesis wording. Each match includes its similarity reasons so you can see why a prior experiment was considered relevant.

Pass exclude_experiment_id when ranking candidates against a draft experiment that's already saved in the store, so the draft doesn't match itself. Set include_archived to true to also search archived experiments.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `exclude_experiment_id` (`string`, optional): No description.
- `flag_key` (`string`, optional): No description.
- `hypothesis` (`string`, optional): No description.
- `include_archived` (`boolean`, optional): No description. Default: `false`.
- `max_matches` (`integer`, optional): No description. Default: `3`.
- `metric_ids` (`string`, optional): No description.
- `min_similarity` (`number`, optional): No description. Default: `0.1`.

Example input: `{"project_id":1}`

### `mixpanelmcp_bulk_edit_events`

Bulk Edit Events · Write

Edit multiple events at once. Supports two modes:

1. Uniform fields (applied to ALL events): hidden, verified, dropped,
   tags, contact_emails, team_contact_names.
2. Per-event fields (on individual events in the events list):
   description, display_name.

Both modes can be combined in a single call.
Maximum 50 events per call.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `events` (`array`, required): No description.
- `project_id` (`integer`, required): No description.
- `contact_emails` (`string`, optional): No description.
- `dropped` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `tags` (`string`, optional): No description.
- `team_contact_names` (`string`, optional): No description.
- `verified` (`string`, optional): No description.

Example input: `{"events":[],"project_id":1}`

### `mixpanelmcp_bulk_edit_properties`

Bulk Edit Properties · Write

Edit multiple properties at once. Supports two modes:

1. Uniform fields (applied to ALL properties): hidden, dropped, sensitive, tags.
2. Per-property fields (on individual entries in the properties list):
   description, display_name, example_value.

Both modes can be combined in a single call.
All properties must share the same resource_type ("Event" or "User").

Maximum 50 properties per call.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `properties` (`array`, required): No description.
- `resource_type` (`string`, required): No description. One of: `Event`, `User`.
- `dropped` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `sensitive` (`string`, optional): No description.
- `tags` (`string`, optional): No description.

Example input: `{"project_id":1,"properties":[],"resource_type":"Event"}`

### `mixpanelmcp_create_cohort`

Create Cohort · Write

Create a new Mixpanel cohort — a saved, named group of users matching a set of criteria.

Pass `definition` as an object matching the CohortDefinition schema, in either the grouped format (a `groups[]` filters grammar) or the lower-level selector format (`behaviors{}` plus a compound `selector` expression, used for cohorts that embed funnel or retention report behaviors). Call Describe-Cohort-Schema first to retrieve the full JSON schema and the required fields for each format.

In the grouped format, each group's `event` identifies the anchor cohort that the filters narrow down. This is almost always `{"resourceType": "cohort", "value": "$all_users"}`. To anchor on members of an existing cohort instead, set `value` to that cohort's integer ID.

`workspace_id` is required here, unlike List-Cohorts, which lists cohorts project-wide when `workspace_id` is omitted.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `definition` (`object`, required): No description.
- `name` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`integer`, required): No description.
- `description` (`string`, optional): No description.
- `is_visible` (`string`, optional): No description. Default: `true`.

Example input: `{"definition":{},"name":"<name>","project_id":1,"workspace_id":1}`

### `mixpanelmcp_create_custom_property`

Create Custom Property · Write

Create a formula-based custom property (a computed event or user
property) in a project.

Define it with a `display_formula` expression that references named
`composed_properties` variables (_A, _B, ...). Every property used in the
formula must be mapped in `composed_properties` — use List-Properties to
find the properties to compose. `resource_type` is 'events' or 'people'.
The created property appears in Lexicon and is usable in reports.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `custom_property` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"custom_property":"<custom_property>","project_id":1}`

### `mixpanelmcp_create_dashboard`

Create Dashboard · Write

Create a Mixpanel dashboard that combines multiple reports and text into a single view.
Use when the user asks for a "dashboard," "board", or requests to save several reports grouped together.
For a single report request, prefer Run-Query.

Requires query_id(s) from prior Run-Query calls (use skip_results=true to chain multiple queries).

Max 30 rows per dashboard.
Each row can contain up to 4 items (text cards or reports).

Row schema: {'$defs': {'ReportContent': {'additionalProperties': False, 'description': 'Report content for a dashboard row.', 'properties': {'type': {'const': 'report', 'default': 'report', 'title': 'Type', 'type': 'string'}, 'query_id': {'description': 'query_id from Run-Query', 'title': 'Query Id', 'type': 'string'}, 'name': {'maxLength': 255, 'title': 'Name', 'type': 'string'}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'title': 'Description'}}, 'required': ['query_id', 'name'], 'title': 'ReportContent', 'type': 'object'}, 'TextContent': {'additionalProperties': False, 'description': 'Text content for a dashboard cell.', 'properties': {'type': {'const': 'text', 'default': 'text', 'title': 'Type', 'type': 'string'}, 'html_content': {'description': 'HTML content for the text card. Allowed tags: a, blockquote, br, code, em, h1, h2, h3, hr, li, mark, ol, p, s, strong, u, ul. Other tags are stripped. Do not include newlines; Each html element means a new line.', 'maxLength': 2000, 'title': 'Html Content', 'type': 'string'}}, 'required': ['html_content'], 'title': 'TextContent', 'type': 'object'}}, 'description': 'A row to add to a dashboard.', 'properties': {'contents': {'items': {'discriminator': {'mapping': {'report': '#/$defs/ReportContent', 'text': '#/$defs/TextContent'}, 'propertyName': 'type'}, 'oneOf': [{'$ref': '#/$defs/TextContent'}, {'$ref': '#/$defs/ReportContent'}]}, 'maxItems': 4, 'minItems': 1, 'title': 'Contents', 'type': 'array'}}, 'required': ['contents'], 'title': 'DashboardRow', 'type': 'object'}
Time filter schema: {'$defs': {'DateRange': {'description': 'Date range specification for dashboard time filter.', 'properties': {'type': {'description': 'Type of date range', 'enum': ['since', 'between', 'in the last'], 'title': 'Type', 'type': 'string'}, 'from': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "Start date (YYYY-MM-DD) for 'since' or 'between'", 'title': 'From'}, 'to': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': "End date (YYYY-MM-DD) for 'between'", 'title': 'To'}, 'window': {'anyOf': [{'$ref': '#/$defs/TimeWindow'}, {'type': 'null'}], 'default': None, 'description': "Time window for 'in the last'"}}, 'required': ['type'], 'title': 'DateRange', 'type': 'object'}, 'TimeWindow': {'description': 'Time window for relative date ranges.', 'properties': {'unit': {'description': 'Time unit', 'enum': ['day', 'week', 'month'], 'title': 'Unit', 'type': 'string'}, 'value': {'description': 'Number of units', 'minimum': 1, 'title': 'Value', 'type': 'integer'}}, 'required': ['unit', 'value'], 'title': 'TimeWindow', 'type': 'object'}}, 'description': 'Dashboard time filter.', 'properties': {'dateRange': {'$ref': '#/$defs/DateRange', 'description': 'Date range configuration'}, 'displayText': {'description': "Human-readable display text, e.g. 'Last 30 days'", 'title': 'Displaytext', 'type': 'string'}}, 'required': ['dateRange', 'displayText'], 'title': 'DashboardTimeFilter', 'type': 'object'}

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `project_id` (`integer`, required): No description.
- `rows` (`array`, required): No description.
- `title` (`string`, required): No description.
- `description` (`string`, optional): No description.
- `is_private` (`string`, optional): No description. Default: `false`.
- `is_restricted` (`string`, optional): No description. Default: `false`.
- `time_filter` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"project_id":1,"rows":[],"title":"<title>"}`

### `mixpanelmcp_create_experiment`

Create Experiment · Write

Create a new experiment in DRAFT status in the specified project.

Before calling this tool for setup decisions — writing the hypothesis, choosing metrics, sizing the sample, picking a testing model or end condition, or configuring advanced features like CUPED, Winsorization, or multiple-testing correction — call the Get Experiment Setup Guidance tool first. It is the source of truth for what makes a sound experiment configuration.

project_id and experiment.workspaceId are auto-injected from the caller's session; any value supplied for these is replaced before the request reaches the Mixpanel server, so there is no need to look them up first.

Mechanics:
- For a duration-based experiment, set experiment.settings.endCondition to "days" and set endAfterDays. For a sample-size-based experiment, set endCondition to "sample_size" and set sampleSize.
- Reference existing saved metrics with primaryMetricIds, guardrailMetricIds, and secondaryMetricIds (look up IDs with the List Metrics tool), or define metrics inline in the metrics array using eventName and metricType.
- Only include the variants array when specific variant keys, values, or traffic splits are required. When omitted, Mixpanel creates a default 50/50 control/treatment flag.
- Every create runs the same seven deterministic pre-launch pitfall checks used by Run Experiment Pre-Launch Checks, deriving most inputs (arm count, sample size, metric counts, stats toggles) from the experiment configuration itself. Use the optional validationContext object to supply the few values the server can't derive on its own — baseline rate, minimum detectable effect (MDE), expected exposures, cohort size, and primary-metric measurement types. A blocker-severity finding (such as insufficient expected exposures or too small a cohort) stops the create and returns an actionable error; warning and informational findings are returned on the created experiment instead of blocking it.

After creating the experiment, call Update Experiment with action set to "launch" to start it.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `experiment` (`string`, required): No description.
- `project_id` (`integer`, required): No description.

Example input: `{"experiment":"<experiment>","project_id":1}`

### `mixpanelmcp_create_feature_flag`

Create Feature Flag · Write

`project_id` and `workspace_id` are auto-injected from the caller's session — pass any int and the values you supply will be replaced before the call reaches the server. Do not ask the user for them.

For routing (Feature Gate vs Dynamic Config vs Experiment), input gathering, naming/keying conventions, and per-flagType variant rules, call `mixpanelmcp_get_feature_flag_setup_guidance` first.

Mechanics: flag key is auto-derived from name when omitted; flag starts disabled (use mixpanelmcp_update_feature_flag to enable, or call mixpanelmcp_get_feature_flag_lifecycle_guidance for rollout decisions); rolloutPercentage defaults to 1.0 (100% of targeted traffic). Configure cohort targeting in the Mixpanel UI via the URL in the response.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `flag` (`string`, required): The feature flag definition: flag type, name, key, variants, rollout percentage, initial status, serving method, and context.
- `project_id` (`integer`, required): Mixpanel project ID to create the feature flag in.
- `workspace_id` (`integer`, required): Mixpanel workspace ID that scopes this request.

Example input: `{"flag":"<flag>","project_id":1,"workspace_id":1}`

### `mixpanelmcp_create_lookup_table`

Create Lookup Table · Write

Create a lookup table from rows.

Pass `rows` as a list of {column: value} objects; one column is the
primary key (`primary_key_column`, default "Primary Key") used to join
the table to event/user data. The table appears in Lexicon and can then
be mapped to a property in the UI.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `lookup_table` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"lookup_table":"<lookup_table>","project_id":1}`

### `mixpanelmcp_create_metric`

Create Metric · Write

Create a saved metric for reuse across experiments. A saved metric is either:
- A `metric`: a single event behavior, such as a count, unique users, or DAU/WAU/MAU.
- A `formula`: combines multiple existing metrics using a mathematical expression.

Pass `definition` as an object with a `sections.events` array describing which events to count, the aggregation method (`math`), and any property filters. See the Definition field's schema for the full set of supported filter types and options.

The response includes the new metric's ID, which you then pass to Create-Experiment in `primaryMetricIds`. For complex definitions, call Get-Metric on an existing metric first and use its definition as a template.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `definition` (`string`, required): No description.
- `name` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `type` (`string`, required): No description. One of: `metric`, `formula`.
- `description` (`string`, optional): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"definition":"<definition>","name":"<name>","project_id":1,"type":"metric"}`

### `mixpanelmcp_create_tag`

Create Tag · Write

Create a tag for organizing events and properties in Lexicon.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `name` (`string`, required): No description.
- `project_id` (`integer`, required): No description.

Example input: `{"name":"<name>","project_id":1}`

### `mixpanelmcp_dismiss_duplicate_group`

Dismiss Duplicate Group · Write

Dismiss a duplicate-group suggestion so it no longer appears in Find-Duplicate-Groups results. Works for events and event properties. Does not modify any entity data — only hides the suggestion. There is no un-dismiss, so confirm with the user before calling.

Pass the full entity_names list of the group exactly as returned by Find-Duplicate-Groups (order does not matter; the group is keyed by the set of names), plus the group's entity_type. entity_type must be 'events' or 'event_properties'.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `entity_names` (`array`, required): The full list of names in the group, exactly as returned by Find-Duplicate-Groups. Order does not matter; the group is keyed by the set of names.
- `project_id` (`integer`, required): The Mixpanel project containing the duplicate-group suggestion to dismiss.
- `entity_type` (`string`, optional): Whether entity_names refers to 'events' or 'event_properties'. Default: `events`.

Example input: `{"entity_names":[],"project_id":1}`

### `mixpanelmcp_duplicate_dashboard`

Duplicate Dashboard · Write

Create a copy of an existing dashboard with all its contents.
Optionally override the title and description of the new dashboard.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `dashboard_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `description` (`string`, optional): No description.
- `title` (`string`, optional): No description.

Example input: `{"dashboard_id":1,"project_id":1}`

### `mixpanelmcp_edit_event`

Edit Event · Write

Use contact_emails or team_contact_names for ownership. Set verified=True to
verify/approve events, hidden=True to hide from UI, dropped=True to deprecate.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `event_name` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `contact_emails` (`string`, optional): No description.
- `description` (`string`, optional): No description.
- `display_name` (`string`, optional): No description.
- `dropped` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `tags` (`string`, optional): No description.
- `team_contact_names` (`string`, optional): No description.
- `verified` (`string`, optional): No description.

Example input: `{"event_name":"<event_name>","project_id":1}`

### `mixpanelmcp_edit_property`

Edit Property · Write

Set sensitive=True for PII data classification. Set example_value to populate the example shown in Lexicon.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `property_name` (`string`, required): No description.
- `resource_type` (`string`, required): No description. One of: `Event`, `User`.
- `description` (`string`, optional): No description.
- `display_name` (`string`, optional): No description.
- `dropped` (`string`, optional): No description.
- `example_value` (`string`, optional): No description.
- `hidden` (`string`, optional): No description.
- `sensitive` (`string`, optional): No description.

Example input: `{"project_id":1,"property_name":"<property_name>","resource_type":"Event"}`

### `mixpanelmcp_rename_tag`

Rename Tag · Write

Rename an existing tag in a Mixpanel project.
The new name must be unique within the project (max 175 characters).
This updates all events and properties currently using this tag.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `new_tag_name` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `tag_name` (`string`, required): No description.

Example input: `{"new_tag_name":"<new_tag_name>","project_id":1,"tag_name":"<tag_name>"}`

### `mixpanelmcp_update_business_context`

Update Business Context · Write

Update the business context at the project or organization level. This is a full replace — the new content overwrites whatever exists; there is no merge or partial update. Other users may have authored the current context, so ALWAYS ask the user for explicit confirmation before calling this tool.

Content should be minimal and focused: short, structured markdown notes that capture essential domain knowledge.

Params:
 - context (str, required): The new context content. Pass an empty string to clear.
 - level (str, required): Either the literal string "project" or "organization". Must be passed explicitly so the level is never inferred.
 - project_id (int, required when level="project"): The project to update.
 - organization_id (int, required when level="organization"): The org to update. Call List-Organizations FIRST to obtain it. If List-Organizations returns exactly one org, use its id directly; if it returns more than one, ASK the user which org they mean before calling this tool.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `context` (`string`, required): The new context content to save, as structured markdown. Pass an empty string to clear the existing context.
- `level` (`string`, required): Which level of context to update. Must be the literal string "project" or "organization" — no other values are accepted. One of: `project`, `organization`.
- `organization_id` (`string`, optional): Required when level is "organization": the org whose context should be updated. Call List-Organizations first to obtain it.
- `project_id` (`string`, optional): Required when level is "project": the project whose context should be updated.

Example input: `{"context":"<context>","level":"project"}`

### `mixpanelmcp_update_cohort`

Update Cohort · Write

Update an existing Mixpanel cohort.

All fields (`name`, `description`, `definition`, `is_visible`) are optional; only the fields you provide are changed, and omitted fields keep their current value.

`is_visible` toggles whether the cohort is hidden in the Mixpanel UI. The `is_visible` value returned in the response comes from a separate sharing/visibility serialization path and may not reflect the value you just set — do not rely on the response to confirm a hide or unhide.

To change the cohort's filter criteria, pass a new `definition` object matching the CohortDefinition schema, the same format used by Create-Cohort. Call Describe-Cohort-Schema first if you don't already have that schema.

`workspace_id` is required here, unlike List-Cohorts, which lists cohorts project-wide when `workspace_id` is omitted.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `cohort_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`integer`, required): No description.
- `definition` (`string`, optional): No description.
- `description` (`string`, optional): No description.
- `is_visible` (`string`, optional): No description.
- `name` (`string`, optional): No description.

Example input: `{"cohort_id":1,"project_id":1,"workspace_id":1}`

### `mixpanelmcp_update_custom_property`

Update Custom Property · Write

Update an existing formula-based custom property.

Partial update: pass only the fields you want to change (`name`,
`description`, `display_formula`, `composed_properties`); omitted fields
keep their current value. When changing `display_formula` you must also
pass the complete `composed_properties` mapping for it. `resource_type`
is immutable. Use Get-Custom-Property first to see the current definition.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `custom_property` (`string`, required): No description.
- `custom_property_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"custom_property":"<custom_property>","custom_property_id":1,"project_id":1}`

### `mixpanelmcp_update_dashboard`

Update Dashboard · Write

Call Get-Dashboard with include_layout=True first to get cell/row IDs.
- To update a report cell query_id, call Run-Query first.
- To add rows or cells, use any temporary string ID (e.g. "temp-row-1").
  - To add a cell in a new row, use the row's temp ID in the cell definition.
- For updates and deletes, use real row and cell IDs from Get-Dashboard.

rows: ['<row_id>', 'add'] | ['<row_id>', 'delete']
Content: {type: 'text', html_content: 'string'} | {type: 'report', query_id: 'string', name: 'string', description: 'string'}
cells: ['<cell_id>', 'create', 'text' | 'report', {row_id: 'string', ...Content}] | ['<cell_id>', 'update', 'text' | 'report', {...Content}] | ['<cell_id>', 'delete']

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `dashboard_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `cells` (`string`, optional): No description.
- `description` (`string`, optional): No description.
- `rows` (`string`, optional): No description.
- `rows_order` (`string`, optional): No description.
- `title` (`string`, optional): No description.

Example input: `{"dashboard_id":1,"project_id":1}`

### `mixpanelmcp_update_experiment`

Update Experiment · Write

Update an experiment's configuration, or drive it through its lifecycle, in a single call.

Set experiment.action to run a lifecycle transition:
- "launch" moves the experiment from DRAFT to ACTIVE and enables its linked feature flag.
- "conclude" moves it from ACTIVE to CONCLUDED and disables its linked feature flag.
- "decide" moves it from CONCLUDED to SUCCESS or FAIL and optionally ships the winning variant (see below).
- "archive" soft-deletes the experiment; "restore" undoes an archive.

For action="decide", the required fields depend on the experiment's settings.collectionMethod (call Get Experiment first if you don't already know it):
- Feature-flag experiments: set shipMode to "ship_variant" with variant set to the winning key to ship it, "do_not_ship" to keep serving the control (this implies success=true), or "abandon" to disable the flag entirely (this implies success=false and variant="abandoned"). To record a decision without touching the flag, set success and variant directly and omit shipMode.
- Exposure-events experiments: always omit shipMode. Set success=true with variant set to the winning key to ship it or to the control key to keep control, or set success=false with variant="abandoned" to record an abandoned test. Passing shipMode on an exposure-events experiment returns an UnsupportedCollectionMethod error.

Set keepCohortTargeting to true alongside shipMode "ship_variant" or "do_not_ship" to preserve the experiment's existing cohort restrictions instead of rolling the chosen variant out to 100% of eligible traffic.

Configuration fields — name, description, hypothesis, metrics, settings, and tags — can all be updated independently of any lifecycle action. Reference saved metrics with primaryMetricIds, guardrailMetricIds, and secondaryMetricIds (look up IDs with the List Metrics tool), or define metrics inline in the metrics array using eventName and metricType.

Every field edit and every "launch" runs the same seven deterministic pre-launch pitfall checks used by Run Experiment Pre-Launch Checks, evaluated against the configuration that results after this patch is applied. Use the optional validationContext object to supply values the server can't derive on its own — baseline rate, minimum detectable effect (MDE), expected exposures, cohort size, and primary-metric measurement types. A blocker-severity finding stops the update and returns an actionable error; warning and informational findings are returned on the updated experiment instead of blocking it.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `experiment` (`string`, required): No description.
- `experiment_id` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"experiment":"<experiment>","experiment_id":"<experiment_id>","project_id":1}`

### `mixpanelmcp_update_feature_flag`

Update Feature Flag · Write

Update flag configuration, status, or archive state.

For rollout / kill-switch / archival decisions — including the staged-rollout cadence, when to use status vs rolloutPercentage, and archive-vs-restore semantics — call `mixpanelmcp_get_feature_flag_lifecycle_guidance` first.

All fields on `flag` are optional but at least one is required. To configure cohort targeting or advanced rollout rules, use the Mixpanel UI via the flag's URL (returned by mixpanelmcp_get_feature_flag).

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `flag` (`string`, required): Fields to update on the feature flag: name, description, ruleset (variants and/or rolloutPercentage), and/or status.
- `flag_id` (`string`, required): Unique identifier of the feature flag to update.
- `project_id` (`integer`, required): Mixpanel project ID the flag belongs to.
- `workspace_id` (`integer`, required): Mixpanel workspace ID that scopes this request.

Example input: `{"flag":"<flag>","flag_id":"<flag_id>","project_id":1,"workspace_id":1}`

### `mixpanelmcp_update_lookup_table`

Update Lookup Table · Write

Update a lookup table with a row delta and/or edit name/description.

Send only the cells you want to change — you do NOT need to read or resend
the whole table:
- `upsert_rows`: a list of {column: value} objects to add or patch. When a
  row's `primary_key_column` matches an existing row, only the columns you
  send are updated and the row's other columns are kept; an unmatched key
  is added as a new row. Set a column to "" to blank it; to replace all of
  a row's columns, `delete_keys` it and upsert it in the same call.
- `delete_keys`: a list of primary-key values whose rows to remove. Keys
  not in the table are ignored (reported back under `not_found`).
The server reads the current table, applies the delta, and re-imports the
full result, so a shrink is an explicit `delete_keys` rather than an
omission. The response includes an `update_summary`
({added, updated, deleted, not_found}) so you can confirm what landed.

Pass `name`/`description` to edit metadata. Provide at least one field.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `data_group_id` (`string`, required): No description.
- `lookup_table` (`string`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`string`, optional): No description.

Example input: `{"data_group_id":"<data_group_id>","lookup_table":"<lookup_table>","project_id":1}`

### `mixpanelmcp_update_metric`

Update Metric · Write

Update a saved metric's name, definition, or description. At least one of `name`, `definition`, or `description` is required.

This changes the metric in place, which affects every experiment that already references it. If you need to preserve the original metric's behavior for existing experiments, create a new metric instead of updating this one. Call Get-Metric first to review the current definition before changing it.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `metric_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `definition` (`string`, optional): No description.
- `description` (`string`, optional): No description.
- `name` (`string`, optional): No description.

Example input: `{"metric_id":1,"project_id":1}`

### `mixpanelmcp_delete_cohort`

Delete Cohort · Destructive

Delete a Mixpanel cohort. This action is destructive and cannot be undone — always confirm with the user before deleting a cohort.

Mixpanel blocks deletion if the cohort is still used in active reports or other dependencies, and returns an actionable error message in that case. Use List-Cohorts or Get-Cohort to find the cohort ID.

`workspace_id` is required here, unlike List-Cohorts, which lists cohorts project-wide when `workspace_id` is omitted.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `cohort_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.
- `workspace_id` (`integer`, required): No description.

Example input: `{"cohort_id":1,"project_id":1,"workspace_id":1}`

### `mixpanelmcp_delete_dashboard`

Delete Dashboard · Destructive

Delete a dashboard. Always confirm with the user before proceeding.
Use List-Dashboards or Get-Dashboard to find the dashboard ID.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `dashboard_id` (`integer`, required): No description.
- `project_id` (`integer`, required): No description.

Example input: `{"dashboard_id":1,"project_id":1}`

### `mixpanelmcp_delete_tag`

Delete Tag · Destructive

Delete a tag from a Mixpanel project.
This removes the tag from all associated events and properties.
Use with caution as this operation cannot be undone.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `project_id` (`integer`, required): No description.
- `tag_name` (`string`, required): No description.

Example input: `{"project_id":1,"tag_name":"<tag_name>"}`

### `mixpanelmcp_dismiss_issues`

Dismiss Issues · Destructive

Dismiss data quality issues matching natural criteria - no need to look up IDs first.
Specify what to dismiss using event names, property names, dates, and issue types.

Example: dismiss issues for the 'signup' event from November 15th, or dismiss all
type drift issues for the 'user_id' property.

IMPORTANT: If multiple issues match your criteria, you must set
dismiss_all_matching=True as a safety measure. To dismiss a single issue, provide
enough criteria to uniquely identify it (event + date, or property + date).

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `project_id` (`integer`, required): No description.
- `date` (`string`, optional): No description.
- `dismiss_all_matching` (`boolean`, optional): No description. Default: `false`.
- `event_name` (`string`, optional): No description.
- `issue_type` (`string`, optional): No description.
- `property_name` (`string`, optional): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_fill_event_metadata`

Fill Event Metadata · Destructive

Use AI to fill in missing event metadata for a Mixpanel project. For
every event that is missing a display name and/or description, this
generates one and applies it in bulk to the project's Lexicon.

GAP-FILL ONLY: events that already have both a display name and a
description are left untouched — this never overwrites existing
metadata.

DESTRUCTIVE: it writes metadata to the project's events. Always
confirm with the user before calling.

Returns the number of events whose metadata was filled in.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `project_id` (`integer`, required): No description.

Example input: `{"project_id":1}`

### `mixpanelmcp_merge_group`

Merge Group · Destructive

Merge a group of duplicate names into one canonical entity in a Mixpanel project's Lexicon. Works for events and event properties. DESTRUCTIVE: source entities are remapped to the canonical entity and their historical data is unified. Confirm with the user before calling. However, the merge can be undone in the Mixpanel UI with a single button click, so it's not a permanent action.

Use with Find-Duplicate-Groups: pass its suggested_name as canonical_name, the remaining entity_names as source_names, and the group's entity_type as entity_type. canonical_name is filtered out of source_names automatically.

entity_type must be 'events' or 'event_properties'.

excluded: names from the suggested cluster the user does NOT want to merge. Pass them here (not in source_names) — they are left untouched but are still required to locate the suggestion, so include every name the cluster originally had across canonical + source + excluded.

Server-side restrictions (rejected with an error): Mixpanel default entities, custom entities, dropped entities, entities already merged into another, and names that do not exist in the project.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `canonical_name` (`string`, required): The name to keep as the canonical entity, typically the suggested_name returned by Find-Duplicate-Groups.
- `project_id` (`integer`, required): The Mixpanel project that contains the entities to merge.
- `source_names` (`array`, required): The duplicate names to merge into canonical_name. Must contain at least one entry; canonical_name is filtered out automatically if included.
- `entity_type` (`string`, optional): Whether canonical_name and source_names refer to 'events' or 'event_properties'. Default: `events`.
- `excluded` (`string`, optional): Names from the suggested cluster to leave untouched. Still required to locate the suggestion, so include every name the cluster originally had across canonical, source, and excluded.

Example input: `{"canonical_name":"<canonical_name>","project_id":1,"source_names":[]}`

## Related

Other Analytics connectors ([all 94](/agentkit/connectors/?category=analytics)):

- [Microsoft 365](/agentkit/connectors/microsoft365/): Scalekit connector, OAuth, 317 tools
- [HubSpot](/agentkit/connectors/hubspot/): Scalekit connector, OAuth, 457 tools
- [Snowflake](/agentkit/connectors/snowflake/): Scalekit connector, OAuth, 42 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
