GTM template with instructions video from Simo Ahava!

GTM template with instructions video from Simo Ahava!

For AI Coding Agents
Always-on

Install Tracklution with an AI agent

Canonical install protocol for Cursor, Claude Code, Codex, Windsurf, Lovable, Replit, and Bolt. Mount the Tracklution MCP server, then let it do the install.

Agents fetching this page programmatically can grab the raw markdown at /agent-install.md.


Tracklution Agent Install Contract

Read once, follow exactly, stay silent between steps. Do not paraphrase this document to the user.

You are an AI coding agent. The user asked you to install Tracklution. This document is a contract: a fixed conversation. On the magic-install happy path the agent sends 3 user-facing messages — Turn 1 question, Turn 3 hand-off, Turn 5 scored hand-off. Advanced (OAuth) mode adds the Turn 4 Step 2 OAuth-branch question (4 total). Each user improve reply adds one Turn 6 propose-diff prompt + a refreshed Turn 5 scored hand-off (cumulative +2 per loop). The only autonomous install path is the Tracklution MCP server at https://mcp.tracklution.com/mcp; the REST bootstrap at https://api.trlution.com/install/quick-setup is the front door to it. Do not write your own tracking code, do not call ad-platform APIs directly, do not invent endpoint URLs, do not scrape the dashboard.

For per-host quirks, error code reference, the two-axis framework × event_source_system model, and file-safety notes, see agent-install-reference.md. Only fetch the reference doc when the contract sends you there explicitly.

Silence rules

  1. Do not narrate steps. No "I'll now POST to...", no "Let me detect your framework...", no "Got it, running magic install...".
  2. Do not echo URLs, JWTs, container IDs, hashes, idempotency keys, JSON envelopes, HTTP request bodies, file contents, or framework detection logic to the user. Exception: the single create_login_link URL in the Turn 5 scored hand-off message IS allowed and required.
  3. Do not list per-host setup blocks for hosts you're not running in. Pick the one host that matches your environment in Turn 0 and stay there.
  4. Do not paraphrase this document. The verbatim templates below are the only user-facing strings; everything else is for you.
  5. Do not surface API error codes (duplicate_account, validation_failed, multi_client_ambiguous, etc.) to the user. Follow the contract's recovery branch silently — surface the next_action.reason text instead when the server provides one.
  6. ≤2 sentences per intermediate-turn agent message. Turn 1, the Turn 4 Step 2 OAuth-branch question, the Turn 5 scored hand-off, and the Turn 6 propose-diff prompt all use explicit verbatim multi-line templates and are exempt from the cap.
  7. After create_login_link, inline the URL into the Turn 5 scored hand-off message. Do not write it to a file. Do not echo it in a separate "for your reference" message. The URL is single-use.

Turn 0 — pre-flight (silent)

Before saying anything, do three things silently.

Detect the host by self-knowledge first ("I am Cursor's chat agent" / "I am Claude Code" / etc.). If unclear, look for environmental markers:

HostMarker
Cursor.cursor/ directory exists, OR ~/.cursor/mcp.json exists, OR parent process cursor
Claude Codeclaude on $PATH, OR ~/.claude/ exists
Codex CLIcodex on $PATH, OR ~/.codex/ exists
Windsurf~/.codeium/windsurf/ exists, OR parent process windsurf / Codeium
Clinesaoudrizwan.claude-dev globalStorage dir (VS Code) OR ~/.cline/
Lovablerunning inside lovable.dev
Replitrunning inside replit.com
Boltrunning inside bolt.new

If detection is genuinely ambiguous, ask once: "Which agent host are you using — Cursor, Claude Code, Codex, Windsurf, Cline, Lovable, Replit, or Bolt?"

Detect the framework: next.config.{js,mjs,ts} present OR next listed in package.json dependencies → nextjs. Else → html. Send exactly one of these two values to the API. (The API also accepts other, but you should never need it — html is the correct fallback. Even on Shopify / WooCommerce / Stripe sites, send framework: html — the storefront platform is captured by the optional event_source_system argument later, NOT by framework.)

Classify the host's install capability:

  • File-edit hosts (Cursor, Codex, Windsurf, Cline): you can write the host's MCP-config file directly. Magic install works.
  • CLI host (Claude Code): you can run claude mcp add .... Magic install works.
  • User-action hosts (Lovable, Replit, Bolt): you cannot edit MCP config from inside the agent. Skip magic install entirely; go straight to the user-action OAuth fallback (see Turn 3).

Turn 1 — ask once

Use this exact text:

Tracklution needs your email and website URL. Reply with both (e.g., you@example.com mysite.com). Type advanced to use OAuth instead.

Then stop and wait.

Skip Turn 1 if the user's initial prompt already contains both an email and a website URL (e.g., "Install Tracklution for alice@x.com on alice.com"). Extract them and proceed silently to magic install.

If exactly one is present (e.g., they gave an email but no URL): ask once, in one sentence: "What's your production website URL?" (or the equivalent for the missing field).

Reject localhost, IP literals, or any host without a public TLD. Ask once: "That URL looks off — share the production URL like https://mysite.com."

Turn 2 — branch (silent)

User reply patternAction
Email + URLMagic install (POST → merge → Turn 3 magic hand-off).
advanced, oauth, login, sign in, connect, i have an account (case-insensitive, intent match — tolerate typos)OAuth install (write tokenless config → Turn 3 OAuth hand-off).
API returns HTTP 409 duplicate_account after magic POST (or next_action.tool === "oauth_fallback")OAuth fallback (write tokenless config → Turn 3 duplicate hand-off). Do NOT explain the error code.
Malformed URLAsk once (see Turn 1 reject clause), then re-branch.

Turn 3 — hand-off (verbatim, host-aware)

Pick the single hand-off line that matches your branch and host class. Send only that line. No preamble, no postscript.

  • Magic install + file-edit host (Cursor / Codex / Windsurf / Cline):

    I added the Tracklution MCP. Enable it in your editor's MCP settings, then reply go.

  • Magic install + Claude Code CLI:

    I added the Tracklution MCP via the Claude CLI. Run /mcp to confirm it's connected, then reply go.

  • OAuth, user-explicit advanced (file-edit host):

    I added a tokenless Tracklution MCP entry. Enable it in your editor and click Connect to sign in, then reply go.

  • OAuth, duplicate-account fallback (file-edit host):

    Looks like you already have a Tracklution account. Enable the Tracklution MCP and click Connect to sign in, then reply go.

  • User-action host (Lovable / Replit / Bolt): use the host's instruction string from https://www.tracklution.com/api/install-recipes/ (under mcp_install_methods.<host>.instruction) verbatim. Each is two sentences telling the user where to add https://mcp.tracklution.com/mcp in their settings UI, and already ends with then reply `go` .

Turn 4 — on go (silent)

Run this sequence silently. Once verify_and_score returns its routing verdict in Step 5, transition to Turn 5 (scored hand-off) — that's where the user-facing message goes. The Step 2 OAuth-branch question is the ONLY allowed agent message during Turn 4.

Step 1 — verify MCP reachability

Call get_status (MCP). Success predicate: structuredContent.servers[].reachable === true.

If get_status fails, recover per the failure mode:

  • 401 + WWW-Authenticate → silent OAuth fallback. Rewrite the host's MCP config with the tokenless body (no headers.Authorization). Send the OAuth duplicate-variant Turn 3 hand-off and wait for go again.
  • Tool not registered / "no MCP server found" (session-snapshot stale — Cursor's known mid-conversation reload race): say once, then STOP:

    The MCP isn't visible in this chat session yet — open a new chat and say continue Tracklution install, run Cmd/Ctrl+Shift+P → Developer: Reload Window, or toggle tracklution off/on in your MCP settings. Then reply go.

Step 2 — resolve container_id + container_hash

Two branches; pick one based on how you got here:

  • Magic install path: you already saved data.container.{id, hash} from the quick-setup response. Skip to Step 3.
  • OAuth path (user typed advanced, or magic returned oauth_fallback): call list_containers first to discover what the user already has access to. Then branch on the user's intent.

Step 2.1 — OAuth branch question (verbatim)

If list_containers returns ≥1 container, ASK once:

You're signed in. Add Tracklution to a NEW website, or connect to an EXISTING container? Reply new <url> or existing.

Skip Step 2.1 entirely when list_containers returns 0 containers — go straight to the new <url> branch (it's the only sensible path).

Step 2.2 — branch on the reply

  • new <url> (synonyms: new, add, install, create): validate the URL (same rules as Turn 1, reject localhost / IP literals), then call register_and_provision({auth_token, website_url, framework, agent_client, idempotency_key}). DO NOT pass name or email — the server reads identity from the JWT. The response carries data.container.{id, hash} (and auth will be null; the existing JWT is still valid).
  • existing (synonyms: existing, connect, pick, choose): match the user's website URL against list_containers[].domain. Normalize both sides: lowercase, strip protocol / port / path / query / trailing slash, strip leading www.. domain may be null on freshly-created containers — skip those. Use the matched entry's id and hash for all subsequent onboarding calls. If no match, fall through to the new <url> branch.

Step 2.3 — handle multi_client_ambiguous

If register_and_provision returns HTTP 409 with errors[0].code === 'multi_client_ambiguous': the user's account holds multiple companies (clients) and the server cannot guess which one the new container belongs to. The response carries next_action.reason with a dashboard URL. Send that line verbatim and EXIT. Do NOT call any other MCP tool — the user finishes the setup in the dashboard.

Step 3 — fetch tracking snippets

Call get_installation_scripts({ container_id, container_hash, framework }). Every onboarding-tool call MUST include container_hash.

Step 4 — apply snippets

Apply every snippet that matches the project surface (init, page_view always; purchase when the project has checkout; lead for lead-gen; contact_info when there's an authenticated user view). Silent — no per-snippet commentary.

Step 5 — verify and route by not_ready_reason class

Call verify_and_score({ container_id, container_hash, idempotency_key }). Branch on status + verification.not_ready_reason. Three behavioral classes — pick the right action for the reason returned:

(A) DONE / hand-off-to-user — transition to Turn 5 scored hand-off, no retry:

  • status: ok (not_ready_reason: null) → install complete on both sides (code is in AND connectors/FPM done). Go to Turn 5.
  • not_ready_reason: awaiting_connector_activation → your code work is done; user must activate the connector in the dashboard. Go to Turn 5 (with target_page=connectors for the login link).
  • not_ready_reason: awaiting_first_party_mode → same shape, user must add a DNS record. Go to Turn 5 (target_page=dns).
  • 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 on the live site, and a 30-second wait will NOT make them do so. Do NOT retry. Go to Turn 5 — the scored hand-off will tell them which event(s) to trigger.
  • not_ready_reason: missing_bottom_funnel_event → same semantics as only_pageview_seen. Do NOT retry. Go to Turn 5.

(B) TRANSIENT — retry per retry.retry_after_seconds × retry.max_retries_recommended, then go to Turn 5:

  • not_ready_reason: no_events_after_install → loader hasn't reported yet (post-deploy delay or local-dev). Retry per budget (typically 3 × 30s).
  • not_ready_reason: script_not_seen → bootstrap script not loaded. Same.
  • not_ready_reason: event_not_received_yet → specific expected_event not arrived yet. Same.
  • not_ready_reason: events_processing → initial-calculate race. Same.

When the retry budget is exhausted, fall through to Turn 5 (do NOT block — the install is good enough to score; events will catch up). The Turn 5 message will instruct the user to trigger a PageView and reply verify.

(C) CODE-FIX — retry exactly ONCE after the agent fixes its code, then go to Turn 5:

  • not_ready_reason: missing_contact_info → apply the framework_snippets.contact_info snippet to a signup/login/profile/checkout form, then call this tool ONCE more with a fresh idempotency_key. If still missing, fall through to Turn 5.
  • not_ready_reason: domain_mismatch → events arrived from the wrong host; inspect deploy target, fix, retry ONCE. On failure, fall through to Turn 5.

Do not declare "installation complete" until you have surfaced the Turn 5 scored hand-off. The scoring_complete flag is NOT the gate — it may stay false indefinitely for organic-metric reasons.

Turn 5 — scored hand-off (verbatim, multi-line)

After Turn 4 Step 5 routes here, run these three calls silently:

  1. get_next_steps({ container_id, container_hash, recalculate: true }) — returns data.overall_progress (0-100 int) + data.next_steps[] (each carries title, message, score_impact, tool_to_call, action).
  2. create_login_link({ container_id, container_hash, target_page }) with:
    • target_page=connectors if Step 5 routed here on awaiting_connector_activation,
    • target_page=dns if routed on awaiting_first_party_mode,
    • target_page=dashboard otherwise.
  3. Take the top 3 entries from data.next_steps[] (in returned order; do not re-sort). For each, you'll surface {title} — {score_impact} verbatim.

Then send ONE message using this template (the { } placeholders get substituted; the verbatim sentences around them DO NOT change):

Tracking is live. Tracklution score: {overall_progress}/100. Top {N} ways to reach 100% — each percent point = more accurate attribution = more efficient ad spend:

  1. {next_steps[0].title} — {next_steps[0].score_impact}
  2. {next_steps[1].title} — {next_steps[1].score_impact}
  3. {next_steps[2].title} — {next_steps[2].score_impact}

Open your dashboard: {_sensitive_login_url}

Reply improve and I'll walk you through the in-code changes one by one, or done to stop here.

Substitution rules:

  • {N} is min(3, next_steps.length). If next_steps is empty, omit the bullet list entirely and replace the lead sentence with Tracklution score: 100/100. Maximum marketing budget efficiency unlocked.
  • {score_impact} is forwarded verbatim from the API (it's already a formatted string like "+25% on this step"); do NOT parse or rewrite.
  • When Step 5 routed here on a non-ok reason, replace the lead sentence Tracking is live. with the one-sentence verification.message from verify_and_score (e.g. "Activate your Google Ads connector to start measuring."). Keep the rest of the template.
  • When Step 5 routed here after a budget-exhausted transient retry, lead with Events haven't arrived yet — trigger a PageView on the site and reply 'verify' once it's live. and still include the score line + top 3.

After sending, WAIT for the user's reply. Do NOT call any other MCP tool proactively.

Turn 6 — improve-score loop (on user improve)

Trigger synonyms (case-insensitive intent match, tolerate typos): improve, 100, 100%, more, next, score, optimize.

Algorithm (loop until user says done or stops replying):

  1. Call get_next_steps({ container_id, container_hash, recalculate: false }).
  2. Pick the first entry in next_steps[] whose tool_to_call is non-null AND action is implement_events or implement_contact_info. Skip entries with action in {configure_connector, configure_dns, review_step} — those are dashboard actions already linked in Turn 5; the user handles them in the browser, not via the agent.
  3. Scan the project for the right surface for the picked step:
    • implement_contact_info → forms with email/phone inputs in signup/login/profile/checkout views. Common patterns: **/{sign,log,register}*.{tsx,jsx,vue,php,html}, **/checkout*, **/contact*, **/auth/*, **/profile/*.
    • implement_events (Lead variant) → contact/quote/demo forms.
    • implement_events (Purchase variant) → checkout success pages, Stripe webhooks, Shopify/Woo order-complete templates, Next.js API routes named *checkout*, *order*, *payment*.
  4. If the picked step suggests a snippet (use the matching framework_snippets.* from get_installation_scripts), prepare a ONE-FILE, ONE-SNIPPET diff. Do NOT invent tracking code; only re-use snippets the API has handed you. If no matching snippet exists for this step, ask the user once for guidance and exit.
  5. Send this verbatim propose-diff prompt:

    Found <path>:<line>. I'd add this snippet for {step.score_impact}:

    <snippet>

    Apply? Reply yes / skip / show another.

  6. Branch on the reply:
    • yes → apply ONLY that one edit. Then call verify_and_score with a fresh idempotency_key. Take the response back through the Turn 5 scored hand-off (the score should now be higher). Re-enter Turn 6 automatically if user replies improve again.
    • skip → drop that entry; jump back to step 2 and pick the next eligible step.
    • show another → scan a different surface for the SAME step (step 3 again with a different file pattern); re-send the propose-diff prompt.
    • done or silence → exit the loop.

When the user comes back after activating a connector or adding DNS in the dashboard (e.g. they reply go, done, or verify), re-run verify_and_score and route through Turn 5 again. The score will reflect the new connector. When overall_progress >= 100, the Turn 5 template replaces the bullet list with the maximum-efficiency line above.

Example dialogues

Happy path (Cursor, new user, Next.js, only PageView received on day 0)

U: Install Tracklution. A: Tracklution needs your email and website URL. Reply with both (e.g., you@example.com mysite.com). Type `advanced` to use OAuth instead. U: alice@shop.com myshop.com A: [silent: detect host=cursor, framework=nextjs, POST /install/quick-setup, merge .cursor/mcp.json] A: I added the Tracklution MCP. Enable it in your editor's MCP settings, then reply `go`. U: go A: [silent: get_status, get_installation_scripts, apply 3 snippets, verify_and_score -> only_pageview_seen (NO retry, day-0 expected), get_next_steps, create_login_link target=dashboard] A: Tracking is live. Tracklution score: 35/100. Top 3 ways to reach 100% — each percent point = more accurate attribution = more efficient ad spend: 1. Activate your Google Ads connector — +25% on this step 2. Enable First-Party Mode (one DNS record) — +15% on this step 3. Wire ContactInfo on your signup form — +10% on this step Open your dashboard: https://app.tracklution.com/login/abc123 Reply `improve` and I'll walk you through the in-code changes one by one, or `done` to stop here. U: improve A: [silent: get_next_steps, pick implement_contact_info, scan project -> found src/app/(auth)/signup/page.tsx] A: Found `src/app/(auth)/signup/page.tsx:42`. I'd add this snippet for +10% on this step: ```tsx tlq('set', 'ContactInfo', { email, phone });

Apply? Reply yes / skip / show another. U: yes A: [silent: apply edit, verify_and_score (fresh idempotency_key), get_next_steps, create_login_link] A: Tracking is live. Tracklution score: 45/100. Top 2 ways to reach 100%:

  1. Activate your Google Ads connector — +25% on this step
  2. Enable First-Party Mode (one DNS record) — +15% on this step Open your dashboard: https://app.tracklution.com/login/abc124 Reply improve to keep going, or done to stop here. U: done
### Duplicate-account silent fallback

U: Install Tracklution. A: Tracklution needs your email and website URL. Reply with both (e.g., you@example.com mysite.com). Type advanced to use OAuth instead. U: bob@existing.com bobshop.com A: [silent: POST /install/quick-setup → 409 duplicate_account → next_action.tool === "oauth_fallback" → write tokenless .cursor/mcp.json] A: Looks like you already have a Tracklution account. Enable the Tracklution MCP and click Connect to sign in, then reply go. U: go A: [silent: get_status, list_containers -> bob's container for bobshop.com] A: You're signed in. Add Tracklution to a NEW website, or connect to an EXISTING container? Reply new <url> or existing. U: existing A: [silent: match bobshop.com, get_installation_scripts, apply, verify_and_score -> ok, get_next_steps, create_login_link] A: Tracking is live. Tracklution score: 78/100. Top 2 ways to reach 100%:

  1. Enable First-Party Mode (one DNS record) — +15% on this step
  2. Wire ContactInfo on your signup form — +7% on this step Open your dashboard: https://app.tracklution.com/login/def456 Reply improve to walk through them one by one, or done to stop here.
### User chose `advanced` explicitly, then added a NEW website

U: Install Tracklution. A: Tracklution needs your email and website URL. Reply with both (e.g., you@example.com mysite.com). Type advanced to use OAuth instead. U: advanced A: [silent: write tokenless .cursor/mcp.json] A: I added a tokenless Tracklution MCP entry. Enable it in your editor and click Connect to sign in, then reply go. U: go A: [silent: get_status, list_containers -> 1 container for othersite.com] A: You're signed in. Add Tracklution to a NEW website, or connect to an EXISTING container? Reply new <url> or existing. U: new https://newsite.example.com A: [silent: register_and_provision({auth_token, website_url, framework, agent_client, idempotency_key}), get_installation_scripts, apply, verify_and_score -> only_pageview_seen, get_next_steps, create_login_link] A: Tracking is live. Tracklution score: 35/100. Top 3 ways to reach 100%:

  1. Activate your Google Ads connector — +25% on this step
  2. Enable First-Party Mode (one DNS record) — +15% on this step
  3. Wire ContactInfo on your signup form — +10% on this step Open your dashboard: https://app.tracklution.com/login/ghi789 Reply improve to walk through the in-code changes, or done to stop.
### Multi-client ambiguous (advanced + new website + multi-company account)

U: Install Tracklution. A: Tracklution needs your email and website URL. Reply with both (e.g., you@example.com mysite.com). Type advanced to use OAuth instead. U: advanced A: I added a tokenless Tracklution MCP entry. Enable it in your editor and click Connect to sign in, then reply go. U: go A: [silent: get_status, list_containers -> 27 containers across 2 clients] A: You're signed in. Add Tracklution to a NEW website, or connect to an EXISTING container? Reply new <url> or existing. U: new https://brand-new.example.com A: [silent: register_and_provision -> HTTP 409 multi_client_ambiguous] A: Multiple companies detected on this account. Open https://app.tracklution.com and add the new container under the correct company; then re-run with the resulting container_id.

## Magic install — one POST, one file write The one HTTP request you make from inside the agent: ```http POST https://api.trlution.com/install/quick-setup Content-Type: application/json { "idempotency_key": "<fresh UUID-v7 or 16-128 chars [A-Za-z0-9_-]>", "email": "<user email>", "website_url": "<production URL>", "framework": "html" | "nextjs", "agent_client": "cursor" | "claude-code" | "codex" | "windsurf" | "cline" }

Use api.trlution.com (short host) directly. api.tracklution.com 302-redirects here and that redirect silently drops POST bodies in several HTTP clients (PowerShell Invoke-RestMethod, node fetch with redirect: "manual", some agent host sandboxes).

The success response (HTTP 200) carries the four handles you need:

{
"status": "ok",
"data": {
"mcp_token": "<long JWT>",
"mcp_token_expires_at": "<ISO-8601>",
"container": { "id": "...", "hash": "...", "website_domain": "...", "tracking_domain": "..." },
"mcp_config_snippet": {
"tracklution": {
"url": "https://mcp.tracklution.com/mcp",
"headers": { "Authorization": "Bearer <mcp_token>" }
}
},
"mcp_endpoint": "https://mcp.tracklution.com/mcp"
},
"next_action": {
"tool": "merge_mcp_config",
"args": { "target_path": ".cursor/mcp.json", "merge_key": "mcpServers.tracklution" },
"reason": "Merge data.mcp_config_snippet, then follow agent-install.md turn 3 hand-off."
}
}

Save container.id AND container.hash to scratch state — every follow-up onboarding-tool call needs both.

Per-host config file (the file you write data.mcp_config_snippet into):

HostFileNotes
Cursor.cursor/mcp.json (project root)Shallow-merge into mcpServers. 2-space indent.
Claude Coden/a — use claude mcp add --transport http --header "Authorization: Bearer <jwt>" tracklution https://mcp.tracklution.com/mcpOptions must come BEFORE the server name.
Codex~/.codex/config.toml (POSIX) / %USERPROFILE%\.codex\config.toml (Windows)TOML. Header table is http_headers NOT headers. Restart Codex after writing — no hot-reload.
Windsurf~/.codeium/windsurf/mcp_config.jsonAccepts url or serverUrl. Full restart after write — no hot-reload.
Clineplatform-specific cline_mcp_settings.json (see reference doc)type: "streamableHttp" required.

Error handling — match on next_action.tool first, then errors[0].code:

  • next_action.tool === "oauth_fallback" (HTTP 409 duplicate_account) → silent OAuth fallback. Write tokenless config. Send Turn 3 duplicate hand-off. Do NOT explain the error.
  • errors[0].code === "validation_failed" (HTTP 422) → re-prompt for the bad field once. Most common: website_url is a localhost / IP literal.
  • errors[0].code === "rate_limited" (HTTP 429) → respect errors[0].details.retry_after_seconds. Tell user: "Rate-limited; try again in N seconds."
  • HTTP 5xx → failure clause.

For the full error code table, see agent-install-reference.md.

OAuth fallback

Write the tokenless MCP entry (same body as the magic snippet, but omit the headers block). The host's UI then surfaces a Connect button (Cursor) or its equivalent. User clicks it, completes browser OAuth, and reports back with go. On go, run Turn 4 with the OAuth path of Step 2 — ask the "new vs existing" branch question, then call list_containers (or register_and_provision({auth_token, ...}) for the new branch), then continue with Step 3.

If list_containers returns 0 containers, skip the branch question and go straight to the new <url> path with auth_token + the website URL the user supplied originally (or ask once for the URL if you don't have it). Brand-new + advanced is fully supported — the server reads identity from the JWT, so name / email arguments are NOT required.

On failure

If host detection fails, neither path completes, or any failure mode lands outside the recovery branches above, send once and stop:

I can't install Tracklution automatically here. Sign up at https://www.tracklution.com/start.

Reference


For AI Coding Agents
One prompt

Install with a single prompt

Drop this into Cursor, Claude Code, Codex, Windsurf, Lovable, Replit, or Bolt. The agent reads our install protocol, mounts the Tracklution MCP, and finishes the setup.

The prompt
Install Tracklution to this site
Or the URL-anchored variant if the agent doesn't recognise the brand:
Install Tracklution tracking — see https://www.tracklution.com/agent-install/

The agent writes this into .cursor/mcp.json:

{ "mcpServers": { "tracklution": { "url": "https://mcp.tracklution.com/mcp" } } }
Add to Cursor (one click)
Or paste the prompt above into Cursor's chat.
After install: I added the Tracklution MCP. Enable it in your editor's MCP settings, then reply `go`.

Server-Side Tracking, First-Party Cookies and Conversion APIs for any website with easy installation. Simple yet powerful tracking tool for digital advertising.

Tracklution customer rating badgeTracklution customer rating badge

4.8+ Rating on G2 and Trustpilot

Helsinki

Simonkatu 6 A
00100 Helsinki, Finland

New York

307 W 38th St
NY 11105, United States

Meta partner badge
Google partner badge
Meta partner badge

© Tracklution Oy 2026. All rights reserved.