{"id":8020,"plugin_id":"Plugin_646f53d9a40c8191a747ca268ab3d779","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T22:51:46.829Z","digest":"a0c48c10cf70de37a4090a5c672b74885814f0a1be9c6e87fd869ba89332c3ce","against":null,"payload":{"name":"mixpanel-auth","description":"Manage Mixpanel Headless authentication: check session state, list/add/use accounts, run OAuth login, switch projects/workspaces, manage targets, and check bridge credentials.","included_files":[],"skill_md_contents":"---\nname: mixpanel-auth\ndescription: \"Manage Mixpanel Headless authentication: check session state, list/add/use accounts, run OAuth login, switch projects/workspaces, manage targets, and check bridge credentials.\"\n---\n\n# Mixpanel Authentication Management\n\nYou manage Mixpanel credentials by shelling out to `auth_manager.py`. Every\nsubcommand emits exactly one JSON object to stdout — parse it and present the\nresult conversationally.\n\nBefore running bundled scripts, set `PLUGIN_ROOT` to the absolute path of the installed\n`mixpanel-headless` plugin directory.\n\n**Script path:** `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py`\n\n**Schema:** Every response has `schema_version: 1` and a discriminated `state`\nof `ok` | `needs_account` | `needs_project` | `error`. Errors emit JSON to\nstdout (exit 0) so you can `json.loads` unconditionally — no try/except needed.\n\n## Security Rules (NON-NEGOTIABLE)\n\n- **NEVER ask for secrets (passwords, API secrets) in conversation** — they would be visible in history\n- **NEVER pass secrets as CLI arguments** — visible in process list\n- For account creation, guide the user to run `mp account add <name> --type service_account -u <username> -p <project_id> -r <region>` themselves — this prompts for the secret with hidden input\n\n## Routing\n\nParse `$ARGUMENTS` and route to the appropriate subcommand. With no\narguments, run `session`.\n\n### \"login\"\n\nFor first-time setup, the frictionless one-shot path is `mp login`. It\nruns the right auth flow for the environment, derives the account name\nfrom `/me`, and pins a default project. Tell the user to run:\n\n```bash\nmp login\n```\n\nRegion behavior is auth-type-specific:\n- `service_account` and `oauth_token` paths: probes `us → eu → in` and\n  uses the first 200.\n- `oauth_browser` path (the bare-`mp login` default): commits to `us`\n  unless the user passes `--region eu` or `--region in`.\n\nOptional flags they may want:\n- `--name NAME` — override the derived account name\n- `--region us|eu|in` — set the region explicitly (required for EU / India browser users)\n- `--project ID` — skip the project picker\n- `--service-account` — force the SA path (requires `MP_USERNAME` + `MP_SECRET` in env)\n- `--token-env VAR` — force the static-bearer path (reads token from `$VAR`)\n- `--no-browser` — print the authorization URL instead of launching a browser\n\nAfter the user confirms they ran it, verify with `account test`:\n`python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account test`\n\n### No arguments or \"session\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py session`\n\nSwitch on `state`:\n- **`ok`** — show one line: \"Active: `account.name` → project `project.id`\"\n  (add workspace `workspace.id` if non-null). Mention that\n  the account-list and project-list workflows in this skill exist if the user wants to switch.\n- **`needs_account`** — no account configured. Show the first\n  `next[0].command` as the recommended onboarding step (the frictionless\n  `mp login` orchestrator); list the alternatives in `next[1]` (explicit\n  account add) and `next[2]` (`MP_OAUTH_TOKEN` env triple — best for\n  non-interactive contexts like CI or agents).\n- **`needs_project`** — account configured but no project pinned. Tell the\n  user to run `mp project list` then `mp project use <id>`.\n- **`error`** — show `error.message`. If `error.actionable` is true, the\n  message names a concrete next command.\n\n### \"account list\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account list`\n\nPresent `items` as a clean table: `name`, `type`, `region`, `is_active`.\nMark the active account with a star. If `referenced_by_targets` is non-empty\nfor any account, mention it (\"`team` is referenced by targets: `ecom`\").\n\nIf `items` is empty, show the `next` onboarding hints (same as `needs_account`).\n\n### \"account add\"\n\nThis is a guided wizard. Do NOT run any script that handles secrets.\n\n1. Ask for the **account name** (e.g., \"personal\", \"team\", \"ci\")\n2. Ask for the **type** — `oauth_browser` (recommended for laptops),\n   `service_account` (long-lived), or `oauth_token` (CI/agents)\n3. Ask for the **region** (us, eu, or in — default us)\n4. For `service_account`: ask for username and project ID (numeric).\n   For `oauth_token`: ask for project ID and the env-var name holding the bearer.\n   For `oauth_browser`: project ID is OPTIONAL — `mp account login` will\n   backfill it after the PKCE flow.\n5. Then instruct the user to run the appropriate command. For service accounts:\n\n```bash\nNow run this command — it will prompt for your service account secret with hidden input:\n\nmp account add <NAME> --type service_account --username <USERNAME> --project <PROJECT_ID> --region <REGION>\n```\n\nFor OAuth browser, prefer the one-shot `mp login` (covered by the \"login\"\nbranch above):\n\n```bash\nmp login --name <NAME> --region <REGION>\n```\n\nFor full control over registration before the PKCE flow, the explicit\ntwo-step is still available:\n\n```bash\nmp account add <NAME> --type oauth_browser --region <REGION>\nmp account login <NAME>      # opens browser for PKCE flow\n```\n\nReplace placeholders with the values collected above.\n\n6. After the user confirms they ran it, verify with `account test`:\n   `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account test <NAME>`\n7. Report success or failure based on the `result.ok` field.\n\n### \"account use\" or \"account use <name>\"\n\nIf a name is provided:\n- Run: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account use <name>`\n\nIf no name:\n- First run `account list` to show available accounts\n- Ask which to switch to\n- Then run `account use` with the chosen name\n\nOn `state: ok`, show one line: \"Switched to `active.account` (project `active.project`)\".\nOn `state: error`, show `error.message`.\n\n### \"account login\" or \"account login <name>\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account login <name>`\n\nTell the user a browser window will open for Mixpanel authentication.\nWait for the JSON response.\n\nOn `state: ok`: \"OAuth login successful! `logged_in_as.user.email`, token\nvalid until `logged_in_as.expires_at`.\"\nOn `state: error`: Show `error.message` and suggest retrying.\n\n### \"account test\" or \"account test <name>\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py account test [name]`\n\nThe subcommand never raises — `state` is always `ok`. Read `result.ok` to\ndetermine whether the credentials worked:\n- `result.ok: true` → \"Connected as `result.user.email` ·\n  `result.accessible_project_count` accessible projects.\"\n- `result.ok: false` → \"Test failed: `result.error`.\"\n\n### \"project list\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py project list`\n\nPresent `items` as a table: organization, project name, project ID. Mark the\nactive project (`is_active: true`) with a star. Suggest the project-use workflow\nin this skill to switch.\n\n### \"project use <id>\"\n\nIf no ID: run `project list` first, then ask which to switch to.\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py project use <PROJECT_ID>`\n\nOn `state: ok`: \"Switched to project `active.project`.\"\nOn `state: error`: Show `error.message`.\n\n### \"workspace list\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py workspace list`\n\nPresent `items` as a table: workspace ID, name, `is_default`. Mark the\nactive workspace with a star. Mention the parent project from\n`project.name` (`project.id`).\n\n### \"workspace use <id>\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py workspace use <WORKSPACE_ID>`\n\nOn `state: ok`: \"Pinned workspace `active.workspace`.\"\n\n### \"target list\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py target list`\n\nTargets are saved (account, project, workspace?) triples — named cursor\npositions. Present as a table: name, account, project, workspace.\n\n### \"target add\"\n\nGuided wizard — collect target name, account name, project ID, optional\nworkspace ID. Then either invoke the auth_manager directly:\n\n```\npython3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py target add <NAME> --account <ACCT> --project <PROJ> [--workspace <WS>]\n```\n\nOr guide the user to `mp target add <NAME> --account <ACCT> --project <PROJ> [--workspace <WS>]`.\n\n### \"target use <name>\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py target use <name>`\n\nApplies all three axes (`account` / `project` / `workspace`) to `[active]`\nin a single atomic config write.\n\n### \"bridge status\"\n\nRun: `python3 $PLUGIN_ROOT/skills/mixpanelyst/scripts/auth_manager.py bridge status`\n\nParse the JSON:\n- If `bridge` is null → \"No bridge file found. To create one, run\n  `mp account export-bridge --to <path>` on your host machine.\"\n- If `bridge` is non-null → show `bridge.path`, `bridge.account.name`\n  (`bridge.account.type`), pinned `bridge.project` / `bridge.workspace` if set,\n  and any custom `bridge.headers`.\n\n## Bearer-token env vars (`MP_OAUTH_TOKEN`)\n\nFor non-interactive contexts (CI, agents, ephemeral environments) where the\nPKCE browser flow isn't viable, set:\n\n```\nexport MP_OAUTH_TOKEN=<bearer-token>\nexport MP_PROJECT_ID=<project-id>\nexport MP_REGION=<us|eu|in>\n```\n\nThe library builds an `Authorization: Bearer <token>` header for every\nMixpanel endpoint. The full service-account env-var set (`MP_USERNAME` +\n`MP_SECRET` + `MP_PROJECT_ID` + `MP_REGION`) takes precedence when both\nsets are complete, so this is safe to add to a shell that already exports\nthe service-account vars.\n\n## Presentation Style\n\n- Be concise — show status in 1–2 lines, not a wall of JSON\n- Use tables for lists of accounts, projects, workspaces, targets\n- Always suggest a next action when something is missing\n- On errors, show `error.message` verbatim — it names the fix\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}