mcpbeat Sign in

Querying Canvas Data Agent Skill

> capture, openExternal, navigate), the data hierarchy (saved insights first, typed query nodes second, inline HogQL last), per-insight-type result shapes, date-range wiring, and event capture from a canvas. Use whenever a canvas shows metrics, charts, tables, or any PostHog data, or needs to send analytics events.

1k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
690
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/PostHog/posthog --skill querying-canvas-data

The instruction itself

5 sections, as written by the author

Querying canvas data

The global ph object (injected by the host — never imported, never initialized) is the only way

a canvas talks to PostHog. Credentials stay in the host; fetch(), posthog-js, and hand-rolled

clients fail in the sandbox.

Data hierarchy — back every metric with a saved insight

  • Preferred — save an insight, load it by reference. Use the PostHog MCP insight tools to

create/save an insight that computes the metric with an insight query type (TrendsQuery,

FunnelsQuery, RetentionQuery, PathsQuery, or the web-analytics kinds WebOverviewQuery /

WebStatsTableQuery — not raw SQL). Confirm its numbers, note the short_id, and render it with

await ph.loadInsight(shortId, { dateRange }). These are proven queries — numbers match the

PostHog UI exactly (sessionization, unique users, breakdowns, bounce rate). Never fabricate a

query or guess event/property names; discover and save them via MCP first.

  • Secondary — an ad-hoc typed node: ph.query({ kind: "TrendsQuery", series: [...], dateRange: {...} })

when saving an insight genuinely doesn't fit.

  • Last resort — inline HogQL: ph.query("SELECT …"), only when no insight kind can express

the metric; you then own the SQL and its date window.

For web-analytics boards specifically, use the web-analytics query kinds — raw HogQL subtly gets

bounce rate, sessionization, channel attribution, and unique-visitor counts wrong.

Whatever tier you use, declare it in the project's capabilities before publishing: every

ph.loadInsight short id in capabilities.posthog.insights, every ph.capture event name in

captureEvents, and inlineQueries: true for any ph.query use. The host rejects undeclared

calls at runtime, and validation fails on undeclared literals.

Result shapes — read them correctly or every value renders 0

  • Trends-style results (insight query types, via ph.loadInsight or a typed node): results

is an array of series objects, not rows. Each series has data: number[] (per interval),

days: string[] (ISO), labels: string[], count (sum), aggregated_value (single-value

total), label, and optional compare_label: "current" | "previous". A KPI total is

results[0].count (or .aggregated_value); a line chart plots results[0].data over

results[0].days. With a compare period, find the prior series by compare_label === "previous"

— never by index. columns is empty here.

  • SQL results: { columns: string[], results: rows[][] } — each row an array of cell values in

columns order.

Load data in useEffect with useState, show a loading state, and handle empty/error. Aggregate

in the query; never fetch raw event dumps.

Date windows

  • Pass the canvas's date-picker window straight into dateRange:

ph.loadInsight(shortId, { dateRange: { date_from: win.start.toISOString(), date_to: win.end.toISOString() } })

— the saved insight re-scopes to the window with no time SQL. Typed nodes take the same

dateRange. Re-run every query when the window changes.

  • A saved SQL insight may ignore dateRange (its window lives inside the SQL) — a reason to

prefer insight query types.

  • Inline HogQL escape hatch only: never bake now() or a hardcoded INTERVAL. Compute unix bounds

(Math.floor(win.start.getTime() / 1000)) and write half-open

timestamp >= toDateTime(fromUnix) AND timestamp < toDateTime(toUnix). Prior period = the

equal-length window immediately before; bucket with toStartOfDay/toStartOfHour.

Side effects

  • ph.capture(event, properties?, distinctId?) — analytics events for interactions

(fire-and-forget). Session replay, $session_id, and person attribution are handled by the

host automatically; never roll your own capture.

  • ph.openExternal(url) — opens https://posthog.com / *.posthog.com URLs only, and only from

a user interaction (opens outside focus are ignored). Don't link elsewhere.

  • ph.navigate.toTask(id) / .toNewTask() / .toCanvas(id) / .toNewCanvas() — in-app

navigation within the canvas's own channel.

Other skills for the same job

different authors, same section of the catalogue
Youtube Automation
by ComeOnOliver
×2

Automate YouTube tasks via Rube MCP (Composio): upload videos, manage playlists, search content, get analytics, and handle comments. Always search tools first for current schemas.

5k tokens needs MCP
Scientific Visualization
by K-Dense-AI
×1

Create and audit truthful, accessible, publication-ready scientific figures with Matplotlib, Seaborn, or Plotly. Use for figure design, multi-panel layouts, uncertainty and missing-data displays, color/contrast review, image metadata validation, and journal export planning.

48k tokens scripts
Video Comparer
by nicepkg
×1

This skill should be used when comparing two videos to analyze compression results or quality differences. Generates interactive HTML reports with quality metrics (PSNR, SSIM) and frame-by-frame visual comparisons. Triggers when users mention "compare videos", "video quality", "compression analysis", "before/after compression", or request quality assessment of compressed videos.

24k tokens scripts
Pyimagej Fiji Bridge
by BioTender-max
×1

Python bridge to ImageJ2/Fiji for macros, plugins (Bio-Formats, TrackMate, Analyze Particles), NumPy↔ImagePlus/ImgLib2 exchange, and ImageJ Ops. Automates Fiji headlessly from Python. Use scikit-image for pure Python without Fiji plugins; napari for visualization.

6k tokens
Threejs Skills
by ComeOnOliver
×1

Create 3D scenes, interactive experiences, and visual effects using Three.js. Use when user requests 3D graphics, WebGL experiences, 3D visualizations, animations, or interactive 3D elements.

7k tokens
Chart Image
by zebbern

Generate publication-quality PNG chart images from data, supporting line, bar, area, candlestick, pie, and heatmap charts. Triggers when the user asks to visualize data, create a graph, plot a time series, or generate a chart for a report, alert, or dashboard. Runs as a lightweight, headless Node.js process without a browser.

19k tokens scripts
Tao Analyze Changenet Rca
by NVIDIA
vendor

Performs deep Root Cause Analysis (RCA) on NVIDIA TAO Visual ChangeNet classification experiments with image-evidence-driven investigation. Use when analyzing ChangeNet model failures, investigating poor recall / FAR / PASS-NO_PASS metrics, auditing visual inspection pipeline quality, or running an RCA report for an AOI defect-detection model. Trigger phrases include "RCA on my ChangeNet model", "why is my AOI model failing", "audit ChangeNet predictions", "investigate FAR regressions", "root cause analysis on visual-changenet".

22k tokens scripts
Threejs
by mrgoonie

Build 3D web apps with Three.js (WebGL/WebGPU). Use for 3D scenes, animations, custom shaders, PBR materials, VR/XR experiences, games, data visualizations, product configurators.

37k tokens

How to use it

Copy the folder

Take posthog/querying-canvas-data from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.