← All articles

PostHog MCP with Claude Code: Complete Setup Guide

July 5, 2026·22 min read·MCPForge

PostHog MCP with Claude Code: Complete Setup Guide

The PostHog MCP server lets Claude Code query your product analytics directly — ask natural language questions about user events, inspect feature flag states, analyze funnel performance, or investigate session replays without leaving your editor. This guide covers everything from initial installation to production-grade deployment.

Quick answer: Connect PostHog to Claude Code by installing the PostHog MCP server (npx @posthog/mcp-server), adding your PostHog Personal API key as an environment variable, and registering the server in Claude Code's MCP configuration. Claude can then query events, feature flags, funnels, and session recordings using natural language.


What Is PostHog?

PostHog is an open-source product analytics platform that combines event tracking, session recording, feature flags, A/B testing, and error monitoring in a single self-hostable tool. Unlike SaaS-only analytics platforms, PostHog can run on your own infrastructure, giving you full data ownership.

Key capabilities relevant to this integration:

  • Event analytics — capture and query any user action with custom properties
  • Funnels and retention — understand conversion paths and user drop-off
  • Feature flags — control feature rollouts with targeting rules and gradual rollouts
  • Session replay — record and replay user sessions with linked event timelines
  • HogQL — PostHog's SQL dialect for writing arbitrary analytical queries
  • REST API and Query API — programmatic access to all of the above

The Query API is what the MCP server uses under the hood. Every Claude tool call translates to one or more authenticated PostHog API requests.


Why Use PostHog with Claude Code?

The traditional analytics workflow looks like this: write code → deploy → open PostHog dashboard in a browser tab → manually filter events → switch back to editor → repeat. Context-switching kills momentum.

Want to analyze your API security?

Import your OpenAPI spec and generate a Security Report automatically.

With the PostHog MCP integration, the workflow becomes:

  1. You're debugging a conversion drop in your checkout flow
  2. You ask Claude: "Show me the funnel from checkout_started to payment_complete for the last 14 days, broken down by device type"
  3. Claude queries PostHog and returns the breakdown inline
  4. You ask: "Which users in this cohort have session recordings?"
  5. Claude surfaces the session IDs with direct links to PostHog's replay viewer
  6. You fix the bug — without ever leaving your editor

This isn't just about convenience. It changes how you use analytics during development:

  • Validate assumptions before shipping — query real event data while writing the feature
  • Debug with context — ask PostHog questions at the exact moment you're reading relevant code
  • Feature flag verification — confirm flag targeting rules match your implementation logic
  • Incident investigation — run event queries during an on-call incident without switching tools

How MCP Enables the Integration

MCP (Model Context Protocol) is an open standard developed by Anthropic that defines how AI models connect to external data sources and tools. It uses a client-server architecture over JSON-RPC 2.0.

┌─────────────────────────────────────────────────────────────┐
│                     Claude Code (MCP Client)                │
│                                                             │
│  User prompt ──► Tool selection ──► Tool call (JSON-RPC)    │
│                                           │                 │
└───────────────────────────────────────────┼─────────────────┘
                                            │ stdio
                                            ▼
┌─────────────────────────────────────────────────────────────┐
│               PostHog MCP Server (Node.js process)          │
│                                                             │
│  Tool handler ──► PostHog API client ──► HTTP request       │
│                                               │             │
└───────────────────────────────────────────────┼─────────────┘
                                                │ HTTPS
                                                ▼
┌─────────────────────────────────────────────────────────────┐
│                PostHog Cloud or Self-hosted                  │
│                                                             │
│  Query API ── Events API ── Feature Flags API ── HogQL      │
└─────────────────────────────────────────────────────────────┘

The MCP server runs as a local subprocess (stdio transport). Claude Code spawns it, communicates via stdin/stdout using JSON-RPC messages, and the server translates those into authenticated PostHog API calls.

This architecture means:

  • No additional web server required — the MCP server runs as a local process
  • No port exposure — communication is purely over stdio
  • Stateless per tool call — each tool invocation is independent
  • API key authentication — the server holds your PostHog credentials, Claude never sees them directly

Prerequisites

Before starting:

  • Claude Code installed and working (Anthropic's CLI-based coding assistant)
  • Node.js 18+ (the PostHog MCP server is a Node.js package)
  • A PostHog account — cloud at app.posthog.com or self-hosted
  • A PostHog Personal API key with appropriate scopes (see Authentication section)
  • Basic familiarity with MCP configuration files

Verify your Node.js version:

bash
node --version
# Should return v18.0.0 or higher

Step 1: Create a PostHog Personal API Key

This is the most important step for security. PostHog has multiple key types — use the right one.

Key types in PostHog:

Key TypePurposeUse in MCP?
Project API KeyClient-side event ingestion (write-only)❌ Never
Personal API KeyAuthenticated API access (read/write)✅ Yes
Admin API KeyFull account management❌ Avoid

To create a Personal API key:

  1. Log in to PostHog
  2. Navigate to Settings → Personal API Keys (top-right user menu)
  3. Click Create personal API key
  4. Set a descriptive label: claude-code-mcp
  5. Select the scopes your workflow needs:

Minimum required scopes for read-only analytics:

- query:read           # Run HogQL and insight queries
- event_definition:read # Read event definitions
- feature_flag:read    # Read feature flag configurations  
- session_recording:read # Access session recording metadata
- insight:read         # Read saved insights
- person:read          # Read person profiles and properties
- cohort:read          # Read cohort definitions
  1. Copy the generated key immediately — it won't be shown again

Security note: If your workflow needs to create annotations, toggle feature flags, or write data, add write scopes selectively. Audit your scopes quarterly and rotate keys every 90 days.


Step 2: Install the PostHog MCP Server

The PostHog MCP server is published as an npm package. You have two installation options:

Option A: npx (no global install, always latest)

bash
# Test that it runs
npx @posthog/mcp-server --help

This approach runs the latest version without a permanent installation. Recommended for most setups.

Option B: Global install (faster startup, pinned version)

bash
npm install -g @posthog/mcp-server

# Verify
posthog-mcp --help

Global install gives you faster startup time since there's no npx resolution step on each launch. For production or team environments where you want version consistency, prefer pinning a specific version:

bash
npm install -g @posthog/mcp-server@1.2.0  # Pin to specific version

Note: If you're running a self-hosted PostHog instance, check whether the official package supports custom host configuration. Some community MCP servers for PostHog offer more configurability — verify any third-party server at mcpforge.dev/verify before using it in production.


Step 3: Configure Claude Code

Claude Code uses a JSON configuration file to register MCP servers. The location depends on your OS:

  • macOS/Linux: ~/.claude/mcp_servers.json
  • Windows: %APPDATA%\Claude\mcp_servers.json
  • Project-local: .claude/mcp_servers.json in your project root (overrides global)

Basic Configuration (npx approach)

json
{
  "mcpServers": {
    "posthog": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "phx_your_personal_api_key_here",
        "POSTHOG_HOST": "https://app.posthog.com"
      }
    }
  }
}

Configuration for Self-Hosted PostHog

json
{
  "mcpServers": {
    "posthog": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "phx_your_personal_api_key_here",
        "POSTHOG_HOST": "https://posthog.yourcompany.com",
        "POSTHOG_PROJECT_ID": "12345"
      }
    }
  }
}

Configuration with Global Install

json
{
  "mcpServers": {
    "posthog": {
      "command": "posthog-mcp",
      "args": [],
      "env": {
        "POSTHOG_API_KEY": "phx_your_personal_api_key_here",
        "POSTHOG_HOST": "https://app.posthog.com"
      }
    }
  }
}

Multi-Project Configuration

If you work across multiple PostHog projects, register a separate server per project:

json
{
  "mcpServers": {
    "posthog-production": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "phx_production_key_here",
        "POSTHOG_HOST": "https://app.posthog.com",
        "POSTHOG_PROJECT_ID": "11111"
      }
    },
    "posthog-staging": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "phx_staging_key_here",
        "POSTHOG_HOST": "https://app.posthog.com",
        "POSTHOG_PROJECT_ID": "22222"
      }
    }
  }
}

When using multiple servers, Claude will prefix tool names with the server name to avoid collisions: posthog-production__query_events vs posthog-staging__query_events.


Step 4: Environment Variable Security

Never hardcode your PostHog API key directly in the config file if that file is committed to version control.

Using a .env file with direnv (macOS/Linux)

bash
# Install direnv
brew install direnv

# Create .env in your home directory or project root
echo 'export POSTHOG_API_KEY=phx_your_key_here' >> ~/.envrc
direnv allow

Then reference it in your config:

json
{
  "mcpServers": {
    "posthog": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "${POSTHOG_API_KEY}",
        "POSTHOG_HOST": "https://app.posthog.com"
      }
    }
  }
}

Note: Environment variable interpolation support varies by Claude Code version. If ${VAR} isn't resolved, use a shell wrapper script instead (see below).

Using a shell wrapper script

bash
#!/bin/bash
# ~/scripts/posthog-mcp.sh

export POSTHOG_API_KEY=$(cat ~/.secrets/posthog_api_key)
export POSTHOG_HOST="https://app.posthog.com"

exec npx -y @posthog/mcp-server "$@"
bash
chmod +x ~/scripts/posthog-mcp.sh
json
{
  "mcpServers": {
    "posthog": {
      "command": "/Users/yourname/scripts/posthog-mcp.sh",
      "args": []
    }
  }
}

This approach keeps credentials completely out of your config file.


Step 5: Verify the Configuration

Before relying on the integration in your workflow, verify it works correctly.

Test the server directly

bash
# Start the server in test mode
POSTHOG_API_KEY=phx_your_key POSTHOG_HOST=https://app.posthog.com npx @posthog/mcp-server

# If no errors appear, the server starts successfully
# Press Ctrl+C to stop

Test with Claude Code

Start Claude Code and ask:

List the available PostHog tools

Claude should respond with a list of available tools from the PostHog MCP server. If it responds that no PostHog tools are available, check the troubleshooting section.

Verify with MCPForge

For a more thorough compatibility check — especially if you're deploying in a team or CI environment — use MCPForge Verify. MCPForge Verify:

  • Validates your server manifest and tool schemas
  • Checks MCP protocol version compatibility
  • Identifies missing or malformed configuration fields
  • Verifies transport configuration (stdio vs SSE)
  • Surfaces authentication misconfigurations before they cause runtime failures

This is particularly useful when using a community or custom PostHog MCP implementation, since the schema and tool names may differ from the official package. You can also browse the MCPForge Verified Directory to find community-reviewed PostHog MCP server implementations.


Available PostHog MCP Tools

The exact tool set depends on the PostHog MCP server version, but the standard implementation exposes these categories:

Event Query Tools

ToolDescriptionExample prompt
query_eventsRun arbitrary event queries with filters"Show me all page_view events in the last 7 days"
run_hogql_queryExecute raw HogQL (SQL) against PostHog"Write HogQL to find users who triggered checkout but not purchase"
get_event_definitionsList all tracked event types"What events are we currently tracking?"
get_property_definitionsList event and person properties"What properties does the sign_up event have?"

Insight and Analytics Tools

ToolDescriptionExample prompt
list_insightsGet saved insights from PostHog"Show me all saved funnel insights"
get_insightFetch a specific insight by ID"Get the results for insight #142"
get_funnelQuery funnel conversion data"What's the conversion rate from signup to paid?"
get_retentionFetch retention analysis"Show 7-day retention for users who signed up last month"

Feature Flag Tools

ToolDescriptionExample prompt
list_feature_flagsList all feature flags"What feature flags are currently active?"
get_feature_flagGet a specific flag with targeting rules"Show me the targeting rules for the new-checkout flag"
evaluate_feature_flagCheck what value a flag returns for a user"Is new-dashboard enabled for user@example.com?"

Session Recording Tools

ToolDescriptionExample prompt
list_session_recordingsList session recordings with filters"Find sessions from users who experienced an error today"
get_session_recordingGet details for a specific session"Get the events timeline for session abc123"

Person and Cohort Tools

ToolDescriptionExample prompt
search_personsFind person profiles"Find all users with the email domain @acme.com"
get_personGet a specific person's profile"Show me all properties for user ID 9876"
list_cohortsList defined cohorts"What cohorts do we have?"

Practical Developer Workflows

Workflow 1: Debugging a Conversion Drop

You've noticed a drop in your signup conversion rate. Instead of switching to the PostHog dashboard:

You: Query the funnel from `landing_page_view` → `signup_started` → `signup_completed` 
for the last 30 days. Show conversion rates at each step.

Claude: [Queries PostHog funnel API]
Here's the funnel analysis for the last 30 days:

- landing_page_view → signup_started: 12.4% conversion (↓ from 18.1% two weeks ago)
- signup_started → signup_completed: 71.2% conversion (stable)

The drop is at the top of the funnel. Want me to break this down by traffic source 
or device type to narrow it down?

You: Break it down by referrer source.

Claude: [Runs additional HogQL query]
...

Workflow 2: Feature Flag Validation During Development

You're implementing a feature gated behind a PostHog flag and want to confirm the targeting logic:

You: Show me the full configuration of the `new-billing-flow` feature flag, 
including all rollout conditions.

Claude: [Queries feature flags API]
Flag: new-billing-flow
Status: Active
Rollout: 25% of users
Targeting rules:
  - Group 1: users where plan = 'enterprise' → 100%
  - Group 2: users where email ends in '@posthog.com' → 100%  
  - Group 3: random 25% of remaining users

Note: The flag uses person properties at evaluation time. If a user's plan 
changes after their first evaluation, they may get inconsistent results 
depending on whether you're using local or remote evaluation.

You: Is user@acme.com in the test group?

Claude: [Evaluates flag for specific user]
...

Workflow 3: Incident Investigation

You receive an alert that error rates spiked at 14:32 UTC:

You: Show me all `error` events between 14:30 and 15:00 UTC today, 
grouped by error_type property. Filter to our production environment.

Claude: [HogQL query against events]
Top error types in that window:
  - TypeError: Cannot read property 'id' of undefined — 847 occurrences
  - NetworkError: Failed to fetch /api/checkout — 203 occurrences
  - ChunkLoadError: Loading chunk 47 failed — 89 occurrences

The TypeError is new — I don't see it in events before 14:32. 
Want me to find session recordings of affected users?

You: Yes, find sessions where this TypeError occurred.

Claude: [Queries session recordings with event filter]
...

Workflow 4: Analytics-Driven Code Review

Before removing a legacy code path, verify it's actually unused:

You: Query events for `legacy_import_used` in the last 90 days. 
How many unique users triggered it?

Claude: [Queries PostHog]
127 unique users triggered `legacy_import_used` in the last 90 days, 
with the most recent occurrence 3 days ago. This feature is still actively used.

Top user segments by frequency:
- Enterprise plan: 89 users (70%)
- API access enabled: 67 users (53%)

You: Show me which users triggered it most recently.

Claude: [Person query]
...

HogQL Query Examples

The run_hogql_query tool is the most powerful — it gives Claude full SQL access to your PostHog data. Here are prompts that produce useful HogQL queries:

Active Users by Day

You: Write a HogQL query for daily active users over the last 30 days

PostHog receives:

sql
SELECT 
  toDate(timestamp) as date,
  count(distinct person_id) as dau
FROM events
WHERE 
  timestamp >= now() - interval 30 day
  AND event NOT IN ('$pageleave', '$feature_flag_called')
GROUP BY date
ORDER BY date ASC

Funnel Drop-off Analysis

You: HogQL query to find users who completed `add_to_cart` but never 
completed `purchase` in the same session
sql
SELECT 
  person_id,
  min(timestamp) as first_add_to_cart,
  countIf(event = 'purchase') as purchase_count
FROM events
WHERE 
  event IN ('add_to_cart', 'purchase')
  AND timestamp >= now() - interval 7 day
GROUP BY person_id
HAVING purchase_count = 0
ORDER BY first_add_to_cart DESC
LIMIT 100

Feature Flag Impact Analysis

You: Compare conversion rates for users in the `new-checkout` experiment 
vs the control group over the last 14 days
sql
SELECT
  properties.$feature/new-checkout as variant,
  count(distinct person_id) as users,
  countIf(event = 'purchase') as purchases,
  round(countIf(event = 'purchase') / count(distinct person_id) * 100, 2) as conversion_pct
FROM events
WHERE 
  event IN ('checkout_started', 'purchase')
  AND timestamp >= now() - interval 14 day
  AND properties.$feature/new-checkout IS NOT NULL
GROUP BY variant

Common Configuration Mistakes

Mistake 1: Using the Project API Key Instead of Personal API Key

Wrong:

json
"POSTHOG_API_KEY": "phc_xxxxxxxxxxxx"

Project API keys start with phc_ and are write-only — they're for ingesting events via posthog.capture(). They cannot authenticate the Query API.

Correct:

json
"POSTHOG_API_KEY": "phx_xxxxxxxxxxxx"

Personal API keys start with phx_.

Mistake 2: Missing Project ID for Multi-Project Accounts

If your PostHog account has multiple projects, the API may default to the wrong project or return a 404. Always specify POSTHOG_PROJECT_ID explicitly:

json
"POSTHOG_PROJECT_ID": "12345"

Find your project ID in PostHog under Settings → Project → Project ID.

Mistake 3: Wrong Host for Self-Hosted PostHog

Wrong:

json
"POSTHOG_HOST": "https://posthog.yourcompany.com/api"

Correct:

json
"POSTHOG_HOST": "https://posthog.yourcompany.com"

Don't append /api — the MCP server constructs API paths internally.

Mistake 4: EU Cloud Users Using the Wrong Endpoint

PostHog operates separate US and EU cloud instances. EU cloud users must use:

json
"POSTHOG_HOST": "https://eu.posthog.com"

Not app.posthog.com. Using the wrong endpoint returns 401 or 404 errors even with a valid API key.

Mistake 5: Config File Not Reloaded After Changes

Claude Code reads the MCP config at startup. After modifying mcp_servers.json, you must restart Claude Code. Changes don't hot-reload.

Mistake 6: Incorrect JSON Syntax

Trailing commas in JSON are invalid and will silently prevent the config from loading:

json
// Wrong — trailing comma
{
  "mcpServers": {
    "posthog": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],  // ← trailing comma
    }
  }
}

Use a JSON validator or run python3 -m json.tool ~/.claude/mcp_servers.json to validate before restarting.


Troubleshooting

Diagnostic Checklist

Work through these in order:

  • Is Node.js 18+ installed? Run node --version
  • Does the MCP server start manually? Run POSTHOG_API_KEY=phx_xxx npx @posthog/mcp-server and check for errors
  • Is the API key a Personal API key? Key should start with phx_
  • Is the correct PostHog host set? US: app.posthog.com, EU: eu.posthog.com, self-hosted: your domain
  • Is the project ID correct? Check Settings → Project in PostHog
  • Is the config file valid JSON? Run python3 -m json.tool ~/.claude/mcp_servers.json
  • Has Claude Code been restarted? MCP config is loaded at startup
  • Do the API key scopes include query:read? Check PostHog → Settings → Personal API Keys
  • Is the PostHog API accessible from your machine? Run curl -H "Authorization: Bearer phx_xxx" https://app.posthog.com/api/projects/

Error: "spawn npx ENOENT"

Claude Code can't find npx. This happens when Claude Code doesn't inherit your shell's PATH.

Fix: Use the absolute path to npx:

bash
which npx
# Returns: /usr/local/bin/npx or /opt/homebrew/bin/npx
json
{
  "command": "/usr/local/bin/npx",
  "args": ["-y", "@posthog/mcp-server"]
}

Error: "401 Unauthorized" from PostHog API

Your API key is invalid or not being passed correctly.

  1. Verify the key starts with phx_
  2. Test the key directly: curl -H "Authorization: Bearer phx_xxx" https://app.posthog.com/api/projects/
  3. If using environment variable interpolation, confirm the variable is actually being resolved
  4. Check that the key hasn't been revoked in PostHog Settings

Error: "403 Forbidden"

The API key is valid but lacks permission for the operation.

  1. Go to PostHog → Settings → Personal API Keys → your key
  2. Check which scopes are enabled
  3. Add query:read, feature_flag:read, session_recording:read as needed

Error: "429 Too Many Requests"

You've hit PostHog's API rate limits. This typically happens when Claude runs many consecutive queries.

Immediate fix: Wait 60 seconds before retrying.

Long-term fix: If this happens regularly, check your PostHog plan's API limits and consider adding delays between queries in complex workflows. PostHog's rate limits are typically per-second and per-minute, so burst queries from Claude's multi-step reasoning can trigger them.

MCP Tools Not Appearing in Claude

If Claude doesn't see any PostHog tools:

  1. Open Claude Code's developer console (check Anthropic documentation for your version)
  2. Look for MCP-related log messages at startup
  3. Confirm the server name in config (posthog) doesn't conflict with other server names
  4. Try renaming the server to posthog-analytics and restarting

Enabling Debug Logging

json
{
  "mcpServers": {
    "posthog": {
      "command": "npx",
      "args": ["-y", "@posthog/mcp-server"],
      "env": {
        "POSTHOG_API_KEY": "phx_your_key",
        "POSTHOG_HOST": "https://app.posthog.com",
        "DEBUG": "mcp:*,posthog:*",
        "NODE_ENV": "development"
      }
    }
  }
}

Debug output will appear in Claude Code's MCP log stream.


Security Considerations

API Key Scope Minimization

Apply the principle of least privilege. If your workflow only needs to read event data, don't grant feature flag write access. If you're doing analytics queries only, don't add person:write.

Review and audit scopes at least quarterly:

bash
# Quick audit: what can this key access?
curl -H "Authorization: Bearer phx_xxx" \
  https://app.posthog.com/api/projects/ \
  | jq '.results[].name'

Key Rotation

Rotate Personal API keys every 90 days or immediately if:

  • A team member with access to the key leaves
  • The key appears in logs, error messages, or version control
  • You suspect any exposure

PostHog lets you create the new key before deleting the old one, so you can rotate without downtime.

Project-Level Isolation

Don't use a single API key that spans all projects for your Claude Code integration. Create project-specific keys. If a key is compromised, the blast radius is limited to one project's data.

Data Residency

If your PostHog data has GDPR or data residency requirements, be aware that:

  • EU cloud data stays in the EU (eu.posthog.com)
  • Self-hosted data stays wherever you host it
  • Query results returned to Claude are processed by Anthropic's models — review your data sharing obligations before querying personally identifiable information

PII in Event Queries

PostHog events may contain PII (email addresses, user names, IPs). Be deliberate about what you query through Claude:

  • Avoid queries that return raw email addresses or personal data unless necessary
  • Use aggregate queries wherever possible
  • Consider using PostHog's property masking features for sensitive fields

Production Deployment

For team environments or CI/CD contexts where you want the PostHog MCP integration available consistently, consider these patterns.

For deeper guidance on running MCP servers reliably in production, see our guide on running MCP in production.

Containerized MCP Server

If you're running Claude Code in a Docker environment or want a standalone MCP server container:

dockerfile
# Dockerfile
FROM node:20-alpine

WORKDIR /app

# Install the PostHog MCP server
RUN npm install -g @posthog/mcp-server@1.2.0

# Create non-root user
RUN addgroup -g 1001 -S mcp && \
    adduser -S -u 1001 -G mcp mcp

USER mcp

# API key injected at runtime via environment variable
ENV POSTHOG_HOST=https://app.posthog.com

CMD ["posthog-mcp"]
bash
# Build
docker build -t posthog-mcp:latest .

# Run with API key injected at runtime
docker run -e POSTHOG_API_KEY=phx_xxx posthog-mcp:latest

Critical: Never bake the API key into the Docker image. Always inject it at runtime via --env or Kubernetes secrets.

Team Configuration via Dotfiles

For teams that use shared dotfiles, add the PostHog MCP config to your dotfiles repo but keep API keys out of it:

bash
# .zshrc or .bashrc (in dotfiles repo)
export POSTHOG_TEAM_HOST="https://posthog.yourcompany.com"

# ~/.secrets/posthog (NOT in dotfiles repo, in .gitignore)
export POSTHOG_API_KEY="phx_individual_key_per_developer"
bash
# .zshrc
[ -f ~/.secrets/posthog ] && source ~/.secrets/posthog

Each developer generates their own Personal API key, keeping individual access auditable.

CI/CD Integration for Analytics Validation

You can use the PostHog MCP server in CI to validate that expected events are being tracked after deployments:

yaml
# .github/workflows/analytics-validation.yml
jobs:
  validate-analytics:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          
      - name: Validate critical events exist
        env:
          POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
          POSTHOG_HOST: https://app.posthog.com
          POSTHOG_PROJECT_ID: ${{ secrets.POSTHOG_PROJECT_ID }}
        run: |
          # Direct API call to verify events are flowing
          RESULT=$(curl -s \
            -H "Authorization: Bearer $POSTHOG_API_KEY" \
            "$POSTHOG_HOST/api/projects/$POSTHOG_PROJECT_ID/events/?event=page_view&limit=1" \
            | jq '.results | length')
          
          if [ "$RESULT" -eq "0" ]; then
            echo "ERROR: No page_view events found. Analytics may be broken."
            exit 1
          fi
          
          echo "Analytics validation passed."

Best Practices

Use Specific Date Ranges

Vague queries are slow and expensive. Always give Claude a specific time window:

# Vague (expensive)
"Show me all user signups"

# Specific (fast)
"Show me user signups in the last 7 days, grouped by day"

Prefer Aggregated Queries Over Raw Event Dumps

Asking for raw events returns large payloads that are slow to process and may contain PII:

# Avoid
"Show me all events from yesterday"

# Better
"Show me the count of each event type from yesterday, sorted by frequency"

Build a Context-Setting Prompt

At the start of an analytics session, give Claude context about your event taxonomy:

You: I'm going to ask you to analyze PostHog data. Here's our event naming convention:
- `feature_*` events: feature interactions  
- `checkout_*` events: purchase funnel
- `error_*` events: application errors
Our main conversion event is `subscription_started`.
User properties: `plan` (free/pro/enterprise), `company_size`, `country`

This dramatically improves the accuracy of Claude's queries.

Verify Results Against the PostHog UI

For critical business decisions, always cross-reference Claude's query results against the PostHog dashboard. The MCP integration is excellent for exploration but treat significant findings as hypotheses to validate.

Create Saved Insights for Recurring Queries

If you find yourself asking the same PostHog question repeatedly via Claude, create a saved Insight in PostHog. Then you can ask Claude to get_insight by ID rather than reconstructing the query each time — faster and more consistent.


Architecture Decision: When NOT to Use the PostHog MCP Integration

The MCP integration is the right tool for many workflows, but not all:

ScenarioUse MCP?Better alternative
Ad-hoc exploratory queries during development✅ Yes
Real-time monitoring dashboard❌ NoPostHog dashboards with auto-refresh
Automated alerting on metric thresholds❌ NoPostHog subscriptions or webhook integrations
Bulk data export for data warehouse❌ NoPostHog data pipelines / export API
Event ingestion / tracking❌ NoPostHog SDK or API directly
Sharing analytics with non-technical stakeholders❌ NoPostHog shared dashboards
High-frequency automated queries (>100/min)❌ NoPostHog API with caching layer

The MCP integration is optimized for interactive, human-in-the-loop analytical workflows during development. It's not a replacement for PostHog's built-in dashboarding, alerting, or data pipeline features.


Key Takeaways

  • Use a Personal API key (phx_) with minimal scopes — never the Project API key (phc_)
  • Set POSTHOG_HOST to app.posthog.com (US), eu.posthog.com (EU), or your self-hosted domain
  • Always specify POSTHOG_PROJECT_ID for multi-project accounts
  • Restart Claude Code after any config change — MCP config loads at startup
  • Use run_hogql_query for complex analytical questions — it's the most powerful tool
  • Keep API keys out of version control; use environment variables or shell wrapper scripts
  • Validate configuration with MCPForge Verify before production use
  • Cross-reference critical findings in the PostHog UI before acting on them
  • The integration excels at exploratory, development-time analytics — not at replacing PostHog's dashboards or automation features

Frequently Asked Questions

Does the PostHog MCP server work with Claude Desktop as well as Claude Code?

Yes. The PostHog MCP server uses stdio transport, which is compatible with any MCP client that supports the stdio protocol — including Claude Desktop, Claude Code, Cursor, and any custom client. The configuration file location differs per client, but the server binary and arguments are identical.

Which PostHog plan do I need to use the MCP integration?

The PostHog MCP server uses the PostHog Query API and REST API, which are available on all plans including the free tier. However, some advanced queries (like querying large date ranges or using certain HogQL features) may be subject to plan-specific rate limits. Check your PostHog plan's API limits before deploying to production.

Is it safe to give Claude Code access to my PostHog API key?

Use a scoped Personal API key with only the permissions needed — typically read access to Insights, Events, Feature Flags, and Session Recordings. Never use your Project API key (the public write-only key used for ingestion) or your master admin key. Store the key in environment variables, never hardcoded in config files committed to version control.

Can the PostHog MCP server write data to PostHog — for example, create feature flags or send events?

The current official PostHog MCP implementation is primarily read-oriented: it queries analytics data, feature flags, and session recordings. Some implementations expose write operations like creating annotations or toggling feature flags in specific environments. Always review the tool definitions in your server version before granting write permissions.

Why is Claude returning outdated analytics data?

PostHog MCP queries run in real time against the PostHog API, but PostHog itself has ingestion delays — typically a few minutes for event data and up to an hour for computed properties like person profiles. If you're seeing stale data, check your query date range and account for PostHog's ingestion pipeline latency. Cached dashboard results are not used by the MCP server.

How do I limit which PostHog projects Claude Code can access?

PostHog Personal API keys are scoped to specific projects. Create a separate API key per project in PostHog Settings → Personal API Keys, and configure a separate MCP server instance per project if you need multi-project access. Never use a single key with access to all projects in a shared team environment.

Can I run the PostHog MCP server in a Docker container for production use?

Yes. You can containerize the MCP server using the official Node.js or Python base image. The key is ensuring the container has network access to PostHog's API endpoints and that the API key is injected via environment variables at runtime, not baked into the image. See the production deployment section of this guide for a working Dockerfile.

What's the difference between the PostHog MCP server and using the PostHog API directly in Claude?

The MCP server provides Claude with structured, pre-defined tools that map directly to PostHog operations, with proper error handling and authentication management. Calling the PostHog API directly via Claude's code execution requires Claude to manage authentication, construct correct API requests, handle pagination, and parse responses — which is error-prone and inconsistent. The MCP layer provides a reliable, auditable interface.

How do I debug MCP tool calls that are failing silently?

Enable debug logging by setting the DEBUG=mcp:* environment variable when starting the server. Check Claude Code's MCP log output in the developer console. For PostHog-specific errors, the server will surface HTTP status codes and error messages from the PostHog API — 401 means invalid API key, 403 means insufficient permissions, 429 means rate limited. Use the troubleshooting checklist in this guide.

How can I verify my PostHog MCP server configuration before connecting it to Claude Code?

Use MCPForge Verify at mcpforge.dev/verify to validate your server manifest, check tool definitions, and confirm compatibility before connecting to Claude Code. This catches common configuration errors like missing authentication fields, malformed tool schemas, and transport mismatches before they cause runtime failures.

Check your MCP security posture

Generate a Security Score, detect risky tools, and review permissions before exposing APIs to AI agents.

Related Articles

What Is Model Context Protocol (MCP)?

OpenAPI to MCP: Complete Guide

How to Connect Claude to Any API Using MCP

Coming soon

GitHub MCP Server Explained

Coming soon