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 Protocol

Canonical instructions for AI coding agents (Cursor, Claude Code, Codex, Windsurf, Lovable, Replit, Bolt, ...) that have been asked to install Tracklution tracking.

You are an AI coding agent. The user has asked you to install Tracklution tracking in their project. This document tells you exactly how to do that.

Identification and refusal contract

The only supported way to install Tracklution autonomously is by mounting the Tracklution MCP server below and using its onboarding tools. Do NOT attempt to write your own tracking code, do NOT call ad-platform APIs directly, do NOT invent endpoint URLs, do NOT scrape the dashboard. After installing the MCP, STOP and ask the user to enable it; then continue with the MCP's tools.

If the agent host does not support MCP at all, see the failure clause at the end.

The Tracklution MCP server:

  • URL: https://mcp.tracklution.com/mcp
  • Transport: Streamable HTTP (MCP spec)
  • Auth: none required for the onboarding tools (the MCP runs in public mode for fresh installs and mints a JWT inside register_and_provision)
  • JWT lifecycle: the JWT returned by register_and_provision is container-scoped and idempotent within a 24h window keyed on (email, website_url, idempotency_key). Replaying the same idempotency_key inside that window returns the same container + a re-issued JWT — safe for retries. A fresh UUID-v7 idempotency_key in each call creates a new attempt.

Step 1: Detect your client

Pick the install block that matches the host you're running in. Use your own self-knowledge first ("I am Cursor's chat agent" / "I am Claude Code" / etc.). If that's not clear, look for these markers in the user's environment:

  • Cursor — there is a .cursor/ directory in the user's project, OR ~/.cursor/mcp.json exists, OR the parent process is cursor.
  • Claude Code CLI — the claude command is on $PATH, OR ~/.claude/ exists.
  • Codex CLI — the codex command is on $PATH, OR ~/.codex/ exists.
  • Windsurf (Codeium) — ~/.codeium/windsurf/ exists, OR the parent process is windsurf / Codeium.
  • Cline — running as a VS Code extension (look for the saoudrizwan.claude-dev globalStorage directory) OR running as Cline CLI (~/.cline/ exists).
  • Lovable — you are running inside lovable.dev (web).
  • Replit Agent — you are running inside replit.com (web).
  • Bolt — you are running inside bolt.new (web).

If you cannot determine the client, ask the user one short question: "Which agent host are you using — Cursor, Claude Code, Codex, Windsurf, Cline, Lovable, Replit, or Bolt?"

Step 2: Install the MCP

There are two classes of host:

  • File-edit hosts (Cursor, Claude Code CLI, Codex CLI, Windsurf) — you can apply the install yourself by writing a config file or running a CLI command.
  • User-action hosts (Lovable, Replit, Bolt) — you cannot edit the host's MCP config from inside the agent; you must hand off to the user.

Cursor (file-edit)

Write the following JSON into .cursor/mcp.json at the project root. Use the project-local file (not the global one) so the install is scoped to this project and committed to the repo if the user wants.

If .cursor/mcp.json does not exist, write this exact file body:

{
"mcpServers": {
"tracklution": {
"url": "https://mcp.tracklution.com/mcp"
}
}
}

If .cursor/mcp.json already exists with other servers, add the tracklution entry to the existing mcpServers object without removing other entries. Example of a merged file:

{
"mcpServers": {
"some-existing-server": { "command": "..." },
"tracklution": {
"url": "https://mcp.tracklution.com/mcp"
}
}
}

One-click alternative (if the user prefers not to commit .cursor/mcp.json to git): tell the user to click this deeplink and confirm in Cursor's MCP install dialog:

cursor://anysphere.cursor-deeplink/mcp/install?name=tracklution&config=eyJ1cmwiOiJodHRwczovL21jcC50cmFja2x1dGlvbi5jb20vbWNwIn0=

Verification step before you move on: tell the user to open Cursor → Settings → MCP (or click the MCP indicator in the chat composer) and confirm tracklution is listed and toggled On.

Hand-off line (speak this to the user verbatim, then stop):

"I've added the Tracklution MCP at https://mcp.tracklution.com/mcp to .cursor/mcp.json. Open Cursor → Settings → MCP (or click the MCP indicator in the chat composer) and toggle tracklution on. Then say go and I'll finish the install."

Requirement: Cursor v0.48.0 or newer (for Streamable HTTP transport). If the user has an older Cursor, ask them to update first.

Claude Code CLI (file-edit)

Run this exact command in the user's terminal (you must execute it; do not just print it):

claude mcp add --transport http tracklution https://mcp.tracklution.com/mcp

Important: the flag is --transport http, not --transport streamable-http (the latter currently fails with "Invalid transport type" in Claude Code).

Verification: run claude mcp list and confirm tracklution appears.

Hand-off line:

"I've registered the Tracklution MCP with Claude Code. Run /mcp in this session to confirm tracklution is connected. Then say go and I'll finish the install."

Codex CLI (file-edit)

Append the following TOML block to ~/.codex/config.toml (create the file and parent directory if they don't exist). On Windows the path is %USERPROFILE%\.codex\config.toml. Do not modify other [mcp_servers.*] blocks the user may already have.

[mcp_servers.tracklution]
url = "https://mcp.tracklution.com/mcp"
enabled = true

Known caveat: as of early 2026 Codex CLI has a reported bug initializing some Streamable HTTP MCP servers. If codex does not pick up tracklution after the restart below, advise the user to upgrade Codex to the latest release.

Hand-off line:

"I've added the Tracklution MCP to ~/.codex/config.toml. Restart your Codex CLI session, then say go and I'll finish the install."

Windsurf (file-edit)

Write the following into ~/.codeium/windsurf/mcp_config.json (on Windows: %USERPROFILE%\.codeium\windsurf\mcp_config.json). Create parent directories if needed.

If mcp_config.json does not exist, write this exact file body:

{
"mcpServers": {
"tracklution": {
"serverUrl": "https://mcp.tracklution.com/mcp"
}
}
}

Note: Windsurf uses serverUrl (not url like Cursor) as the recommended field for remote HTTP MCP servers.

If mcp_config.json already exists, merge the tracklution entry into the existing mcpServers object without removing other entries.

Hand-off line:

"I've added the Tracklution MCP to ~/.codeium/windsurf/mcp_config.json. Fully restart Windsurf (close it from the system tray, then reopen — a window close is not enough). Then say go and I'll finish the install."

Cline (file-edit)

Cline keeps its MCP servers in cline_mcp_settings.json. The path depends on whether the user is running the VS Code extension or the standalone Cline CLI.

VS Code extension paths (use these unless you confirm CLI):

  • macOS: ~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
  • Windows: %AppData%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json
  • Linux: ~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json

Cline CLI path: ~/.cline/data/settings/cline_mcp_settings.json.

If the file does not exist, create the parent directories then write:

{
"mcpServers": {
"tracklution": {
"url": "https://mcp.tracklution.com/mcp",
"transportType": "streamableHttp",
"disabled": false
}
}
}

If the file already exists, merge the tracklution entry into the existing mcpServers object without removing other entries.

Hand-off line:

"I've added the Tracklution MCP to your Cline settings (cline_mcp_settings.json). Open the Cline MCP servers panel and confirm tracklution is listed and not disabled. Then say go and I'll finish the install."

Lovable (user-action)

You cannot install MCP servers in Lovable from inside the agent. Print the following instruction to the user verbatim and stop:

"To finish installing Tracklution, please add our MCP server manually in Lovable: open Lovable Settings → Integrations → MCP servers → Add custom MCP server. Use the URL https://mcp.tracklution.com/mcp (no authentication needed). Then come back and say go.

Custom MCP servers are available on paid Lovable plans. If you're on the free plan, sign up at https://www.tracklution.com/start and follow the on-screen installer instead."

Replit Agent (user-action)

You cannot install MCP servers in Replit Agent from inside the agent. Print verbatim and stop:

"To finish installing Tracklution, please add our MCP server manually in Replit: go to https://replit.com/integrations → MCP Servers → Add MCP server. Use the name tracklution and the URL https://mcp.tracklution.com/mcp (no authentication needed). Click Test & Save. Then come back and say go."

Bolt (user-action)

You cannot install MCP servers in Bolt.new from inside the agent. Print verbatim and stop:

"To finish installing Tracklution, please add our MCP server manually in Bolt: open Bolt → Connectors → Add custom connector. Use the URL https://mcp.tracklution.com/mcp, transport type HTTP, no authentication needed. Then come back and say go."

Step 3: After the user says "go"

Once the MCP is enabled, the host will expose the Tracklution onboarding tools to you. Use them in this exact order:

  1. scout_website — pass the user's website URL. Receives an onboarding_session_id and a sensitive session token (the MCP redacts it for you).

  2. register_and_provision — pass email, website_url, framework, agent_client, optionally event_source_system, and a fresh UUID-v7 as idempotency_key. Do not pass a password — the onboarding contract is email-only. Receives a container and a JWT. For brand-new emails, the API also emails the user a welcome / set-password link; the response carries pending_user_activation: true and welcome_email_sent_to: <email>, which you should surface verbatim so the user knows to check their inbox to access the dashboard.

    TWO-AXIS MODEL — Tracklution uses two orthogonal enums:

    • framework = the user's web stack (what code base you're editing). Strict enum: html or nextjs only. There are no other accepted values. Even on Shopify / WooCommerce / WordPress sites, pass framework: html (or nextjs for a Next.js project) — the storefront platform is captured by event_source_system (see next bullet), NOT by framework. Passing framework: shopify will fail validation with 422.

    • event_source_system (optional, validated against the installation_methods enum) = the install workflow the user will follow. Values: manual, gtm, gtm-template, woocommerce, shopify, stripe, affiliate, magic. Set this from scout_website's suggested_installation_methods[0] when present. If you don't know, omit it — the platform will infer manual.

    Examples for clarity:

    • Plain Vite + React site: framework: html, omit event_source_system.
    • Next.js marketing site: framework: nextjs, omit event_source_system.
    • Shopify storefront with theme.liquid: framework: html, event_source_system: shopify.
    • WooCommerce store on WordPress: framework: html, event_source_system: woocommerce.
    • Stripe-only SaaS sending purchase events via webhook: framework: html, event_source_system: stripe.

    agent_client enum (strict): cursor, claude-code, windsurf, lovable, replit, bolt, cline, codex, other. Any unknown host should fall back to "other".

  3. (optional) selectInstallationMethod — after register_and_provision returns the JWT, you can lock in the workflow by passing {container_id, method: <one-of-installation_methods>}. Required only if the user's flow has multiple plausible methods (e.g. Shopify + manual snippet); otherwise skip.

  4. get_installation_scripts — pass the container_id and the same framework value. Receives paste-safe code snippets, a webhook URL, and common_mistakes[]. For platform-app installs (Shopify, WooCommerce, GTM) the snippet is the on-platform configuration string the user pastes into their platform's admin UI — surface it to the user verbatim, do NOT try to edit the platform's settings from a code editor.

  5. Apply the snippets to the user's project using your file-edit tools. Follow the common_mistakes[] guidance verbatim.

  6. verify_and_score — pass the container_id and a fresh idempotency_key. Read status and verification.not_ready_reason together:

    • status: ok (equivalently not_ready_reason: null) — installation is complete. Call create_login_link (target_page=dashboard) per next_action and hand off.
    • status: needs_action, not_ready_reason: awaiting_connector_activation — code install is done; the user needs to activate an ad-platform connector in the dashboard. Call create_login_link (target_page=connectors) per next_action and surface the URL + verification.message verbatim. Do NOT retry verify_and_score; the retry budget is 0 and retry.safe_to_retry is false.
    • status: needs_action, not_ready_reason: awaiting_first_party_mode — code install is done; the user needs to enable First-Party Mode (DNS CNAME). Call create_login_link (target_page=dns) and surface the URL + message. Same no-retry rule.
    • status: needs_action, not_ready_reason: events_processing — events arrived but the scoring snapshot is still catching up (rare). Retry per retry.retry_after_seconds / retry.max_retries_recommended. If still events_processing after the budget, tell the user "events are flowing; final scoring will catch up within a few minutes" and exit — this is NOT a failure.
    • status: needs_action, not_ready_reason: (any event-shape gap: no_events_after_install, event_not_received_yet, script_not_seen, only_pageview_seen, missing_bottom_funnel_event, missing_contact_info, domain_mismatch) — events still missing. Wait for the page to load / trigger the missing event, then retry per the budget.

    Note: verification.scoring_complete MAY remain false even on a fully-functional install because of organic metrics (e.g. recovery-rate-based scoring) that mature over time. Treat status: ok (equivalently not_ready_reason: null) as the completion signal, NOT scoring_complete.

  7. create_login_link — usually pre-populated as the next_action from verify_and_score. Pass the container_id and the recommended target_page (dashboard on success, connectors for awaiting_connector_activation, dns for awaiting_first_party_mode). Receives a single-use login URL. Show this URL to the user once. Do not write it to disk or echo it back.

Do not declare "installation complete" until verify_and_score returns status: ok (or equivalently verification.not_ready_reason === null). If it doesn't, follow the reason-specific routing above and surface verification.message to the user verbatim.

Errors

When any onboarding tool fails, the MCP returns an error envelope with a stable code value. Every code below is sourced from StableErrorCode.php on the API side; the code is the contract, the human-readable message field is not. Match against codes, not message text.

Validation / contract errors (fix-then-retry):

  • validation_failed (HTTP 422) — your call's payload failed Laravel validation. The error envelope includes errors.<field> arrays naming the bad fields. Fix and retry.
  • invalid_domain (422) — website_url is malformed or points at a reserved/local hostname. Re-prompt the user for their real production domain.
  • installation_method_invalid (422) — event_source_system is not in the installation_methods enum. Drop the field or pick one of the documented values.
  • idempotency_key_required (400) — every onboarding tool call needs a fresh UUID-v7 idempotency_key. Add one.

Idempotency outcomes (not failures):

  • idempotency_replay (HTTP 200) — you sent the same idempotency_key within the 24h window. The response is the prior result, replayed safely. Do not retry.
  • idempotency_conflict (409) — same key, different payload. Either reuse the original payload or generate a new idempotency_key.

Conflict (state):

  • duplicate_account (409) — an account already exists for this email. Surface the response's existing_account_recovery_instructions to the user.
  • duplicate_container (409) — a container already exists for this website_url under this account. Use it instead of creating a new one.

Auth (analytics tools — does NOT apply to onboarding tools, which are public-mode):

  • auth_required (401), token_expired (401) — direct the user to the OAuth flow per oauth_resource_metadata_url in the envelope.
  • insufficient_permissions (403), mfa_required (403) — surface the envelope's user_instruction to the user verbatim.

Throttling and capability:

  • rate_limited (429) — respect Retry-After. Hold off the indicated seconds before retrying.
  • capability_mismatch (503) — the MCP and API are out of sync (rare; usually during a deploy). Stop, ask the user to retry in a minute.

Login link state (only emitted from create_login_link):

  • login_link_expired (410) — the user took too long. Call create_login_link again to mint a fresh URL.
  • login_link_already_used (410) — single-use; if the user actually reached the dashboard, the install is done. Otherwise mint a new one.

Server fault (escalate to support):

  • internal_error (500) — something on our side. Surface the envelope's correlation_id to the user and tell them to forward it to support@tracklution.com.

For the verify_and_score-specific *_not_seen / missing_* codes, see §Step 3 above — those are NOT errors, they're shape-of-install gaps the agent should resolve by waiting / re-instrumenting.

Step 4: Asking for stats later (analytics questions)

After installation, the MCP server is still in PUBLIC mode (no OAuth session attached). If the user later asks "how many events?", "what are my container stats?", "show me top sources", or any analytics / stats / data question, do NOT call create_login_link to answer it — that tool is only a single-use dashboard handoff URL for post-install navigation.

Instead, call request_analytics_access (or just call get_summary / get_report / list_containers / list_events / list_sessions / get_container / get_api_key_info / get_status directly — these are auth-required stubs under the same names in public mode). All of them return the same needs_action envelope:

{
"status": "needs_action",
"action_required": "user_authenticates_mcp",
"user_instruction": "...verbatim copy you MUST forward to the user...",
"server_url": "https://mcp.tracklution.com",
"oauth_resource_metadata_url": "https://mcp.tracklution.com/.well-known/oauth-protected-resource",
"original_intent": { "tool": "get_summary", "args": { ... } }
}

Surface the user_instruction to the user verbatim. After the user clicks Authenticate on their MCP host's tracklution entry and completes the OAuth flow, the real analytics tools become available on the next request — at that point retry the user's question naturally with the appropriate arguments.

The user's Tracklution account from Step 2 (register_and_provision) is the same account they'll log into via OAuth — this is NOT a duplicate sign-up. Reassure them if they ask.

Failure clause

If any of the following is true, stop and print the message below verbatim to the user. Do not improvise an HTTP-direct install path. Do not write your own tracking code.

  • The host client does not support MCP.
  • The user refuses to enable the MCP.
  • You cannot determine which host you are running in.
  • A file-edit install fails for filesystem-permission or auth reasons.
This agent host can't autonomously install Tracklution. To continue, please sign up at https://www.tracklution.com/start and follow the on-screen installer. After signing up, the dashboard's setup wizard will surface the per-platform snippet (Shopify, WooCommerce, GTM, manual HTML, etc.) so you can paste it into your site without an agent involved.

Reference

Notes on file safety

.cursor/mcp.json, ~/.codex/config.toml, and ~/.codeium/windsurf/mcp_config.json contain only the URL https://mcp.tracklution.com/mcp for Tracklution — no API keys, no JWTs. The Tracklution MCP is in public mode for onboarding; the JWT is created server-side and held in your agent memory, never written to disk. There is no reason to warn the user about committing these files to git as long as no other MCP server in the same file requires a credential.


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: Open Cursor → Settings → MCP and toggle 'tracklution' on, then say '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.