Tracklution

Use Tracklution MCP to install and configure server-side conversion tracking with your AI coding agent.

Community: Submitted by a user or imported; check the owner before granting accessOnlineNo sign-inGlobalFreeRead-only

What it can do

  • Get Status: Connectivity check only — does NOT return any analytics data. Pings every connected Tracklution server and reports reachable / unreachable. USE WHEN: - The user reports the integration "is
  • Get Api Key Info: API key inspection only — does NOT return any analytics data. Shows the key name, prefix, how many containers it can access, and when it expires, for every connected server. USE WHEN
  • List Containers: Entry-point tool. Lists every tracking container the user can access across all connected servers. Each container is one tracked website or app. USE WHEN: - Starting any session — you

What data it sees

Do you need an account

No: the server works without sign-in

Use Tracklution MCP to install and configure server-side conversion tracking with your AI coding agent. Verify your setup, troubleshoot issues, and query performance data.

Server tool list (18)

Raw names from tools/list. Only developers need these.

get_statusConnectivity check only — does NOT return any analytics data. Pings every connected Tracklution server and reports reachable / unreachable. USE WHEN: - The user reports the integration "isn't working" and you need to isolate network vs. data issues. - You want to confirm a freshly-added server is online before running real queries. For any data question (counts, events, sessions), skip this and go straight to get_summary or get_report.
get_api_key_infoAPI key inspection only — does NOT return any analytics data. Shows the key name, prefix, how many containers it can access, and when it expires, for every connected server. USE WHEN: - The user asks "which account / key am I connected with?" or "when does my key expire?". - You hit an authorization error and need to confirm the key is still valid. For any data question, skip this and go straight to get_summary or get_report.
list_containersEntry-point tool. Lists every tracking container the user can access across all connected servers. Each container is one tracked website or app. USE WHEN: - Starting any session — you need a container_id before calling get_report, get_summary, list_events, or list_sessions. - The user asks "which sites / accounts can I see?" or names a brand without giving a trc_ ID. - You need the server_name for multi-server setups. - **OAuth fallback path of the agent install contract** (https://www.tracklution.com/agent-install.md, Turn 4 Step 2) — after the user completes browser-OAuth, call this tool to enumerate the user's containers and resolve the (container_id, container_hash) pair you need for onboarding tools (get_installation_scripts, verify_and_score, create_login_link, ...). Match against the user's website URL via the `domain` field (compare by host name — `domain` may be `null` on freshly-created containers, skip those). Returns container IDs (trc_...), container hash (dashboard-URL identifier AND secret half of the dual-key auth-token cache lookup; pass as `container_hash` on every onboarding-tool call — may be `null` on legacy Laravel deploys that pre-date the field, in which case fall back to register_and_provision with auth_token + website_url), titles, domains, currency, timezone, and active status.
get_containerDetail view of one container — reveals which event names are tracked and which connectors (Google Ads, Facebook, GA4, etc.) are active. USE WHEN: - You need the exact event names to pass as event_name filter on get_report / list_events (don't guess names like "Purchase" — check here first). - You need the connector alias for get_report's connector= filter. - The user asks "what's set up on site X?" or "which integrations are live?". Call list_containers first to find the trc_ ID. Returns no time-series or event data — pair with get_summary / get_report for that.
get_reportAggregated analytics broken down by dimension and/or time. Fast — hits the pre-aggregated reporting endpoint, not the raw events table. USE WHEN the user asks for counts, values, or trends grouped by anything: - by event name ("how many Purchases vs Leads?") → dimensions=['event_name'] - by traffic source ("top sources?", "Google vs Facebook?") → dimensions=['source'] - by day / week / month ("daily conversions", "weekly trend") → granularity + read daily_series in response - by hour, device, or browser → dimensions=['hour'|'device'|'browser'] - first-click vs last-click attribution → attribution='first_click' - filtered to one delivery integration ("events delivered to Facebook CAPI") → connector='facebook' Prefer this over list_events / list_sessions for ANY question that resolves to a number, a chart, or a ranking — it is orders of magnitude faster. For a single-period overall snapshot (no dimension breakdown), use get_summary instead. Date range required, max 30 days. Call get_container first if you need the list of valid event names for this container.
get_summaryAggregated performance snapshot for one container over a date range. Fast — hits the pre-aggregated reporting endpoint, not the raw events table. USE WHEN the user asks: - "How is my site performing last week?" - "How many events / what's the total value / how many emails collected?" - "What's my recovery rate / how many ad-blocked events?" - "Quick breakdown by traffic source" Returns totals, consent stats, recovery (adblock + restricted-browser) stats, and a per-source breakdown — all in one call. This is the DEFAULT first call for any single-period performance question. Only escalate to get_report when the user wants a breakdown by a specific dimension (event_name, day, hour, device, browser) or a time series. Date range required, max 30 days.
list_eventsFetch ONE event by its ID. The only way to use this tool is to pass a known event_id (starts with "evt_" or "TE"). Listing / filtering by date, source, status, or has_* flags is NOT supported on this tool. USE WHEN: - The user references a specific event ID (TE... or evt_...) — pass it as event_id. DON'T USE for counts, totals, top-N rankings, trends, or any breakdown by source / event_name / day — use get_report instead. For an overall performance snapshot, use get_summary. If the user genuinely needs raw events, ask them to look one up in the Tracklution dashboard and provide its ID. Returns a one-element events array (the same shape as before) so existing parsers keep working.
list_sessionsFetch ONE visitor session by its ID, with the full event timeline, UTM params, device info, country, and event counts. The only way to use this tool is to pass a known session_id (starts with "ses_" or "VS"). Listing / filtering by date, source, or has_* flags is NOT supported on this tool. USE WHEN: - The user references a specific session ID (VS... or ses_...) — pass it as session_id. DON'T USE for session counts, conversion rates, top sources, or any "how many sessions" / "show me sessions" question — use get_report or get_summary instead (orders of magnitude faster). If the user genuinely needs to inspect a session, ask them to look one up in the Tracklution dashboard and provide its ID. Returns a one-element sessions array (the same shape as before) so existing parsers keep working.
query_eventsNote: this tool holds data for a limited timeframe — only the last ~7-14 days are available, depending on the container. Paginated list of raw events for a date range, with filters (event_name, source, status, and 10 has_* click-ID presence flags). DATA RETENTION: the v2 store currently holds only the last ~7-14 days. Older date_from values pass validation but return empty rows. A "warnings" array is added when date_from is outside the retention window. USE WHEN: - User wants to loop through all events for a given date range, inspecting data from each one in detail. - User wants to enumerate events matching a filter (e.g. "show all Purchase events with gclid this week", "list error events from yesterday"). - User explicitly wants raw event records, not aggregates. DON'T USE for counts, totals, top-N rankings, breakdowns by source/day — use get_report (orders of magnitude faster on aggregates). For a single event by ID, use list_events. STATUS FILTER: defaults to "processed" — these are the real, successfully-recorded events that nearly every analytics question is about. Only set status explicitly when debugging delivery/ingestion issues: "pending" (queued, not yet processed), "error" (processing failed), "rejected" (validation/spam blocked). Asking for non-processed events without a debugging reason will mislead the user. Pagination is cursor-based: pass the returned meta.cursor.next_cursor back as cursor on the next call. Stop when has_more is false. Backend caps date range at 30 days.
query_sessionsNote: this tool holds data for a limited timeframe — only the last ~7-14 days are available, depending on the container. Paginated list of visitor sessions for a date range, with filters (source and 10 has_* click-ID presence flags). Each session record includes UTM params, device info, country, event counts, contact-presence flags (no raw PII), and the full event timeline. DATA RETENTION: the v2 store currently holds only the last ~7-14 days. Older date_from values pass validation but return empty rows. A "warnings" array is added when date_from is outside the retention window. USE WHEN: - User wants to loop through all sessions for a given date range, inspecting data from each one in detail. - User wants to enumerate sessions matching a filter (e.g. "list sessions from organic with adblock this week"). - User explicitly wants raw session records, not aggregates. DON'T USE for session counts, top sources, or "how many sessions" / conversion-rate questions — use get_report or get_summary (orders of magnitude faster). For a single session by ID, use list_sessions. Pagination is cursor-based: pass the returned meta.cursor.next_cursor back as cursor on the next call. Stop when has_more is false. Backend caps date range at 30 days.
scout_websitePublic discovery; safe to call without auth. Detects CMS/platform hints and creates an onboarding session. Returns an `onboarding_session_id` and a single-use `_sensitive_onboarding_session_token` used by `register_and_provision` to link this scout to the provision. Every response includes `_request_id` in `structuredContent`. When reporting issues to Tracklution support, include this value verbatim — it correlates the call across both the MCP server and the Laravel backend logs.
register_and_provisionCreate/reuse an account and the first tracking container in one agent-safe call. For brand-new emails: the API creates the account, immediately emails the user a welcome / set-password link, and returns a 60-minute JWT in `data.auth._sensitive_access_token` so this agent can continue applying snippets and verifying events without further authentication. Hold the JWT only for this conversation and pass it back as `auth_token` on subsequent onboarding tool calls. After the user clicks the welcome email link, they finish setup and log into the dashboard. The response carries two informational flags for fresh registrations: `pending_user_activation: true` and `welcome_email_sent_to: <email>`. Surface the inbox-check instruction to the user verbatim when these are present. PROACTIVE auth_token: If you ALREADY have an `auth_token` (the user is signed in, or a previous turn returned one), pass it INSTEAD of `email`. With `auth_token` the call returns the existing-or-new container for that (user, website_url) pair — no `duplicate_account` error occurs. Do NOT pass `name` or `email` alongside `auth_token`; the server reads identity from the JWT. RECOVERY on `duplicate_account` (HTTP 409): the user already has a Tracklution account. Ask them to log in at https://app.tracklution.com (or request a fresh setup link at https://app.tracklution.com/account-recovery if they never finished the welcome flow), then re-run this tool with `auth_token` in memory. RECOVERY on `multi_client_ambiguous` (HTTP 409): the JWT-authed user has multiple companies (clients) and the requested `website_url` does not match any existing container. The server cannot pick a company on the user's behalf. Surface `next_action.reason` verbatim (it contains a dashboard URL) and EXIT — do NOT call any other MCP tool. The user finishes the container creation from their dashboard, then can re-run with the resulting `container_id`. RECOVERY on `rate_limited` (HTTP 429): respect `retry_after_seconds` strictly. Never retry without backoff. If `errors[0].details.key` mentions `domain:<host>`, the cap is per-website-domain — a different `email` will NOT bypass it. The MCP server does NOT generate idempotency keys — the agent MUST supply `idempotency_key` (UUID v7 recommended). Every response includes `_request_id` in `structuredContent`.
get_installation_scriptsReturn paste-safe tracking snippets, webhook templates, recommended events, common mistakes, and verification instructions for the given framework. Sensitive: the response includes a `_sensitive_webhook` block — only `structuredContent` carries the live URL. Every response includes `_request_id` in `structuredContent`. APPLY EVERY RELEVANT SNIPPET: the response's `framework_snippets` keys are typically `init`, `page_view`, `purchase`, `lead`, `contact_info`. Apply ALL that match the project's surface: - `init` — always required (loads the tracker). - `page_view` — always required (the first signal of installation). - `purchase` — when the project has a checkout/order success flow (`has_checkout=true`). - `lead` — when the project is a lead-gen funnel. - `contact_info` — when the project has an authenticated user view (`has_login=true`). SKIPPING `contact_info` causes `verify_and_score.scoring_complete` to stay `false` indefinitely; the user will see 'almost done' forever. READ `common_mistakes[]` PER SNIPPET: the Tracklution tracking engine is intentionally robust (deduplicates repeat Purchases, accepts late ContactInfo, absorbs React Strict Mode double-fires), so the `common_mistakes` are framed as OPTIMAL-vs-acceptable, not breakage warnings. Follow them when you can; their absence does NOT break tracking, but their presence makes the developer's network log cleaner.
select_installation_methodPersist the chosen installation method on the container. Mutating — requires an agent-supplied `idempotency_key`. Every response includes `_request_id` in `structuredContent`.
verify_and_scoreForce-process recent events, recalculate scoring, and return a strict verification diagnosis. Mutating — requires an agent-supplied `idempotency_key`. Every response includes `_request_id` in `structuredContent`. COMPLETION CONTRACT (read this every time): The success signal is the envelope's top-level `status`, NOT `verification.scoring_complete`. A fresh install can sit at `scoring_complete=false` indefinitely because of organic metrics (e.g. recovery-rate-based scoring) that mature only as real traffic accumulates — using `scoring_complete` as the completion gate would mean no install ever appears done. Use `status` + `verification.not_ready_reason` (equivalently: `not_ready_reason === null`) as the gate. READING `status` + `verification.not_ready_reason` — three behavioral classes: (A) DONE / hand-off-to-user (no retry, transition to Turn 5 scored hand-off): - `status='ok'` (`not_ready_reason === null`) — install complete on both sides. Call `get_next_steps` to grab `overall_progress` + `next_steps[]`, then `create_login_link` (target_page=dashboard), then send the Turn 5 scored hand-off (see agent-install.md Step 5). - `not_ready_reason='awaiting_connector_activation'` — your code is done; user activates connector in dashboard. Call `create_login_link` (target_page=connectors), send the scored hand-off naming the connector step, and EXIT. `retry.max_retries_recommended === 0`. - `not_ready_reason='awaiting_first_party_mode'` — same shape, target_page=dns. EXIT. - `not_ready_reason='only_pageview_seen'` — code is in, loader works, only PageView received. This is the EXPECTED day-0 state for a fresh install: the user hasn't performed a Purchase/Lead yet, and a 30-second wait will NOT make them click 'Buy' on their own site. Do NOT retry. Transition to the Turn 5 scored hand-off, surface the score, and instruct the user to trigger a real event on the live site, then reply `verify` for a re-check. - `not_ready_reason='missing_bottom_funnel_event'` — same semantics as `only_pageview_seen` (no bottom-funnel event yet). Do NOT retry. Transition to scored hand-off; user must trigger the missing event on the live site. (B) TRANSIENT / retry with budget (3 × 30s, then graceful exit): - `not_ready_reason='no_events_after_install'` — loader hasn't reported yet (post-deploy delay or local-dev environment). Retry per `retry.retry_after_seconds` / `retry.max_retries_recommended`. On budget exhaustion, transition to the Turn 5 scored hand-off with `events haven't arrived yet — trigger a PageView on the site and reply 'verify'` instead of declaring failure. - `not_ready_reason='script_not_seen'` — bootstrap script not loaded. Same retry shape as above. - `not_ready_reason='event_not_received_yet'` — a specific expected_event hasn't arrived. Same retry shape. - `not_ready_reason='events_processing'` — initial-calculate race. Same retry shape; on exhaustion say `events are flowing; final scoring will catch up within a few minutes` and exit. (C) CODE-FIX / retry ONCE after fix (do not loop): - `not_ready_reason='missing_contact_info'` — `tlq('set','ContactInfo',...)` not seen. Apply the missing snippet (see `get_installation_scripts.framework_snippets.contact_info`), then call this tool ONCE more. If still missing, transition to scored hand-off; the next_steps list will name `implement_contact_info` as a remaining task. - `not_ready_reason='domain_mismatch'` — events arrived from the wrong host. Inspect deploy target, fix, retry ONCE. On failure, transition to scored hand-off. DATA FIELDS YOU MUST READ: - `data.event_names_seen[]` — distinct `track`-type events received (PageView, Purchase, Lead, ...). - `data.set_events_seen[]` — distinct `set`-type metadata received (ContactInfo, ...). Do NOT expect ContactInfo to appear in `event_names_seen`; it lives ONLY in `set_events_seen` because `tlq('set', 'ContactInfo', ...)` is metadata, not an event. - `data.verification.not_ready_reason` — stable enum, full list: `no_events_after_install`, `event_not_received_yet`, `script_not_seen`, `only_pageview_seen`, `missing_bottom_funnel_event`, `missing_contact_info`, `domain_mismatch`, `awaiting_connector_activation`, `awaiting_first_party_mode`, `events_processing`. Map verbatim to user-friendly copy via `verification.message`. IDEMPOTENCY: use the SAME `idempotency_key` to dedupe within a 30s window (returns the cached response). Use a FRESH `idempotency_key` after the window to trigger a new force-process pass over recent events.
get_next_stepsReturn scoring-driven ordered guidance for the agent. Non-mutating. Pass `recalculate=true` only when you explicitly want to force a fresh scoring pass (expensive). Every response includes `_request_id` in `structuredContent`.
get_onboarding_sessionReplayable onboarding transcript. Use the JWT when the session has a user; use the pre-auth `_sensitive_onboarding_session_token` from scout when the session is pre-auth. Every response includes `_request_id` in `structuredContent`.
create_login_linkCreate a one-time dashboard handoff URL after AI setup. The login URL contains a single-use token. Do not write it to disk or echo it back. Pass it directly to the user. Returns `login_link_consume_disabled` (HTTP 503) when the feature flag is off — in that case, ask the user to log in manually. Every response includes `_request_id` in `structuredContent`. DO NOT use this tool to answer analytics or stats questions. It is a single-use dashboard handoff URL for post-install navigation only. For data questions, call the analytics tools directly (`get_summary` / `get_report` / `list_containers` / etc.); the MCP host will automatically open an OAuth dialog inline if the user has not authenticated yet, and will retry the call once authentication completes.
Tracklution: connect to Claude, ChatGPT, Cursor · Connectors.fun