Implementing MCP tools
Contents
MCP tools are atomic capabilities – CRUD operations and simple actions that agents compose into workflows. Every product should be accessible through the MCP server. Tools answer "what can I do?" (list feature flags, execute SQL, create a survey).
For teaching agents how to use these capabilities in combination, see Writing skills.
TL;DR
Tool design principles
MCP tools should be basic capabilities – atomic CRUD operations and simple actions. Agents compose these primitives into higher-level workflows.
Good tools:
- List feature flags
- Get an experiment by ID
- Create a survey
- Summarize a session recording
Bad tools:
- "Search for session recordings of an experiment" – this bundles multiple concerns. Instead, expose four composable tools: list experiments, get experiment, search session recordings, summarize sessions.
The reasoning: agents are better at composing simple tools than navigating complex ones, and simple tools are reusable across many workflows.
Two MCP server versions
Clients must support two main capabilities: MCPs and skills.
MCP support is widespread; however, skills support is still very early
and mostly coding agents support them.
To mitigate this, the MCP server ships two versions controlled via the
x-posthog-mcp-version: <version_number> header.
Legacy MCP (v1)
For clients that don't support skills. Exposes the full set of CRUD tools with simple instructions (list, read, create, update, delete).
Primarily oriented toward vibe-coding web tools.
SQL-first MCP for clients supporting skills (v2)
v2 instructs the agent to read data through a unified HogQL interface (list and get tools are generally excluded), which unlocks flexibility in data retrieval, search, and manipulation. Additionally, the consumer has access to a skill that provides schema references and example patterns, giving it richer context about PostHog's data model.
Primarily oriented toward coding agents (PostHog Code, PostHog AI, Claude Code).
SQL-first MCP: HogQL system tables
Every list/get endpoint exposed as an MCP tool must have a corresponding HogQL system table. This lets agents query PostHog data via SQL in addition to (or instead of) the REST API tools.
System tables are defined in posthog/hogql/database/schema/system.py as PostgresTable instances.
Each table must include a team_id column for data isolation.
Use mcp_version: 1/2 to control availability of retrieval tools in v2 of the MCP.
Example from the codebase:
Agents query these tables with the system. prefix:
Extending query examples
When you add a new system table,
also add a model reference file to products/posthog_ai/skills/query-examples/references/.
The naming convention is models-<domain>.md.
Existing references:
models-actions.mdmodels-cohorts.mdmodels-dashboards-insights.mdmodels-data-warehouse.mdmodels-error-tracking.mdmodels-flags-experiments.mdmodels-groups.mdmodels-notebooks.mdmodels-surveys.mdmodels-variables.md
Each file documents the table's columns, types, nullability, and notable structures (like JSON fields).
See models-flags-experiments.md for a good example.
Register your new reference in products/posthog_ai/skills/query-examples/SKILL.md under Data Schema.
Code generation pipeline
The pipeline turns Django serializers into MCP tool handlers via OpenAPI. Run the full pipeline with:
Pipeline steps
YAML definitions
YAML definitions are the configuration layer. They can live in two locations:
products/<product>/mcp/*.yaml– preferred for product-owned definitions, keeps config close to the code.services/mcp/definitions/*.yaml– shared location.
The build pipeline discovers YAML files from both paths. Product teams own their definitions and control which operations are exposed as MCP tools.
Workflow: scaffold, configure, generate.
Scaffold a starter YAML with all operations disabled. Operations are discovered by matching URL paths against product names (e.g.,
error_trackingmatches all paths containing/error_tracking/).shConfigure the YAML – enable tools, add scopes, annotations, and descriptions. Each YAML file has a top-level structure validated by Zod (
scripts/yaml-config-schema.ts):Tool names follow a
domain-actionconvention in kebab-case, e.g.feature-flags-list,experiments-create,surveys-delete. The domain groups related tools together and the action describes the operation.YAMLUnknown keys are rejected at build time (Zod
.strict()) to catch typos early. See supported annotations for the full list.Generate handlers and schemas:
sh
Keeping definitions in sync
When backend API endpoints change, sync the YAML definitions:
This is idempotent and non-destructive –
it only adds newly discovered operations (with enabled: false) and removes stale ones.
All hand-authored configuration is preserved.
CI runs this as a drift check.
See services/mcp/definitions/README.md for the full YAML schema reference
and services/mcp/scripts/yaml-config-schema.ts for the Zod validation source.
Testing
See How to develop and test for instructions on running the MCP server locally and verifying tools end-to-end.
Serializer best practices
Descriptions flow through the entire pipeline:
Product teams should type and describe their serializer fields. These descriptions are what agents read to understand tool parameters – vague or missing descriptions lead to worse agent behavior.
Tips:
- Use
help_texton serializer fields – it becomes the OpenAPI description. Be careful when using imperative language inhelp_text, as the same annotations are used in the API docs. - Use
param_overridesin YAML definitions to override Orval-generated descriptions. This is useful when you want to add imperative instructions for specific fields. - Be specific about formats, constraints, and valid values.
- Avoid jargon that an LLM wouldn't understand without context.
HogQL query schemas (WIP)
frontend/src/queries/schema/schema-assistant-queries.ts defines structured query types
for the AI assistant (trends, funnels, retention, etc.).
These schemas describe the shape of analytical queries with rich JSDoc comments that help agents generate correct HogQL. The cleaner and better-described these schemas are, the better agents perform at query generation.
This is a work in progress –
the goal is to make it easier to generate HogQL queries from typed schemas
than from freeform SQL.
A schema.json integration into the codegen pipeline is planned.
Agent skills that support the MCP server
query-examples– HogQL query patterns, system model schemas, and available functions. Extend this skill to explain how agents should use your HogQL-exposed tables and queries. Seeproducts/posthog_ai/skills/query-examples/SKILL.md.