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:
- You're debugging a conversion drop in your checkout flow
- You ask Claude: "Show me the funnel from
checkout_startedtopayment_completefor the last 14 days, broken down by device type" - Claude queries PostHog and returns the breakdown inline
- You ask: "Which users in this cohort have session recordings?"
- Claude surfaces the session IDs with direct links to PostHog's replay viewer
- 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:
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 Type | Purpose | Use in MCP? |
|---|---|---|
| Project API Key | Client-side event ingestion (write-only) | ❌ Never |
| Personal API Key | Authenticated API access (read/write) | ✅ Yes |
| Admin API Key | Full account management | ❌ Avoid |
To create a Personal API key:
- Log in to PostHog
- Navigate to Settings → Personal API Keys (top-right user menu)
- Click Create personal API key
- Set a descriptive label:
claude-code-mcp - 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
- 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)
# 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)
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:
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.jsonin your project root (overrides global)
Basic Configuration (npx approach)
{
"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
{
"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
{
"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:
{
"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)
# 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:
{
"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
#!/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 "$@"
chmod +x ~/scripts/posthog-mcp.sh
{
"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
# 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
| Tool | Description | Example prompt |
|---|---|---|
query_events | Run arbitrary event queries with filters | "Show me all page_view events in the last 7 days" |
run_hogql_query | Execute raw HogQL (SQL) against PostHog | "Write HogQL to find users who triggered checkout but not purchase" |
get_event_definitions | List all tracked event types | "What events are we currently tracking?" |
get_property_definitions | List event and person properties | "What properties does the sign_up event have?" |
Insight and Analytics Tools
| Tool | Description | Example prompt |
|---|---|---|
list_insights | Get saved insights from PostHog | "Show me all saved funnel insights" |
get_insight | Fetch a specific insight by ID | "Get the results for insight #142" |
get_funnel | Query funnel conversion data | "What's the conversion rate from signup to paid?" |
get_retention | Fetch retention analysis | "Show 7-day retention for users who signed up last month" |
Feature Flag Tools
| Tool | Description | Example prompt |
|---|---|---|
list_feature_flags | List all feature flags | "What feature flags are currently active?" |
get_feature_flag | Get a specific flag with targeting rules | "Show me the targeting rules for the new-checkout flag" |
evaluate_feature_flag | Check what value a flag returns for a user | "Is new-dashboard enabled for user@example.com?" |
Session Recording Tools
| Tool | Description | Example prompt |
|---|---|---|
list_session_recordings | List session recordings with filters | "Find sessions from users who experienced an error today" |
get_session_recording | Get details for a specific session | "Get the events timeline for session abc123" |
Person and Cohort Tools
| Tool | Description | Example prompt |
|---|---|---|
search_persons | Find person profiles | "Find all users with the email domain @acme.com" |
get_person | Get a specific person's profile | "Show me all properties for user ID 9876" |
list_cohorts | List 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:
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
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
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:
"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:
"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:
"POSTHOG_PROJECT_ID": "12345"
Find your project ID in PostHog under Settings → Project → Project ID.
Mistake 3: Wrong Host for Self-Hosted PostHog
Wrong:
"POSTHOG_HOST": "https://posthog.yourcompany.com/api"
Correct:
"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:
"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:
// 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-serverand 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:
which npx
# Returns: /usr/local/bin/npx or /opt/homebrew/bin/npx
{
"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.
- Verify the key starts with
phx_ - Test the key directly:
curl -H "Authorization: Bearer phx_xxx" https://app.posthog.com/api/projects/ - If using environment variable interpolation, confirm the variable is actually being resolved
- 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.
- Go to PostHog → Settings → Personal API Keys → your key
- Check which scopes are enabled
- Add
query:read,feature_flag:read,session_recording:readas 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:
- Open Claude Code's developer console (check Anthropic documentation for your version)
- Look for MCP-related log messages at startup
- Confirm the server name in config (
posthog) doesn't conflict with other server names - Try renaming the server to
posthog-analyticsand restarting
Enabling Debug Logging
{
"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:
# 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
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"]
# 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:
# .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"
# .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:
# .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:
| Scenario | Use MCP? | Better alternative |
|---|---|---|
| Ad-hoc exploratory queries during development | ✅ Yes | — |
| Real-time monitoring dashboard | ❌ No | PostHog dashboards with auto-refresh |
| Automated alerting on metric thresholds | ❌ No | PostHog subscriptions or webhook integrations |
| Bulk data export for data warehouse | ❌ No | PostHog data pipelines / export API |
| Event ingestion / tracking | ❌ No | PostHog SDK or API directly |
| Sharing analytics with non-technical stakeholders | ❌ No | PostHog shared dashboards |
| High-frequency automated queries (>100/min) | ❌ No | PostHog 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_HOSTtoapp.posthog.com(US),eu.posthog.com(EU), or your self-hosted domain - Always specify
POSTHOG_PROJECT_IDfor multi-project accounts - Restart Claude Code after any config change — MCP config loads at startup
- Use
run_hogql_queryfor 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
Related Resources
- PostHog Query API documentation — official API reference for all endpoints the MCP server uses
- PostHog HogQL reference — SQL dialect reference for writing custom analytical queries
- PostHog Personal API Keys — official authentication documentation
- MCPForge Verified Directory — browse community-reviewed MCP server implementations including PostHog integrations
- Running MCP in Production — deployment patterns, monitoring, and reliability guidance for production MCP setups
- MCPForge Verify — validate your MCP server configuration before deployment