Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion context/commandments.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ commandments:
- "capture_exception takes POSITIONAL args: PostHog.capture_exception(exception, distinct_id, additional_properties) — do NOT use keyword args"
- "Define posthog_distinct_id on the User model for automatic user association in error reports — posthog-rails auto-detects by trying: posthog_distinct_id, distinct_id, id, pk, uuid (in order)"
- "For ActiveJob user association, use the class-level DSL `posthog_distinct_id ->(user) { user.email }` or pass user_id: in a hash argument"
- Store API key in Rails credentials or environment variables, never hardcode
- Store the project token in Rails credentials or environment variables, never hardcode
- "For frontend tracking alongside posthog-rails, add the posthog-js snippet to the layout template — posthog-js handles pageviews, session replay, and client-side errors while posthog-ruby handles backend events, server errors, feature flags, and background jobs"

hogql:
Expand Down
4 changes: 2 additions & 2 deletions context/skills/creating-product-tours/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Product tours use PostHog feature flags for targeting (who sees the tour and when) and PostHog events for tracking (completion, drop-off, step funnel). UI components should be custom-built but reusable across multiple tours.

**Local-dev behavior**: the tour renders locally even when PostHog isn't initialized (no API key, provider not mounted, ad blocker active). The feature flag infrastructure is still scaffolded for production rollout — it just isn't a hard gate in dev. This lets engineers iterate on the tour without needing a PostHog project wired up. See "Local development" below for how the fail-open works and how to opt out.
**Local-dev behavior**: the tour renders locally even when PostHog isn't initialized (no project token, provider not mounted, ad blocker active). The feature flag infrastructure is still scaffolded for production rollout — it just isn't a hard gate in dev. This lets engineers iterate on the tour without needing a PostHog project wired up. See "Local development" below for how the fail-open works and how to opt out.

## Step 1: gather requirements

Expand Down Expand Up @@ -73,7 +73,7 @@ interface UseTourOptions {
storageKey?: string; // localStorage key to remember completion; defaults to `tour-${flagKey}`
// When true, the flag check is enforced even if PostHog isn't initialized
// (the tour won't render locally without PostHog wired up). Default false:
// fail-open in dev so engineers can iterate without an API key.
// fail-open in dev so engineers can iterate without a project token.
requireFlag?: boolean;
}

Expand Down
18 changes: 9 additions & 9 deletions context/skills/mcp-analytics/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Create the PostHog client **once at module scope** (never per request), reading
```ts
import { PostHog } from "posthog-node"

const posthog = new PostHog(process.env.POSTHOG_PROJECT_API_KEY, {
const posthog = new PostHog(process.env.POSTHOG_PROJECT_TOKEN, {
host: process.env.POSTHOG_HOST, // https://us.i.posthog.com or https://eu.i.posthog.com
})
```
Expand Down Expand Up @@ -106,7 +106,7 @@ const handler = createMcpHandler((server) => {
```ts
import { PostHogMCP } from "@posthog/mcp"

const posthog = new PostHogMCP(process.env.POSTHOG_PROJECT_API_KEY, {
const posthog = new PostHogMCP(process.env.POSTHOG_PROJECT_TOKEN, {
host: process.env.POSTHOG_HOST,
})

Expand Down Expand Up @@ -136,7 +136,7 @@ import { Module } from "@nestjs/common"
import { McpModule } from "@rekog/mcp-nest"
import { PostHog, instrumentMutator } from "@posthog/mcp"

const posthog = new PostHog(process.env.POSTHOG_PROJECT_API_KEY, {
const posthog = new PostHog(process.env.POSTHOG_PROJECT_TOKEN, {
host: process.env.POSTHOG_HOST,
})

Expand All @@ -161,7 +161,7 @@ import os
from posthog import Posthog

posthog = Posthog(
os.environ["POSTHOG_PROJECT_API_KEY"],
os.environ["POSTHOG_PROJECT_TOKEN"],
host=os.environ["POSTHOG_HOST"], # https://us.i.posthog.com or https://eu.i.posthog.com
)
```
Expand All @@ -184,7 +184,7 @@ analytics = instrument(server, posthog) # wrap right after constructing the ser
import time
from posthog.mcp import PostHogMCP

posthog = PostHogMCP(os.environ["POSTHOG_PROJECT_API_KEY"], host=os.environ["POSTHOG_HOST"])
posthog = PostHogMCP(os.environ["POSTHOG_PROJECT_TOKEN"], host=os.environ["POSTHOG_HOST"])

# on the initialize handshake:
posthog.capture_initialize(client_name=client_name, client_version=client_version, distinct_id=distinct_id)
Expand All @@ -207,10 +207,10 @@ Resolve `distinct_id` / `session_id` from whatever auth/session the dispatcher a

### STEP 5: Wire up credentials

- Check existing env files (`.env`, `.env.local`, etc.) for a PostHog project API key. If a valid `phc_…` key and host are already set, reference those and skip the rest of this step.
- If the key is missing, use the PostHog MCP server's `projects-get` tool to fetch the project's `api_token`. If multiple projects come back, ask the user which to use. If the MCP server isn't connected, ask the user for their project API key directly.
- Check existing env files (`.env`, `.env.local`, etc.) for a PostHog project token. If a valid `phc_…` token and host are already set, reference those and skip the rest of this step.
- If the token is missing, use the PostHog MCP server's `projects-get` tool to fetch the project's `api_token`. If multiple projects come back, ask the user which to use. If the MCP server isn't connected, ask the user for their project token directly.
- Host: `https://us.i.posthog.com` for US Cloud, `https://eu.i.posthog.com` for EU Cloud.
- Write `POSTHOG_PROJECT_API_KEY` and `POSTHOG_HOST` to the appropriate env file and reference them in code (`process.env.*` in JS, `os.environ[...]` in Python) — never hardcode the key.
- Write `POSTHOG_PROJECT_TOKEN` and `POSTHOG_HOST` to the appropriate env file and reference them in code (`process.env.*` in JS, `os.environ[...]` in Python) — never hardcode the token.

### STEP 6: Ensure events get flushed

Expand Down Expand Up @@ -251,7 +251,7 @@ The PostHog client batches events; the user owns the client's lifecycle.

- **One server, one wrapper.** `instrument()` is idempotent; don't call it twice on the same server.
- **Module-scope client.** Construct the `PostHog` / `Posthog` / `PostHogMCP` client once, not per request.
- **Env, never hardcode.** The project API key and host come from environment variables.
- **Env, never hardcode.** The project token and host come from environment variables.
- **Additive only.** Don't change tool behavior or restructure the server — just wrap/capture.
- **Don't break STDIO.** No `console.*` (JS) or `print()` (Python) on STDIO transports; use a `logger` instead.
- **Pin the beta SDK** and tell the user it's pre-1.0. (Python: `posthog.mcp` ships inside `posthog`; pin `posthog>=7.21`.)
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ STEP 6: Upload source maps (frontend/mobile only).

STEP 7: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- Write these values to the appropriate env file using the framework's naming convention.
- Reference these environment variables in code instead of hardcoding them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ STEP 5: Instrument the feature.

STEP 6: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- Write these values to the appropriate env file using the framework's naming convention.
- Reference these environment variables in code instead of hardcoding them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ STEP 5: Identify users.

STEP 6: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- Write these values to the appropriate env file (e.g. `.env.local` for Next.js, `.env` for others) using the framework's naming convention.
- Reference these environment variables in code instead of hardcoding them.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ STEP 5: Link to users.

STEP 6: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- Write these values to the appropriate env file using the framework's naming convention.
- Reference these environment variables in code instead of hardcoding them.
Expand Down
2 changes: 1 addition & 1 deletion context/skills/omnibus/instrument-logs/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ STEP 6: Add structured properties.

STEP 7: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- For the OpenTelemetry endpoint, use `https://us.i.posthog.com/v1` (US) or `https://eu.i.posthog.com/v1` (EU).
- Write these values to the appropriate env file using the framework's naming convention.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ STEP 8: Add error tracking.

STEP 9: Set up environment variables.
- Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step.
- If the PostHog API key is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project API key instead.
- If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead.
- For the PostHog host URL, use `https://us.i.posthog.com` for US Cloud or `https://eu.i.posthog.com` for EU Cloud.
- Write these values to the appropriate env file using the framework's naming convention.
- Reference these environment variables in code instead of hardcoding them.
Expand Down
2 changes: 1 addition & 1 deletion example-apps/expo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ PostHog is configured in `src/config/posthog.ts` using environment variables fro
```typescript
import Constants from 'expo-constants'

const apiKey = Constants.expoConfig?.extra?.posthogProjectToken
const projectToken = Constants.expoConfig?.extra?.posthogProjectToken
```

### Event Tracking
Expand Down
8 changes: 4 additions & 4 deletions example-apps/expo/src/config/posthog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import Constants from 'expo-constants'

// Configuration loaded from app.config.js extras via expo-constants
// Environment variables are read at build time in app.config.js
const apiKey = Constants.expoConfig?.extra?.posthogProjectToken as string | undefined
const projectToken = Constants.expoConfig?.extra?.posthogProjectToken as string | undefined
const host = (Constants.expoConfig?.extra?.posthogHost as string) || 'https://us.i.posthog.com'
const isPostHogConfigured = apiKey && apiKey !== 'phc_your_project_token_here'
const isPostHogConfigured = projectToken && projectToken !== 'phc_your_project_token_here'

if (__DEV__) {
console.log('PostHog config:', {
apiKey: apiKey ? `SET` : 'NOT SET',
projectToken: projectToken ? `SET` : 'NOT SET',
host,
isConfigured: isPostHogConfigured,
})
Expand All @@ -34,7 +34,7 @@ if (!isPostHogConfigured) {
*
* @see https://posthog.com/docs/libraries/react-native
*/
export const posthog = new PostHog(apiKey || 'placeholder_key', {
export const posthog = new PostHog(projectToken || 'placeholder_key', {
// PostHog API host
host,

Expand Down
6 changes: 3 additions & 3 deletions example-apps/javascript-web/src/posthog.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
*/
import posthog from 'posthog-js';

const apiKey = import.meta.env.VITE_POSTHOG_PROJECT_TOKEN;
const projectToken = import.meta.env.VITE_POSTHOG_PROJECT_TOKEN;
const apiHost = import.meta.env.VITE_POSTHOG_HOST || 'https://us.i.posthog.com';

if (!apiKey) {
if (!projectToken) {
console.warn(
'PostHog not configured (VITE_POSTHOG_PROJECT_TOKEN not set).',
'App will work but analytics will not be tracked.',
);
} else {
posthog.init(apiKey, {
posthog.init(projectToken, {
api_host: apiHost,
// Autocapture is ON by default — tracks clicks, form submissions, pageviews
// capture_pageview: true (default) — captures $pageview on init
Expand Down
2 changes: 1 addition & 1 deletion example-apps/php/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# PostHog configuration
POSTHOG_API_KEY=phc_your_api_key_here
POSTHOG_PROJECT_TOKEN=phc_your_project_token_here
POSTHOG_HOST=https://us.i.posthog.com
6 changes: 3 additions & 3 deletions example-apps/php/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ composer install
# Copy environment template
cp .env.example .env

# Edit .env and add your PostHog API key
# POSTHOG_API_KEY=phc_your_api_key_here
# Edit .env and add your PostHog project token
# POSTHOG_PROJECT_TOKEN=phc_your_project_token_here
# POSTHOG_HOST=https://us.i.posthog.com
```

Expand Down Expand Up @@ -84,7 +84,7 @@ basics/php/
### 1. Initialize Once

```php
PostHog::init($apiKey, [
PostHog::init($projectToken, [
'host' => $host,
'error_tracking' => [
'enabled' => true,
Expand Down
8 changes: 4 additions & 4 deletions example-apps/php/todo.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ function initializePostHog(): bool
{
loadEnvFile(__DIR__ . '/.env');

$apiKey = getenv('POSTHOG_API_KEY');
if (!$apiKey || str_starts_with($apiKey, 'phc_your_')) {
echo "WARNING: PostHog not configured (POSTHOG_API_KEY not set)\n";
$projectToken = getenv('POSTHOG_PROJECT_TOKEN');
if (!$projectToken || str_starts_with($projectToken, 'phc_your_')) {
echo "WARNING: PostHog not configured (POSTHOG_PROJECT_TOKEN not set)\n";
echo " App will work but analytics won't be tracked\n";
return false;
}

PostHog::init($apiKey, [
PostHog::init($projectToken, [
'host' => getenv('POSTHOG_HOST') ?: 'https://us.i.posthog.com',
'error_tracking' => [
'enabled' => true,
Expand Down
6 changes: 3 additions & 3 deletions example-apps/react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,10 @@ The PostHog client is configured with V4 SDK options. If no project token is pro
import PostHog from 'posthog-react-native'
import Config from 'react-native-config'

const apiKey = Config.POSTHOG_PROJECT_TOKEN
const isPostHogConfigured = apiKey && apiKey !== 'phc_your_project_token_here'
const projectToken = Config.POSTHOG_PROJECT_TOKEN
const isPostHogConfigured = projectToken && projectToken !== 'phc_your_project_token_here'

export const posthog = new PostHog(apiKey || 'placeholder_key', {
export const posthog = new PostHog(projectToken || 'placeholder_key', {
host: Config.POSTHOG_HOST || 'https://us.i.posthog.com',
disabled: !isPostHogConfigured, // Disable if no project token
captureAppLifecycleEvents: true,
Expand Down
6 changes: 3 additions & 3 deletions example-apps/react-native/src/config/posthog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import Config from 'react-native-config'

// Environment variables are embedded at build time via react-native-config
// Ensure .env file exists with POSTHOG_PROJECT_TOKEN and POSTHOG_HOST
const apiKey = Config.POSTHOG_PROJECT_TOKEN
const projectToken = Config.POSTHOG_PROJECT_TOKEN
const host = Config.POSTHOG_HOST || 'https://us.i.posthog.com'
const isPostHogConfigured = apiKey && apiKey !== 'phc_your_project_token_here'
const isPostHogConfigured = projectToken && projectToken !== 'phc_your_project_token_here'

if (!isPostHogConfigured) {
console.warn(
Expand All @@ -23,7 +23,7 @@ if (!isPostHogConfigured) {
*
* @see https://posthog.com/docs/libraries/react-native
*/
export const posthog = new PostHog(apiKey || 'placeholder_key', {
export const posthog = new PostHog(projectToken || 'placeholder_key', {
// PostHog API host (usually 'https://us.i.posthog.com' or 'https://eu.i.posthog.com')
host,

Expand Down
Loading