posthog-toolkit-mcp
Provides tools for interacting with a PostHog instance, including HogQL queries, event and property definitions, session replays, project listing, and general REST API access with read-only by default and optional write support.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@posthog-toolkit-mcpRun a HogQL query for daily active users over the last 7 days"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
posthog-toolkit-mcp
An MCP server for PostHog, on PostHog Cloud or a self-hosted instance: HogQL queries, event and property definitions, session replays and the REST API — with guards that keep an agent from sending the API key elsewhere or writing by accident.
Tools
Tool | What it does |
| Runs a HogQL query. Refuses insight placeholders like |
| Event names seen in the project, with last-seen time; optional substring |
| Event or person property names with their types. |
| Session recordings of a |
| Projects of the organization. Works with personal API keys scoped to specific projects. |
| GET any PostHog REST endpoint; |
| Any method, including writes. Registered only with |
Related MCP server: pg-readonly-mcp
Configuration
Variable | |
| Required. |
| Required. A personal API key ( |
| Default project for the tools and for |
|
|
| Cap on a tool response. Default |
| Request timeout. Default |
The key needs read access to the project (and user read access for posthog_projects; without it the tool falls
back to the organization project list).
Install
{
"mcpServers": {
"posthog": {
"command": "npx",
"args": ["-y", "posthog-toolkit-mcp"],
"env": {
"POSTHOG_HOST": "https://posthog.example.com",
"POSTHOG_API_KEY": "${POSTHOG_API_KEY}",
"POSTHOG_PROJECT_ID": "1"
}
}
}
}In Claude Code this block goes into the project's .mcp.json; keep the key itself out of the file, e.g. in the
env block of .claude/settings.local.json, and pin the version (posthog-toolkit-mcp@0.1.0) so every machine runs
the same server.
Security
Read-only by default; writes need
POSTHOG_ALLOW_WRITE.Requests go only to the
POSTHOG_HOSTorigin: a path like//other-host/...is refused before the API key could leave with it.Project ids are validated as numbers before they reach a URL.
Development
npm install
npm run typecheck # tsc --noEmit
npm run build # esbuild bundles src/index.ts into dist/server.mjs with no runtime dependencies
npm run smoke # stdio checks: configuration errors, tool list, guards that fire before any network call
npm run check # all threeFile | |
| Entry point: builds the server from the environment and connects stdio. |
| Reads and validates environment variables. |
| PostHog API client; refuses paths that would leave |
| Zod input schemas of the tools; handler argument types are inferred from them. |
| Tool registration and result formatting. |
| HogQL literals, insight placeholder detection, the recordings query. |
The bundle is a single file on purpose: npx starts it without installing any dependencies.
License
MIT — see LICENSE. Dependencies bundled into dist/server.mjs keep their own licenses, listed in
THIRD_PARTY_NOTICES.md.
Available Tools
6 toolsposthog_api_getGET a PostHog API endpointARead-only
GET any PostHog REST endpoint for what HogQL does not cover: feature flags, insights, dashboards, experiments, cohorts. {project_id} in the path is replaced with the default project, e.g. /api/projects/{project_id}/feature_flags/
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Endpoint path, e.g. /api/projects/{project_id}/insights/ | |
| params | No | Query-string parameters |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful behavioral context: the {project_id} path placeholder is replaced with the default project, which is a non-obvious behavior. It does not describe response format, but with no output schema and a generic GET tool, the description provides adequate transparency beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. The primary purpose is front-loaded, the scope boundary is stated immediately, and the {project_id} substitution detail is placed at the end where it belongs. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic GET-all-endpoints tool with readOnlyHint=true and openWorldHint=true, the description covers the essential context: what it does, when to use it, and the key path substitution behavior. It does not explain response format or error behavior, but for a passthrough GET tool with no output schema, this is a minor gap. The sibling tools are not explicitly differentiated, but the HogQL contrast helps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (path and params). The description adds the important detail that {project_id} in the path is replaced with the default project, which adds meaning beyond the schema. However, it does not elaborate on the params object structure beyond what the schema provides, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('GET') and resource ('any PostHog REST endpoint'), and explicitly scopes it to what HogQL does not cover, listing concrete examples (feature flags, insights, dashboards, experiments, cohorts). This clearly distinguishes it from sibling tools like posthog_query, which presumably covers HogQL.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when to use this tool ('for what HogQL does not cover') and lists example endpoints. It does not explicitly name sibling alternatives or state when not to use it, but the contrast with HogQL and the sibling list (posthog_query) makes the usage context reasonably clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
posthog_event_definitionsList event namesARead-only
Event names seen in a project, with when each was last seen. Use it instead of guessing event names in HogQL.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size | |
| offset | No | Pagination offset | |
| search | No | Substring to match in the event name | |
| project_id | No | Project id; defaults to POSTHOG_PROJECT_ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish readOnlyHint=true, so no destructive behavior needs disclosure. The description adds the useful behavioral detail that results include event names and their last-seen timestamps, but it does not describe pagination behavior, ordering, or data freshness. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences, front-loaded with the core purpose and followed by a relevant usage note. Every sentence earns its place, and no redundant content is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple, read-only list operation with no required parameters and a fully documented schema. The description supplies the essential return concept (event names plus last-seen) and a usage context. It could be slightly more complete by noting response ordering or pagination defaults, but those are inferable from the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each of the four parameters (limit, offset, search, project_id) carrying a description and default values. The tool description adds no parameter-level meaning beyond what the schema already provides, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (event names in a project) and the specific aspect it covers (when each was last seen), with a clear title 'List event names'. It does not explicitly distinguish itself from sibling tools like posthog_property_definitions, but the resource is specific enough to avoid confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: 'Use it instead of guessing event names in HogQL.' This tells the agent when this tool is appropriate relative to a query alternative, though it does not explicitly mention alternatives or exclusion cases for sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
posthog_projectsList projectsARead-only
Projects of the organization with their ids. Works with API keys scoped to specific projects.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only and open-world behavior. The description adds useful behavioral context beyond the annotations by disclosing compatibility with project-scoped API keys, which affects how an agent should authenticate and interpret the returned project list. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler; the core purpose is front-loaded and the authentication note is the only additional detail. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list operation, the description names the resource, the returned fields, and an important API-key constraint. A more explicit response shape would be helpful given the lack of an output schema, but the open-world annotation and the simple scope keep this from being a major gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is trivially fully described, so the description does not need to document parameter semantics. It still adds context about the returned content (ids), which is more than the empty schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('projects of the organization') and the key output ('their ids'), and the title supplies the verb 'List'. This is specific enough to distinguish it from sibling tools focused on event definitions, properties, queries, and replays.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives relevant context by noting that the tool works with API keys scoped to specific projects, which implies an authentication prerequisite. However, it does not explicitly state when to prefer this tool over alternatives like posthog_api_get or posthog_query, or when it should not be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
posthog_property_definitionsList property namesARead-only
Event or person property names in a project, with their types. Use it instead of guessing property names in HogQL.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Which properties to list | event |
| limit | No | Page size | |
| offset | No | Pagination offset | |
| search | No | Substring to match in the property name | |
| project_id | No | Project id; defaults to POSTHOG_PROJECT_ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety profile. The description adds no further behavioral details such as pagination behavior, response format, or rate limits, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the core content front-loaded. The second sentence justifies why the tool is useful and is not filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a listing tool with no required parameters and no output schema, the description states what will be returned (names and types), and the annotations cover read-only/open-world behavior. It does not mention pagination or search, but those are fully documented in the schema, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are adequately documented in the schema itself. The description only restates the event/person distinction already encoded in the type enum, adding no new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: listing event or person property names in a project with their types. It is clear, but it does not explicitly contrast itself with sibling tools like posthog_event_definitions, so it relies on the resource name rather than naming the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit usage trigger: use this instead of guessing property names in HogQL. However, it does not state when not to use it or mention alternative tools, so the guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
posthog_queryRun a HogQL queryARead-only
Runs a HogQL (ClickHouse SQL dialect) query: tables events, persons, sessions, groups, raw_session_replay_events. Example: SELECT event, count() FROM events WHERE timestamp > now() - INTERVAL 7 DAY GROUP BY event ORDER BY 2 DESC LIMIT 20.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | HogQL query text | |
| project_id | No | Project id; defaults to POSTHOG_PROJECT_ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint already annotated, the description doesn't need to restate the read-only or open-world traits. It adds valuable behavioral context by enumerating accessible tables (events, persons, sessions, groups, raw_session_replay_events) and showing a concrete query pattern, which helps an agent understand what to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long: the first states the core function and data sources, the second provides an illustrative example. It is front-loaded with the action and resource, and every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic query tool, the description provides everything an agent needs: the dialect, the available tables, and a full sample query. Since no output schema is present, return format expectations are appropriately left open, and the annotations handle read-only and open-world behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only describes the query parameter as 'HogQL query text', but the description adds concreteness by listing the exact tables and providing a working example query. This goes beyond the schema's generic description and gives the agent a clearer model for constructing valid inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a HogQL query against a defined set of tables Aleksandrov, and the example makes the exact syntax concrete. It is easily distinguished from siblings like posthog_event_definitions and posthog_property_definitions, which serve narrower metadata retrieval purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: for writing arbitrary HogQL queries over the listed tables. It doesn't explicitly state when not to use it or explicitly name the sibling alternatives, but the table list implies that this is a general-purpose query tool rather than a structured endpoint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
posthog_replaysFind session replaysARead-only
Session recordings of one distinct_id in a time window, newest first, with links to watch them. Recordings older than the instance retention are gone. Naive timestamps are read in the project timezone.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Window end, ISO 8601; defaults to now | |
| from | No | Window start, ISO 8601; defaults to 7 days before `to` | |
| limit | No | Maximum number of sessions | |
| project_id | No | Project id; defaults to POSTHOG_PROJECT_ID | |
| distinct_id | Yes | distinct_id of the person or device |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only behavior, and the description adds meaningful context: results are sorted newest first, recordings older than instance retention are unavailable, and naive timestamps are interpreted in the project timezone. It does not describe auth requirements, rate limits, or the exact response shape, but those gaps are minor for a read-only lookup tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, with the core function front-loaded. Every sentence earns its place: ordering, watch links, retention limitation, and timezone behavior. There is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
All facts needed to select and invoke the tool are covered: required distinct_id, optional window bounds, limit, ordering, retention, and timezone interpretation. With no output schema, the description only minimally describes the return value via 'links to watch them,' but that is sufficient for basic invocation confidence.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% description coverage, so the baseline is 3. The description adds genuine cross-parameter nuance beyond individual field docs: the from/to window parameters assume naive timestamps in the project timezone, and results are ordered newest first. This helps the agent format the time-window parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource: session recordings for one distinct_id in a time window, with a clear ordering (newest first) and an output affordance (links to watch them). This is distinct from the sibling tools like posthog_query or posthog_api_get, which are more generic. An agent can tell exactly what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is clear from context: fetch session replays for exactly one distinct_id within a bounded time window. However, there is no explicit guidance about when to prefer this over sibling tools or when it would not be appropriate. The agent must infer that posthog_query is not the right tool for retrieving watchable replay links.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
posthog_api_get - First observed
posthog_event_definitions - First observed
posthog_projects - First observed
posthog_property_definitions - First observed
posthog_query - First observed
posthog_replays
TDQS
Scored across 6 tools
Each tool targets a distinct area—definitions, projects, HogQL querying, replays, and generic REST access—so an agent can usually choose correctly. The only mild overlap is between posthog_query and posthog_api_get, but the HogQL vs REST distinction is clearly drawn.
All tools share a posthog_ prefix and snake_case, but the pattern is mixed: event_definitions, projects, property_definitions, and replays are resource nouns, while posthog_query is an operation and posthog_api_get introduces a verb suffix. It is readable but not a consistent verb_noun scheme.
Six tools cover the core PostHog introspection and querying use cases without padding. The generic posthog_api_get tool avoids the need for many narrowly-scoped REST endpoint tools.
Event/property definitions, project selection, HogQL querying, session replays, and a generic REST GET cover the main read and analysis workflows. Write/update operations are not exposed through the REST wrapper, but that appears intentionally out of scope for this query-oriented toolkit.
Maintenance
Related MCP Connectors
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Read-only MCP access to sessions, funnels, campaigns, errors, live visitors, and anomalies.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceProvides secure read-only SQL access to PostgreSQL and ClickHouse databases with built-in safety features like read-only enforcement, timeouts, and managed result files.221 PyPIMIT
- FlicenseAqualityCmaintenanceEnables read-only exploration of a Postgres database using natural language, with multiple safety layers to prevent any modifications.5-
- FlicenseNot gradedqualityCmaintenanceEnables running read-only SQL queries and exploring DuckDB databases through MCP tools like listing tables, describing schemas, and fetching paginated data.-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to query PostgreSQL, inspect schemas, and explain queries, designed for local and development databases with read-only safety by default.37 npmMIT