Clamp Analytics MCP Server
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CLAMP_API_KEY | Yes | Project API key (starts with 'sk_proj...'). Get it from the Clamp dashboard under Settings > API Keys. |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| projects.list | List all Clamp projects this credential can access. Returns each project's id, name, and plan ('free', 'pro', or 'growth'). Use this when the user asks "which sites do you see" or when the agent needs a project_id to disambiguate before calling another tool — most other tools auto-resolve when the credential has access to exactly one project, so explicit calls are only needed for multi-project setups. Examples:
Limitations: returns an empty array if the credential is org-scoped but has no projects yet. The plan field is the current billing plan, not a permission level. |
| traffic.overview | High-level snapshot of website traffic over a period: total pageviews, unique visitors, sessions, bounce rate (%), and average session duration (seconds). Always includes a comparison block with the same metrics for the previous period of equal length plus the absolute and percentage delta. Use this as the first call when the user asks how the site is doing, before drilling into channels, pages, or funnels. Examples:
Limitations: bounce_rate and avg_duration are derived from the SDK's pageview_end beacon — for SDK <0.3 they return null. Custom date ranges must be in YYYY-MM-DD:YYYY-MM-DD format. Maximum range is 365 days. |
| events.list | Get custom event counts. Without a Property values can be strings, numbers, or booleans (each stored in a separate column). When filtering or grouping by a numeric or boolean property, set Examples:
Limitations: only one property/value pair per call. group_by only works when a name filter is set. Returns at most |
| events.observed_schema | Return what's actually firing into ingest as a structured signature, for diffing against the project's authored Response shape: Each property value is an array of typed observations. One entry = the key consistently fired with one type. Two-plus entries = same key fired under multiple storage columns in the period, which is exactly the silent-type-drift signal you want to surface (one call site sending Use it to compare declared vs reality:
Examples:
Limitations: returns keys + types only, no property values. Pairs with: |
| revenue.sum | Sum revenue from Money-typed event properties. Returns per-currency totals, optionally grouped by a traffic dimension (referrer_host, channel, country, device_type, pathname, utm_source/medium/campaign). Different currencies are never mixed in a single sum — each row is one (group, currency) pair. Money properties are tracked via clamp.track("purchase", { total: { amount: 29, currency: "USD" } }) — see /docs/concepts/revenue for the full Money type. Attribution: Examples:
Limitations: events without any Money property contribute zero. If |
| users.journey | Chronological session history for a single visitor (anonymous_id). Each session collapses to one row showing the start and end timestamps, entry page, channel, referrer host, UTMs, country, device type, pageview count, and the distinct custom event names fired in that session. The first row is flagged with Use this when an aggregate query can't answer the question — multi-touch attribution analysis, support / debugging investigations ("what did this user do before signing up?"), or sanity-checking a specific account's journey before drawing conclusions about a cohort. Examples:
Limitations: requires the visitor's anonymous_id, which the SDK exposes via Pairs with: |
| errors.list | Recent error events with full context. One row per occurrence, returned newest-first. Each row carries the error itself (message, type, stack, fingerprint, handled flag) plus the standard event context (url, browser/OS/device, country, anonymous_id, session_id) — same shape ingest enriches every other event with, so an agent can correlate "errors here, traffic there" without joining a second tool. Errors are written to the events table with name = "$error" by the SDKs' captureError() / window.onerror auto-capture. The server adds a stable Examples:
Limitations: returns up to Pairs with: |
| errors.groups | Errors deduplicated by server-computed fingerprint, with counts and first/last-seen timestamps. The triage view: which bugs are firing most often, affecting the most users, or showing up newly in the period. Each group is one fingerprint (a bug). Examples:
Limitations: only fingerprintable errors are grouped; events with neither message nor stack get a null fingerprint and are excluded from this view (they still show up in errors.list). Default sort is by count; pass sort_by to change. Default limit 50, max 200. Pairs with: |
| errors.timeline | Error count over time, bucketed hourly or daily. Optionally scoped to one fingerprint. Use this to spot regressions ("when did this bug start firing?") or post-deploy spikes ("did the deploy at 14:00 break something?"). Returns a series of { bucket, count } rows. The bucket field is an ISO timestamp aligned to the start of the interval. Buckets with no errors are omitted (sparse series); the agent should treat missing buckets as zero. Examples:
Limitations: interval defaults to "hour" for periods ≤ 7 days, "day" otherwise. Override only if the default produces too few or too many buckets for the question. No fingerprint filter returns the total error rate across all bugs. Pairs with: |
| errors.context | Breadcrumbs leading to one error: the events from the same session, before the error timestamp, in chronological order. The "what was the user doing right before this broke" view that turns a stack trace into a story. Given an anonymous_id and the error's timestamp, finds the session that was active at that timestamp and returns up to Examples:
Limitations: scoped to the single session that contained the error. If the error fired during a session the user later ended (closed tab), and you pass a timestamp in a later session, you'll get that later session's events instead. Returns events only — not their full property bags (use users.journey if you need the per-event context). Default limit 20, max 100. Pairs with: |
| traffic.timeseries | Event counts over time as date buckets. Returns [{ date, count }] sorted ascending. Granularity is automatic based on period length (hourly for ≤2 days, daily for ≤90 days, weekly for ≤365 days, monthly beyond) and can be overridden via Examples:
Limitations: forcing granularity="hour" over a 90-day period produces hundreds of buckets and may be truncated server-side. Buckets with no matching events return zero (the series does not skip missing dates). |
| funnels.create | Create and immediately evaluate a conversion funnel. A funnel measures how many unique visitors complete an ordered sequence of steps. Returns step-by-step counts, per-step conversion rates (vs the previous step), and overall conversion (last step / first step). The funnel is saved by name and can be re-evaluated later or for different periods via funnels.list. Step format: a custom event name like "signup", a pathname-scoped pageview like "pageview:/pricing", and optionally one or more property predicates appended in brackets — "cta_click[location=hero_primary]" matches only cta_click events whose location property equals "hero_primary". Stack predicates to AND them: "cta_click[location=hero_primary][plan=pro]". Predicates work on pageview steps too: "pageview:/pricing[utm_source=google]". Requires Pro plan. Predicates default to string-typed comparisons (the property is read from the string column). For number- or boolean-typed properties (declared as such in event-schema.yaml), append a type tag: "purchase[count:n=5]" matches numeric 5; "checkout[refunded:b=false]" matches boolean false; "purchase[plan:s=5]" forces string matching when the value looks numeric. Tags: ":n" number, ":b" boolean (true|false|1|0), ":s" string (default). Examples:
Limitations: between 2 and 10 steps; step strings ≤500 chars; names ≤200 chars. Step order matters — once a session skips a step, it cannot complete later steps. Pageview pathnames match exact strings only (no wildcards). Predicate keys must be snake_case; string values may not contain ']' or '['. Number predicates require a finite value; boolean predicates require true|false|1|0. Funnel evaluation is per-session, not per-user across devices. |
| funnels.list | Retrieve and re-evaluate a previously created funnel against current data for the specified period. Without a Examples:
Limitations: returns 404 if no funnel exists by that name — call funnels.list with no name first to enumerate. Cohort filters apply at the session level, not retroactively per step. Funnel definitions are immutable after creation (re-create with a new name to change steps). |
| cohorts.create | Create and persist a named cohort — a group of visitors defined by an event in a period, optionally narrowed by a property filter. The cohort is stored by name; subsequent retention/compare queries reference it without re-specifying the definition. Membership is recomputed at query time, not materialised, so the same cohort always reflects current data. Requires Pro plan. The 0.x cohort definition is event-based: the user fired Examples:
Limitations:
Pairs with: |
| cohorts.list | List saved cohorts for the project. With Examples:
Limitations: |
| cohorts.retention | Compute the retention curve for a saved cohort. For each requested window (e.g. day 1, 7, 14, 30 after the cohort's anchor event), returns how many cohort members fired any non-pageview-end event in that day's window, and the rate vs the cohort size. Use this to answer "did this cohort stick around?" and to compare retention across cohorts (via Examples:
Limitations: retention measures any non-pageview-end event presence. Custom retention metrics (e.g. "retained = fired purchase event") are not in 0.x. The numerator is computed per-day, so windows like "30d" return only day-30 activity. Cohort size is the denominator and is included in the response so consumers can apply sample-size discipline. Pairs with: |
| cohorts.compare | Compare two saved cohorts side-by-side on retention. Returns each cohort's size and retention curve over the same period set, so you can read "did this week's signups retain better than last week's?" or "is this experiment cohort behaving differently than control?" without composing the rates manually. Examples:
Limitations: only two cohorts at a time. The same retention windows are applied to both — there's no way to use different windows per side. Sample-size caveats apply per cohort; check both |
| cohorts.delete | Delete a saved cohort by name. Irreversible — the agent should confirm intent with the user before calling this. The underlying event data isn't touched; only the cohort definition row is removed. Examples:
Limitations: irreversible. Returns 404 if the cohort doesn't exist. Definition is not returned before deletion — capture it from cohorts.list first if you may need to recreate it. |
| alerts.create | Create a metric alert that fires when a condition crosses its threshold. The alert monitors one metric (pageviews, visitors, sessions, bounce_rate, or avg_duration) over a rolling period and is re-evaluated every time an MCP session connects — alerts surface in-thread when the agent next checks, not as background pushes. Use to set lightweight monitoring like "alert me if pricing pageviews drop 50% week-over-week" or "alert me if bounce rate exceeds 70%". Requires Pro plan. Examples:
Limitations: evaluation is on MCP session connect, not background — there are no push notifications, emails, or webhooks. Threshold for above/below is the absolute metric value; for drops_by/increases_by it is the percentage change vs the previous period of the same length. One alert per call — create multiple alerts for multiple conditions. |
| alerts.list | List all alerts configured for a project. Returns each alert's id (UUID), metric, condition, threshold, period, optional pathname scope, and created_at timestamp. Use before alerts.delete to find the id you want to remove, or to show the user every monitor currently active. Returns an empty array if no alerts have been created yet. Examples:
Limitations: alert state (currently firing vs not) is not included — that surfaces only when the alert is re-evaluated on MCP session connect. There is no pagination; projects with many alerts return all of them in one response. |
| alerts.delete | Delete an alert by its id. Find the id by calling alerts.list first. The deletion is irreversible — there is no soft-delete or undo, and the agent should confirm intent with the user before calling this on a non-trivial alert. Returns 404 if no alert with that id exists for the project. Examples:
Limitations: irreversible. Does not return the deleted alert's prior configuration — capture it from alerts.list first if you may need to recreate it. The alert_id must be the UUID returned by alerts.list, not a metric name. |
| traffic.breakdown | Aggregate visitors and pageviews grouped by a single dimension. The Examples:
Limitations: aggregates pageview events only — for custom event breakdowns use events.list with |
| traffic.compare | Compare one metric across two arbitrary periods side-by-side. Returns both period values plus absolute delta and percentage delta. Periods do not need to be the same length — the percentage delta normalizes by ratio so longer/shorter comparisons remain meaningful. Use when the user asks month-over-month, before-vs-after-launch, or "how does this week compare to last". Examples:
Limitations: one metric per call — for multi-metric comparison either call repeatedly or use traffic.overview (which always includes the previous period). Period strings must be a preset ("today", "yesterday", "7d", "30d", "90d") or a YYYY-MM-DD:YYYY-MM-DD range; relative phrases like "last quarter" are not parsed. |
| sessions.paths | Aggregate (entry_page → exit_page) session pairs. Returns the top pairs with how many sessions followed each path, average pages per session, average duration in seconds, and a bounce flag. Use to answer "what do visitors do after landing on /pricing", "where do sessions end", or "which entry pages lead to the deepest engagement". Aggregate-only — no per-user traces, no full pageview chains, no individual session reconstruction. Examples:
Limitations: shows entry and exit only, not the full pageview chain in between (use events.list for granular event analysis). min_pages=1 (default) includes single-page sessions which always show as bounces; set min_pages=2 to exclude them. Sessions ending without a pageview_end beacon (e.g. browser crash) may have null durations. |
| pages.engagement | Per-page metrics with a selectable detail level. The
Examples:
Limitations: avg_engagement_seconds is null for pages without pageview_end data (SDK <0.3 or pages closed during navigation). view="sections" requires the section-views SDK extension installed (see /docs/sdk/extensions/section-views) and only counts elements with the data-clamp-section attribute — pages with no instrumented sections return []. view="sections" without |
| traffic.live | See who is on the site in the last N minutes. Returns the active visitor count plus top pages, top referrers, and top countries within that window. Defaults to 5 minutes; max 60. Use during incidents ("is anyone hitting the broken page right now"), launches ("is the new post getting traffic"), or whenever the user asks "who is on the site". Examples:
Limitations: ingestion lag is ~30 seconds, so "live" is approximate. Visitor count is unique anonymous_ids in the window, not active sessions. For historical questions ("who visited last week"), use traffic.overview instead. |
| docs.search | Keyword-search the Clamp documentation index for setup, SDK, MCP, concepts, and skills pages. Returns ranked entries with url, title, and a short description. Each match scores higher when query terms appear in the title than the description; results are capped by Examples:
Limitations: keyword (substring) matching only — no semantic search, so synonyms ("webhook" vs "callback") will not match. The index is hand-maintained inside the MCP server and updates only when the server is redeployed. Returns an empty array if no matches; broaden the query rather than retrying with the same terms. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| weekly_report | Generate a weekly analytics report summarizing traffic, top pages, referral sources, and geographic breakdown. Call this to get a comprehensive snapshot of the past 7 days compared to the prior week. |
| traffic_diagnosis | Diagnose why traffic changed. Investigates which channels, countries, devices, and pages are responsible for a traffic increase or decrease. Use when a metric moved unexpectedly. |
| conversion_audit | Audit conversion performance by analyzing funnels and custom events. Identifies the biggest drop-off points and suggests where to focus optimization efforts. |
| channel_breakdown | Deep-dive into traffic channels to understand which sources drive real engagement vs just visits. Compares organic search, social, referral, direct, paid, and email traffic quality. |
| page_performance | Deep-dive into a specific page's performance: traffic trends, referral sources, device breakdown, and engagement metrics. Use to understand how a single page is performing. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/clamp-sh/mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server