# External Services & Runtime Dependencies Everything the wizard touches at runtime beyond its own source code: APIs, OAuth flows, status pages, file system locations, CLI tools, credential storage, and environment variables. > **Scope:** This document covers runtime dependencies only — not npm packages. For architecture details see [`architecture.md`](./architecture.md). --- ## Table of Contents - [Amplitude APIs](#amplitude-apis) - [OAuth Flow](#oauth-flow) - [LLM Gateway & Agent](#llm-gateway--agent) - [MCP Server](#mcp-server) - [Health Checks & Status Pages](#health-checks--status-pages) - [Telemetry](#telemetry) - [Feature Flags](#feature-flags) - [Credential Storage](#credential-storage) - [File System Touchpoints](#file-system-touchpoints) - [CLI Tools Invoked](#cli-tools-invoked) - [Environment Variables](#environment-variables) - [Outbound URLs (Browser)](#outbound-urls-browser) --- ## Amplitude APIs ### Data API (GraphQL) The primary backend for user/org/project discovery after authentication. > **Note.** The GraphQL schema still exposes the legacy field name > `workspaces`. At the TS boundary we rename it to `projects` on > `AmplitudeOrg`, matching the Amplitude website terminology. Do not rename the > GraphQL query field — that's a separate backend contract change. | Zone | Endpoint | |------|----------| | US | `https://data-api.amplitude.com/graphql` | | EU | `https://data-api.eu.amplitude.com/graphql` | **Auth:** `Authorization: Bearer ` (OAuth ID token). **Main query** — `orgs` (from `src/lib/api.ts`): ```graphql query orgs { orgs { id name user { id firstName lastName email } workspaces { id name environments { name rank app { id apiKey } } } } } ``` Used to populate org/project/environment pickers and resolve the API key for the selected environment. (GraphQL `workspaces` → TS `projects`; GraphQL `environments` maps to the env picker.) ### App API (GraphQL) Org-scoped endpoint for app-level operations (charts, dashboards, Slack, activation status). **Auth:** `Authorization: Bearer ` (OAuth access token). **Queries used** (from `src/lib/api.ts`): | Query | Purpose | |-------|---------| | `OwnedDashboards` | Fetch user's dashboards and chart IDs (ChecklistScreen) | | `hasAnyDefaultEventTrackingSourceAndEvents` | Project activation status (DataSetupScreen) | | `SlackInstallUrl` | Direct Slack OAuth install URL (SlackScreen) | | `SlackConnectionStatus` | Check if Slack is already connected (SlackScreen) | ### Web App URLs Deep-links opened in the user's browser for chart creation, dashboard creation, and settings. | Zone | App Base | Overview Base | |------|----------|---------------| | US | `https://app.amplitude.com` | `https://app.amplitude.com` | | EU | `https://app.eu.amplitude.com` | `https://eu.amplitude.com` | Used to construct: `/chart/new`, `/dashboard/new`, `/settings/profile`, `/products?source=wizard`. --- ## OAuth Flow **Protocol:** OAuth 2.0 Authorization Code with PKCE. | Component | US | EU | |-----------|----|----| | Auth Host | `https://auth.amplitude.com` | `https://auth.eu.amplitude.com` | | Authorization URL | `/oauth2/auth` | `/oauth2/auth` | | Client ID | `0ac84169-c41c-4222-885b-31469c761cb0` | `110d04a1-8e60-4157-9c43-fcbe4e014a85` | | Local Redirect Port | `13222` | `13222` | **Overridable via env:** `OAUTH_HOST`, `OAUTH_CLIENT_ID`. **Flow:** 1. Wizard starts a local HTTP server on port `13222` 2. Opens the authorization URL in the user's default browser 3. User authenticates on `auth.amplitude.com` 4. Browser redirects back to `http://localhost:13222/callback` with the auth code 5. Wizard exchanges the code for tokens (ID token + refresh token) 6. Tokens are persisted to `~/.ampli.json` for session reuse **Token reuse:** On subsequent runs, the wizard reads `~/.ampli.json` and validates the stored ID token against the Data API before showing the auth screen. --- ## LLM Gateway & Agent The wizard routes all Claude API calls through Amplitude's LLM gateway, which validates OAuth tokens and forwards requests to Claude. **Agent SDK:** `@anthropic-ai/claude-agent-sdk` — creates a persistent agent session with tool permissions, MCP server connections, and hook callbacks. The agent runs inside the wizard process. --- ## MCP Server Amplitude's remote MCP (Model Context Protocol) server provides the agent with Amplitude product tools. | Environment | Base URL | |-------------|----------| | Production | `https://mcp.amplitude.com` | | Local dev | `http://localhost:8787` | **Transport variants:** - SSE: `/sse` - Streamable HTTP: `/mcp` **Auth:** `Authorization: Bearer ` (Amplitude project API key). **Feature filtering:** Optional query parameter `?features=dashboards,insights,experiments,...` limits which tool categories are exposed. All features are included by default when the param is omitted. **Health check:** `GET https://mcp.amplitude.com/` (5000ms timeout). ### In-Process MCP Server (wizard-tools) The wizard also runs a local MCP server in-process (`src/lib/wizard-tools.ts`) providing 8 tools to the agent: | Tool | Purpose | |------|---------| | `check_env_keys` | Check which env vars are set in the project | | `set_env_values` | Write env vars to `.env.local` | | `detect_package_manager` | Detect npm/yarn/pnpm/bun/pip/etc. | | `load_skill_menu` | Fetch the skill menu for the detected framework | | `install_skill` | Download and install a skill from the remote registry | | `confirm` | Prompt the user for yes/no confirmation | | `choose` | Prompt the user to select from options | | `confirm_event_plan` | Present the event tracking plan for user approval before writing `track()` calls | --- ## Health Checks & Status Pages The wizard monitors 7+ external services via Statuspage.io v2 API and direct endpoint pings. Results are displayed in the `OutageOverlay` when degradation is detected. ### Statuspage.io v2 API Checks All use `GET` with no auth. Response shape: `{ status: { indicator: "none" | "minor" | "major" | "critical" } }`. | Service | Status URL | Components URL | |---------|-----------|----------------| | Claude/Anthropic | `https://status.claude.com/api/v2/status.json` | — | | Amplitude | `https://www.amplitudestatus.com/api/v2/status.json` | `https://www.amplitudestatus.com/api/v2/summary.json` | | GitHub | `https://www.githubstatus.com/api/v2/status.json` | — | | npm | `https://status.npmjs.org/api/v2/status.json` | `https://status.npmjs.org/api/v2/summary.json` | | Cloudflare | `https://www.cloudflarestatus.com/api/v2/status.json` | `https://www.cloudflarestatus.com/api/v2/summary.json` | **Indicator mapping:** - `none` = Operational - `minor` = Degraded - `major` / `critical` = Down ### Direct Endpoint Health Checks Both use a 5000ms timeout (`src/lib/health-checks/endpoints.ts`): | Service | URL | Method | |---------|-----|--------| | LLM Gateway | Configured via `ANTHROPIC_BASE_URL` | GET | | MCP Server | `https://mcp.amplitude.com/` | GET | --- ## Telemetry The wizard reports its own usage analytics to the main `amplitude/Amplitude` project — the same project the rest of the Amplitude app writes to. | Setting | Value | |---------|-------| | SDK | `@amplitude/analytics-node` | | Server URL | `https://api2.amplitude.com/2/httpapi` (configurable via `AMPLITUDE_SERVER_URL`) | | Dev API Key | `ce58b28cace35f7df0eb241b0cd72044` (auto-selected when `NODE_ENV=development` or `test`) | | Prod API Key | `e5a2c9bdffe949f7da77e6b481e118fa` (default) | | Override | Set `AMPLITUDE_API_KEY` to override either default | Both keys mirror Lightning's ampli config (`packages/instrumentation/src/lightning/{agents,wormhole}/src/ampli/index.ts` in `amplitude/javascript`). Local contributor builds invoked via `pnpm try` / `pnpm dev` automatically set `NODE_ENV=development` so they route to the dev project instead of flooding prod. Contributors who `pnpm link --global` and invoke `amplitude-wizard` directly (outside the `pnpm dev` script) need to `export NODE_ENV=development` themselves to hit dev. **Event namespace:** All events prefixed with `wizard cli: ` (e.g., `wizard cli: Session Ended`, `wizard cli: feedback submitted`, `wizard cli: error encountered`). **Property-key convention:** All event-property, user-property, and group-identify keys are lowercase with spaces (`'org id'`, `'duration ms'`, `'error message'`). Keys starting with `$` (`$app_name`, `$error`) are Amplitude-reserved and stay untouched. **Session properties (full):** `integration`, `detected framework`, `typescript`, `project id`, `discovered features`, `additional features`, `run phase`. **Session properties (compact, for high-volume events):** `integration`, `detected framework`, `run phase`, `project id`. **Group analytics:** Every event is automatically associated with the `'org id'` group via `setGroup()` inside `identifyUser()`. Do not re-pass `orgId` per event. **Opt-out:** Controlled by the `FLAG_AGENT_ANALYTICS` feature flag. --- ## Feature Flags The wizard fetches feature flags from Amplitude Experiment at startup (`initFeatureFlags()` in `bin.ts`). Used to control: - Agent analytics opt-out (`FLAG_AGENT_ANALYTICS`) - LLM analytics SDK detection (`FLAG_LLM_ANALYTICS`) - Wizard variant selection (`FLAG_WIZARD_VARIANT`) Flags are refreshed during the session and all active flag values are attached to telemetry events. --- ## Credential Storage ### API Key Storage Three-tier strategy, tried in order (`src/utils/api-key-store.ts`): | Tier | Platform | Mechanism | CLI Tool | |------|----------|-----------|----------| | 1 | macOS | Keychain Services | `security find-generic-password` / `security add-generic-password` | | 2 | Linux | GNOME Keyring / KWallet | `secret-tool lookup` / `secret-tool store` | | 3 | All | `.env.local` in project dir | File I/O (auto-adds to `.gitignore`) | **Scoping:** Keys are scoped by a SHA-1 hash of the install directory (first 12 hex chars), stored under the service name `amplitude-wizard`. ### OAuth Token Storage | File | Contents | |------|----------| | `~/.ampli.json` | OAuth tokens (ID token, refresh token), user info, zone preference | This file is shared with the `ampli` CLI — the wizard intentionally uses the same port (`13222`) and storage location for session interoperability. --- ## File System Touchpoints ### Files Read | Path | Purpose | Source | |------|---------|--------| | `~/.ampli.json` | Cached OAuth tokens + zone preference | `src/utils/ampli-settings.ts` | | `/.env.local` | Fallback API key storage | `src/utils/api-key-store.ts` | | `/package.json` | Framework detection, dependency scanning | Multiple detectors | | `/pyproject.toml` | Python project detection | Framework detectors | | `/requirements.txt` | Python dependency detection | Framework detectors | | `/.vercel/project.json` | Vercel project linking detection | `src/steps/upload-environment-variables/providers/vercel.ts` | | `/.amplitude/events.json` | Event plan generated by agent | Agent workflow | ### Files Written | Path | Purpose | Source | |------|---------|--------| | `~/.ampli.json` | Persist OAuth tokens | `src/utils/ampli-settings.ts` | | `~/.amplitude/wizard/runs//log.txt` | Per-project debug log | `src/lib/observability/logger.ts` | | `~/.amplitude/wizard/runs//log.ndjson` | Structured log mirror | `src/lib/observability/logger.ts` | | `~/.amplitude/wizard/runs//benchmark.json` | Per-project benchmark output | `src/lib/middleware/benchmarks/json-writer.ts` | | `~/.amplitude/wizard/runs//checkpoint.json` | Crash-recovery snapshot | `src/lib/session-checkpoint.ts` | | `~/.amplitude/wizard/plans/.json` | `wizard plan` output | `src/lib/agent-plans.ts` | | `~/.amplitude/wizard/state/.json` | Agent compaction-recovery state | `src/lib/agent-state.ts` | | `~/.amplitude/wizard/update-check.json` | npm registry latest-version cache | `src/utils/update-notifier.ts` | | `/.env.local` | API key (fallback storage) | `src/utils/api-key-store.ts` | | `/.gitignore` | Ensure `.env.local` and `.amplitude/` are ignored | `src/utils/api-key-store.ts`, `src/lib/wizard-tools.ts` | | `/.amplitude/events.json` | Agent-generated event tracking plan (preserved across runs) | `src/lib/wizard-tools.ts` | | `/.amplitude/dashboard.json` | URL of the dashboard the agent created | Agent conclude phase | | `/.amplitude-events.json` | Legacy mirror of `events.json` for bundled-skill compatibility (gitignored, preserved across runs) | `src/lib/wizard-tools.ts` | | `/.amplitude-dashboard.json` | Legacy mirror of `dashboard.json` written by the agent's conclude-phase skill (gitignored, preserved across runs) | Agent conclude phase | | `/amplitude-setup-report.md` | User-facing setup summary the OutroScreen points at (gitignored, overwritten on next run) | Agent conclude phase | ### Editor Config Files Modified (MCP Server Installation) The wizard writes MCP server configuration to enable Amplitude tools in AI-powered editors (`src/steps/add-mcp-server-to-clients/`): | Editor | Config Path | Format | |--------|-------------|--------| | Cursor | `~/.cursor/mcp.json` | JSON with `mcpServers` key | | VS Code | `~/.vscode/mcp.json` | JSON with `mcpServers` key | | Claude Code | `~/.claude/mcp.json` | JSON (or via `claude mcp add` CLI) | | Zed | `~/.zed/mcp.json` | JSON with `mcpServers` key | --- ## CLI Tools Invoked The wizard shells out to these external CLI tools at runtime: ### macOS Keychain (`security`) ```bash # Read security find-generic-password -a "" -s "amplitude-wizard" -w # Write security add-generic-password -U -a "" -s "amplitude-wizard" -w "" # Delete security delete-generic-password -a "" -s "amplitude-wizard" ``` ### Linux Keyring (`secret-tool`) ```bash # Read secret-tool lookup service "amplitude-wizard" account "" # Write printf '%s' "" | secret-tool store --label="Amplitude API Key" service "amplitude-wizard" account "" # Delete secret-tool clear service "amplitude-wizard" account "" ``` ### Claude Code CLI (`claude`) Search order: `~/.local/bin/claude`, `~/.claude/local/claude`, `/usr/local/bin/claude`, `/opt/homebrew/bin/claude`, then `$PATH`. ```bash claude --version # Version check claude mcp list # List configured MCP servers claude mcp add --transport http # Add MCP server claude mcp remove --scope user # Remove MCP server ``` ### Vercel CLI (`vercel`) ```bash vercel --version # Detect CLI presence vercel whoami # Check authentication (run with CI=1) vercel env add # Upload environment variable ``` ### npx ```bash npx -y mcp-remote@latest --header "Authorization: Bearer " # Used as transport proxy for editors that don't support HTTP MCP natively ``` --- ## Environment Variables ### CLI Options (yargs prefix: `AMPLITUDE_WIZARD_`) | Variable | Flag | Description | |----------|------|-------------| | `AMPLITUDE_WIZARD_DEBUG` | `--debug` | Enable debug logging | | `AMPLITUDE_WIZARD_VERBOSE` | `--verbose` | Verbose output | | `AMPLITUDE_WIZARD_DEFAULT` | `--default` | Accept all defaults | | `AMPLITUDE_WIZARD_SIGNUP` | `--signup` | Force sign-up flow | | `AMPLITUDE_WIZARD_LOCAL_MCP` | `--local-mcp` | Use local MCP server | | `AMPLITUDE_WIZARD_CI` | `--ci` | CI mode (non-interactive) | | `AMPLITUDE_WIZARD_API_KEY` | `--api-key` | Pre-set API key | | `AMPLITUDE_WIZARD_PROJECT_ID` | `--project-id` | Pre-set project ID | | `AMPLITUDE_WIZARD_FORCE_INSTALL` | `--force-install` | Force reinstallation | | `AMPLITUDE_WIZARD_INSTALL_DIR` | `--install-dir` | Target directory | | `AMPLITUDE_WIZARD_INTEGRATION` | `--integration` | Force framework | | `AMPLITUDE_WIZARD_MENU` | `--menu` | Show framework menu | | `AMPLITUDE_WIZARD_BENCHMARK` | `--benchmark` | Enable benchmarking | ### Runtime Configuration | Variable | Default | Purpose | |----------|---------|---------| | `NODE_ENV` | — | `test`/`development` routes wizard telemetry to the dev Amplitude project. Does **not** affect any user-facing URLs — both the LLM gateway and the data ingestion host always default to prod (override with `WIZARD_LLM_PROXY_URL` and `AMPLITUDE_WIZARD_INGESTION_HOST` respectively if you actually run a local proxy). | | `OAUTH_HOST` | Zone-specific | Override OAuth host | | `OAUTH_CLIENT_ID` | Zone-specific | Override OAuth client ID | | `AMPLITUDE_API_KEY` | dev: `ce58b28cace35f7df0eb241b0cd72044` / prod: `e5a2c9bdffe949f7da77e6b481e118fa` | Telemetry project API key (auto-selected by `NODE_ENV`) | | `AMPLITUDE_SERVER_URL` | `https://api2.amplitude.com` | Telemetry server URL | | `AMPLITUDE_WIZARD_INGESTION_HOST` | Region-based (`https://api2.amplitude.com` / `https://api.eu.amplitude.com`) | Override the Amplitude data ingestion host the wizard writes into the user's `.env.local` and references in generated SDK init code. Only set this when intentionally proxying ingestion (e.g. local Amplitude proxy). | | `DEMO_MODE_WIZARD` | — | When `1`, limits agent to 5 events for demo runs | | `CI` | — | Non-interactive mode detection; also set to `1` when invoking Vercel CLI | | `AMPLITUDE_WIZARD_MAX_TURNS` | `200` | Override the agent's maximum turn count. Useful for eval fixtures (low cap forces short runs) or quick iteration (`AMPLITUDE_WIZARD_MAX_TURNS=30 pnpm try`). Must be a positive integer ≤ `10000`; empty, non-numeric, zero, negative, or out-of-bounds values silently fall back to the default. | ### Framework-Specific SDK Environment Variables The agent writes these to `.env.local` depending on the detected framework: | Framework | Variable | |-----------|----------| | Next.js | `NEXT_PUBLIC_AMPLITUDE_API_KEY` | | Vite | `VITE_AMPLITUDE_API_KEY` | | Create React App | `REACT_APP_AMPLITUDE_API_KEY` | | Nuxt | `NUXT_PUBLIC_AMPLITUDE_API_KEY` | | SvelteKit / Astro | `PUBLIC_AMPLITUDE_API_KEY` | | Server-side (Node, Python, etc.) | `AMPLITUDE_API_KEY` | --- ## Outbound URLs (Browser) All URLs the wizard opens in the user's browser, defined in `OUTBOUND_URLS` (`src/lib/constants.ts`): | Purpose | URL Pattern | |---------|-------------| | OAuth login | `https://auth[.eu].amplitude.com/oauth2/auth` | | New chart | `https://app[.eu].amplitude.com//chart/new` | | New dashboard | `https://app[.eu].amplitude.com//dashboard/new` | | Slack settings | `https://app[.eu].amplitude.com/analytics/org//settings/profile` | | Products page | `https://app[.eu].amplitude.com/products?source=wizard` | | SDK docs | `https://amplitude.com/docs/sdks` + per-framework variants | | Stripe data source | `https://app.amplitude.com/project/data-warehouse/new-source?kind=Stripe` | | Claude status | `https://status.claude.com` | | Amplitude status | `https://www.amplitudestatus.com` | | Bug reports | `https://github.com/amplitude/wizard/issues` |