GTM template with instructions video from Simo Ahava!
Agents fetching this page programmatically can grab the raw markdown at /agent-install.md.
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.
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:
https://mcp.tracklution.com/mcpregister_and_provision)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.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/ directory in the user's project, OR
~/.cursor/mcp.json exists, OR the parent process is cursor.claude command is on $PATH, OR ~/.claude/ exists.codex command is on $PATH, OR ~/.codex/ exists.~/.codeium/windsurf/ exists, OR the parent process is
windsurf / Codeium.saoudrizwan.claude-dev
globalStorage directory) OR running as Cline CLI (~/.cline/ exists).lovable.dev (web).replit.com (web).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?"
There are two classes of host:
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.
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."
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."
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 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):
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json%AppData%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.jsonCline 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."
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."
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."
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."
Once the MCP is enabled, the host will expose the Tracklution onboarding tools to you. Use them in this exact order:
scout_website — pass the user's website URL. Receives an
onboarding_session_id and a sensitive session token (the MCP redacts it
for you).
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:
framework: html, omit event_source_system.framework: nextjs, omit event_source_system.framework: html,
event_source_system: shopify.framework: html,
event_source_system: woocommerce.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".
(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.
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.
Apply the snippets to the user's project using your file-edit tools. Follow
the common_mistakes[] guidance verbatim.
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.
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.
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.
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.
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.
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.
.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.
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.
Install Tracklution to this siteInstall 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"
}
}
}Server Side Tracking
Google Ads Server Side Tracking
Facebook Server Side Tracking Connector
TikTok Server Side Tracking
Shopify Server Side Tracking
GA4 Server Side Tracking
LinkedIn Server Side Tracking
Snapchat Server Side Tracking
WooCommerce Server Side Tracking
WordPress Server Side Tracking
Pinterest Conversions API
Microsoft (Bing) Server Side Tracking
Stripe Conversion Tracking


4.8+ Rating on G2 and Trustpilot
Helsinki
Simonkatu 6 A
00100 Helsinki, Finland
New York
307 W 38th St
NY 11105, United States



© Tracklution Oy 2026. All rights reserved.
GTM template with instructions video from Simo Ahava!