Tag manager your AI agent sets up and tests
AgentFirstStack Tags is a tag manager an AI agent sets up and tests for you: one snippet, then pixels, click and form events, triggers, variables, versions with preview and rollback, and a consent banner with Google Consent Mode v2, all over an API and MCP. It's free and open source, and replaces Google Tag Manager (also free, but edited by people in its interface) and, on simple sites, a consent plugin such as CookieYes or Cookiebot. Keep GTM if your marketing team edits tags by hand or relies on its template gallery, and use a full consent platform if you show Google ads as a publisher or need IAB TCF. Your agent scans the site first, can import a GTM container, and checks every tag in a preview before it publishes.
Set it up with one prompt
Paste this into your coding agent. It maps the site and reads what's already there before it changes anything, so an existing GTM container or consent banner isn't overwritten blind.
Set up a tag manager for this project with AgentFirstStack Tags. It's a free, open-source tag manager built for agents (tags, triggers, variables, versions, a consent banner and server-side conversions), and you can do the setup yourself: there is no signup form. 1. Read https://agentfirststack.com/llms.txt and https://tags.agentfirststack.com/llms.txt. 2. If this project's .env already has AGENTFIRSTSTACK_API_KEY, use it and read AGENTFIRSTSTACK.md. Otherwise get a key: curl -X POST https://agentfirststack.com/v1/signup, and save api_key in .env as AGENTFIRSTSTACK_API_KEY and in the production secrets. 3. Map the site: its main pages, every main button, link and form, and what counts as a sign-up, lead or purchase here. Create a tags container for the production domain and serve it from the site's own domain: a first-party domain (POST https://agentfirststack.com/v1/first-party-domains with a neutral subdomain such as edge.<domain>; add its one CNAME if you can change the DNS, otherwise give me the record) or, until then, the path proxy from GET /v1/containers/:id/install?proxy=1 with the proxy key kept server-side. Put the snippet first in the head of every page, deploy, and run scan. 4. If the site loads Google Tag Manager, tell me what it fires before you change anything, then import it (draft/import with format "gtm", dry run first) and list what didn't map. 5. Run setup with analytics as a platform, plus the ad platforms this business uses, and one event per main action (a click, a form submit or a thank-you page), named in snake_case. Ask me only for the IDs and tokens setup reports as missing. 6. If the site has visitors from the EU, UK or Switzerland, fires ad pixels and has no consent banner of its own, turn on the container's consent banner with our privacy policy URL and add a "Cookie settings" link to the footer. If it already has a consent platform, keep it and tell me which one. 7. Turn on report_tag_fires, validate, open a preview on the main pages and read its log. If you imported GTM, ask me before you publish, then publish and remove GTM's snippet in the same change, or its tags fire twice. 8. Run the setup test, do its browser plan in a real browser, and run the setup check until the tags rows pass. 9. Write the container id and the env var name (never the key) in AGENTFIRSTSTACK.md, and create a claim link for me with POST https://agentfirststack.com/v1/claim-link. Tell me what you set up, which event fires on which element, what the preview log and the tests showed, what's waiting on me, and give me the claim link.
This is the tags part of the full setup. For analytics, tags, an inbox and replay together, use the full setup prompt.
What your agent does
- Gets a key with
POST https://agentfirststack.com/v1/signup, or reuses the one in.env. One key works for every service. - Creates the container with
POST https://tags.agentfirststack.com/v1/containers {"domain":"example.com"}(MCPtags_create_container) and puts its snippet first in the<head>, so the consent state is set before any other tag loads. - Serves it first-party. A first-party domain (
POST /v1/first-party-domains {"hostname":"edge.example.com"}, one CNAME tofp.agentfirststack.com, no server code) serves the container athttps://edge.example.com/_t/c/<container_id>.js, next to analytics at/_aand replay at/_r. Where the DNS can't change, a path proxy forwards/_t/*with the container's proxy key. Ad blockers block the third-party host, so the direct snippet is the last resort. - Scans the site with
POST /v1/containers/:id/scan(MCPtags_scan_site): the GTM containers, GA4 and Google Ads tags and ad pixels already on the pages, other analytics and replay tools, consent platforms such as Cookiebot, CookieYes or OneTrust, the CMS, every form and main button or link with a CSS selector, likely thank-you pages, and a suggested config. It reads the homepage plus up to 5 paths a call, and the container keeps what it found aslast_scan. - Imports Google Tag Manager if the site has it:
POST /v1/containers/:id/draft/importwithformat: "gtm"and the export file or the Tag Manager API's lists, dry run first. The report lists what mapped, what was adapted with a note, and what didn't map, with the reason and what to use instead. - Adds an event for each main action with
POST /v1/containers/:id/setup(MCPtags_setup_conversion_tracking): each one says how it happens on the site (a click selector, a form selector, a thank-you path or a dataLayer event), and setup writes the triggers, tags and variables into the draft and lists the IDs still missing. Single items can be edited one at a time withPUT /v1/containers/:id/draft/:kind/:key. - Turns on consent where it's needed: the built-in banner, or the site's own consent platform connected to the container.
- Checks, previews, publishes.
POST /draft/validatereturns errors and warnings with hints,GET /diffsays in plain words what publishing will change, andPOST /previewreturns a link that serves the draft on the real site. The preview log says why each tag fired or didn't, for examplepage_path "/pricing" fails starts_with "/thank-you"orwaits for consent: ad_storage. ThenPOST /publish, andPOST /rollback {"version": n}if anything goes wrong. - Tests and hands over. The setup test verifies the container on the live homepage and sends a test event through it, the browser plan clicks each main action as test traffic, the setup check confirms the rows below, and a claim link (
POST /v1/claim-link) lets you see the project in a dashboard with Google sign-in.
T=https://tags.agentfirststack.com
H="Authorization: Bearer $AGENTFIRSTSTACK_API_KEY"
J="content-type: application/json"
curl -s -X POST $T/v1/containers -H "$H" -H "$J" -d '{"domain":"example.com"}'
# snippet first in <head>, deploy, then:
curl -s -X POST $T/v1/containers/$C/scan -H "$H"
curl -s -X POST $T/v1/containers/$C/setup -H "$H" -H "$J" -d @setup.json
curl -s "$T/v1/containers/$C/diff" -H "$H"
curl -s -X POST $T/v1/containers/$C/preview -H "$H"
curl -s "$T/v1/containers/$C/preview/$TOKEN/log" -H "$H"
curl -s -X POST $T/v1/containers/$C/publish -H "$H" -H "$J" -d '{"note":"main actions"}'
The click and form events your agent adds
The scan returns each form with its selector and fields, and each main button or link with its label, kind (signup, purchase, contact, booking, download, outbound and so on) and a selector for a click trigger. Your agent turns the ones that matter into events, named in snake_case and sent to analytics, where each gets a goal:
{
"platforms": { "analytics": { "site_id": "site_..." } },
"conversions": [
{ "name": "sign_up_click", "when": { "click_selector": "a[href^='/signup']" } },
{ "name": "contact_submit", "kind": "contact", "when": { "form_selector": "form#contact" },
"email": { "selector": "input[type=email]" } },
{ "name": "copy_prompt", "when": { "click_selector": "button[data-copy-from]" } }
],
"consent": "banner"
}
Form triggers can wait for the site's own validation, so a submit the page rejected doesn't count, and link clicks can be held up to 2 seconds while the tags' scripts load. Purchases and sign-ups also go to the ad platforms, browser and server with one event id: that part is on the conversion tracking page.
What you get
- Workflow: a draft edited whole or one item at a time, guarded by revision so two edits never overwrite each other; diffs between any two versions; validation with a hint for each issue; preview links with a log of every tag decision; saved versions, publishing a saved version, and rollback; environments, a named snippet pinned to one version for a staging site.
- Triggers: page view, DOM ready, window loaded, init, consent initialization, history changes in single-page apps, clicks and link clicks, form submits, dataLayer events (exact name or regex), element visibility, scroll depth, timers, JavaScript errors, YouTube and HTML5 video, and trigger groups, with conditions such as equals, contains, starts with, regex, CSS selector match and number comparisons, and their negations.
- Variables: data layer keys, URL parts and query parameters, cookies, an element's text, value or attribute, JavaScript globals, constants, lookup and regex tables, formatting, and built-ins for the page, clicks, forms, scrolling, visibility, history, errors and video.
- Tags: GA4, Google Ads, Meta, TikTok, LinkedIn, Microsoft UET, Reddit, X, Pinterest, Snap, AgentFirstStack analytics, image pixels, and custom HTML and JavaScript, with priority, scheduling, sequencing (a setup tag first), once per page, live-only and consent types per tag.
- Custom code checks: custom HTML and JavaScript publish only on a verified domain in a claimed project, and code that looks like a crypto miner, a card skimmer, an obfuscated eval chain or a known malicious host is refused.
- Conversions: one event id shared by the browser pixel and the server-side copy for GA4, Google Ads, Meta, TikTok, LinkedIn, Pinterest, Reddit, Snap, X, analytics and webhooks, plus events your backend sends (conversion tracking).
- Consent: the built-in banner, Google Consent Mode v2 (basic or advanced), defaults by region, and the choices of an existing consent platform followed when it calls
gtag('consent', 'update', ...)or runs IAB TCF v2. Browsers that send Global Privacy Control or Do Not Track get no tags at all by default. - Monitoring: an event and delivery log, tag-fire counts (fired, waiting for consent, failed, never fired), the pages that actually load the container, and attack protection that keeps floods of fake hits away from your ad platforms.
- Browser API: a GTM-compatible
dataLayer.push(objects deep-merge,eventCallbackis honoured),afst()for events, consent and identity, and?afst_debug=1to log every decision in the console.
Consent banner and Consent Mode v2
One block in the draft turns on a consent banner. From then on the container's tags, Google Consent Mode v2, session replay and the analytics tracker (when it stores a visitor id) follow each visitor's choice:
curl -s -X PATCH $T/v1/containers/$C/draft -H "$H" -H "$J" \
-d '{"consent_banner":{"enabled":true,"privacy_url":"https://example.com/privacy"}}'
- It asks visitors from the EU, Iceland, Liechtenstein, Norway, the UK and Switzerland, and visitors whose country is unknown (
regions: "all"asks everyone). Until they choose, every category is denied. - "Reject all" looks exactly like "Accept all", the settings layer has one unticked box per category, and a "Cookie settings" link or a floating button reopens it so the choice can be changed.
- Each tag waits for its consent type (ad pixels for
ad_storage, GA4 foranalytics_storage) and fires the moment the choice grants it. The Consent Mode default is pushed before any Google tag, and every choice sends an update. - Each choice is kept for 12 months as a consent record: an anonymous consent id, the time, the banner version, the choice per category, the country and the container version that held the text. Never the IP address or the visitor id.
It isn't a full consent platform: it doesn't scan the site for cookies, doesn't block scripts loaded outside the container, and isn't an IAB TCF or Google-certified consent platform. The cookie consent banner guide covers what a banner has to do and when you still need one of those, and the Cookiebot alternative page compares the two directly.
What the setup check verifies
GET https://agentfirststack.com/v1/setup (MCP afs_check_setup) lists these rows for tags, per website, from what the service has seen:
| Check | Title | Passes when |
|---|---|---|
tags.container | There is a tag container for the website | A container exists for the domain |
tags.installed | The container snippet is on the pages | The snippet was found on the homepage, or browsers have sent hits |
tags.domain_verified | The container's domain is verified | Verify found the snippet on the homepage, or the DNS TXT record; custom HTML and JavaScript can't be published until then |
tags.published | A version is published | A version is live; until then browsers load an empty container |
tags.events | There is an event for each main action | The live version has events; the detail names them |
tags.to_analytics | The events reach analytics | Events are sent to analytics |
tags.goals_for_events | Each event sent to analytics has a goal there | Every event name sent to analytics has an event goal, so it counts as a conversion |
tags.firing | Every tag fires, and none fails | report_tag_fires is on, and in the last 7 days every enabled tag fired at least once and none failed |
tags.destinations | Conversions reach every ad platform | Shown when there are server-side destinations: none has failing deliveries |
tags.consent_banner | Visitors from the EU, UK and Switzerland are asked before ad pixels fire | Shown when the live version has ad pixels: the banner is on, an IAB TCF platform decides, or the pixels wait for consent there; a warning otherwise |
migrate.tools | What the site used before (other analytics and tag tools) is brought over | A GTM container the last scan found has been imported, and other analytics tools' history brought into analytics |
The setup test (POST /v1/setup/test) also verifies the container on the live homepage, sends one test event through the tag manager to analytics and each conversion to each ad platform in its test mode, and returns a browser plan that clicks each main action. afs_check_test_visit then confirms each expected event arrived and that none went to an ad platform as a real conversion.
Compared with
Facts about other products as of 7 November 2026, from their own pages.
| Tool | What it is and costs | Consent | Comparison |
|---|---|---|---|
| Google Tag Manager | Free: "Manage all your tags without editing code - for free", with vendor tag templates, a Community Template Gallery, preview and debug tools, and workspaces with granular access controls (Tag Manager) | Built-in and additional consent checks per tag; no banner of its own: Google recommends a consent management platform (consent mode support) | Google Tag Manager MCP compared |
| CookieYes | A consent management platform: free up to 5,000 pageviews a month, then $10, $25 or $55 a month per domain (pricing) | Cookie scans, auto-blocking and a consent log on every plan; Google-certified and IAB TCF-certified, with TCF v2.4 on Pro and Ultimate | Cookie consent banner guide |
| Cookiebot (Usercentrics) | A consent management platform: free for one domain up to 50 subpages, Premium from €7 to €90 a month per domain by site size (pricing) | Cookie scans, automatic blocking on Premium, consent records up to 12 months, IAB TCF 2.4 on Premium; a Gold Google CMP partner | Cookiebot alternative |
| AgentFirstStack Tags | Free hosted service with fair-use limits; AGPL-3.0, browser runtime MIT; set up by an agent over REST and MCP | Built-in banner for the container's tags, Consent Mode v2, replay and analytics; 12 months of consent records; no cookie scan, no blocking outside the container, not a TCF platform | This page |
Server-side GTM and its hosts are compared on the server-side GTM and Stape alternative pages.
Limits
On the hosted service (the lower number applies until a person claims the project):
- 10 tag containers per project (3).
- 5 conversion APIs per container.
- The newest 10 versions per container are kept; the live version and versions an environment is pinned to are never deleted.
- Event and delivery log 7 days, preview log 48 hours (500 entries a link), tag-fire stats and page coverage 30 days, consent records 12 months.
- A GTM import up to 2 MB; a scan reads up to 6 pages a call.
- Custom HTML and JavaScript only in a claimed project on a verified domain.
Every cap, with what the project has used: GET /v1/usage (MCP tags_get_usage). The full list is on fair-use limits. Need more? Self-host it: pnpm afs init <name> --domain example.com --account <id>, then pnpm afs deploy <name> on your own Cloudflare account.
When it isn't the right fit
- A marketing team that edits tags by hand. There's no visual tag editor: changes go through your agent, over the API or MCP. Google Tag Manager's interface, workspaces and access controls are built for that team.
- Community templates. Tags supports the tag types listed above plus custom HTML and JavaScript. A vendor that only ships a GTM template needs its snippet as custom code, or GTM.
- What the import leaves out. Universal Analytics, Floodlight, AMP and Firebase containers, server-container clients and unknown templates aren't imported. Microsoft Advertising is browser-only: its server-side conversions aren't built.
- Mobile apps. It runs on websites only.
- A full consent platform. The banner doesn't scan for cookies, block scripts outside the container, produce an IAB TCF consent string or carry Google's CMP certification. Publishers showing personalized Google ads in the EEA, UK or Switzerland need a Google-certified CMP; so do sites whose ad partners need TCF.
FAQ
Can AgentFirstStack Tags replace Google Tag Manager?
For a website, yes: it has a container, tags, triggers, variables, a GTM-compatible dataLayer, preview, versions and rollback, and it imports a GTM web container from its export or the Tag Manager API. It doesn't run GTM's community templates, server containers, Floodlight or Universal Analytics, and there's no visual editor: your agent makes changes over the API or MCP.
Can I keep Google Tag Manager and use only part of it?
Yes. The container pushes the Google Consent Mode default before any Google tag, even with no Google tag in its own config, so a GTM container loaded after it sees the visitor's consent state. So you can keep GTM and use the container only for the consent banner or for server-side conversions. Don't fire the same pixel from both, or it counts twice.
Does it include a cookie consent banner?
Yes. One config block turns on a banner that asks visitors from the EU, UK and Switzerland, holds the container's tags by category, sends Google Consent Mode v2 updates, tells session replay, and keeps 12 months of consent records. It doesn't scan the site for cookies, block scripts loaded outside the container, or act as an IAB TCF consent platform.
How does my agent test a change before visitors see it?
Edits go into a draft. Your agent validates it, reads the diff against the live version, and opens a preview link that serves the draft on the real site with a log of which tags fired and why others didn't. Preview is test traffic: ad pixels don't fire in the browser and server-side conversions go to each platform's test mode. Only then does it publish.
Is it free?
Yes. The hosted service is free within fair-use limits: 10 tag containers per project and 5 conversion APIs per container. The code is AGPL-3.0, the browser runtime is MIT, and you can self-host it on your own Cloudflare account.
What if a published version breaks something?
Your agent rolls back with POST /v1/containers/:id/rollback and a version number: the live pointer moves to that version and the draft stays as it was. Browsers pick up the change within a few minutes, because the script is cached for 60 seconds at the edge and 5 minutes in the browser.
Related
- Conversion trackingBrowser and server, one event id, counted once.
- Cookie consent bannerWhat a banner has to do, and how the options compare.
- Cookiebot alternativeA free banner in your tag manager, and when Cookiebot fits.
- Google Tag Manager MCP comparedEdit GTM, or let the agent run the tag manager.
- Server-side GTMConversion APIs with or without a server container.
- AnalyticsWeb analyticsWhere the events your agent adds are counted.
- All servicesOne MCP server for every serviceAnalytics, tags, mail and replay tools on one key.