npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

google-tag-manager-mcp-core

v2.1.1

Published

Reusable Google Tag Manager MCP tools, schemas and pluggable auth providers

Readme

google-tag-manager-mcp-core

The reusable half of the Google Tag Manager MCP server: every GTM tool, its input schemas and helpers, with no opinion about how credentials are obtained.

Authentication is a single interface, so the same tool set can back a public server doing per-user Google OAuth, a private server holding its own service account, or anything else:

export interface GtmAuthProvider {
  getAccessToken(): Promise<string>;
}

The package is runtime agnostic — it runs on Cloudflare Workers and in Node (token signing uses WebCrypto, not Node-only APIs).

Install

npm install google-tag-manager-mcp-core

@modelcontextprotocol/sdk and zod are peer dependencies on purpose: the SDK identifies tool schemas with instanceof checks, so core and the host server have to share one copy of each. If the host pins an exact SDK version (the agents package does), match that version in your own package.json so npm hoists a single copy.

Usage

A standalone server

import {
  createGtmMcpServer,
  createServiceAccountAuth,
  parseServiceAccountKey,
} from "google-tag-manager-mcp-core";

const server = createGtmMcpServer({
  auth: createServiceAccountAuth({
    ...parseServiceAccountKey(process.env.GOOGLE_SERVICE_ACCOUNT_KEY!),
    // Optional: impersonate a user through domain-wide delegation.
    subject: process.env.GOOGLE_IMPERSONATED_USER,
  }),
  serverInfo: { name: "my-gtm-mcp-server", version: "1.0.0" },
});

await server.connect(transport);

Tools on a server you already own

When the McpServer instance belongs to a framework (an McpAgent subclass, for example), register the tools onto it instead:

import { registerGtmTools } from "google-tag-manager-mcp-core";

registerGtmTools(this.server, { auth });

To change which tools get registered: createGtmMcpServer takes tools (replaces the default set) and extraTools (added on top), while registerGtmTools takes the registrations to use as its third argument.

registerGtmTools(this.server, { auth }, [...tools, myPrivateTool]);

Custom auth

Anything that can produce an access token works — a token vault, an internal auth service, per-request credentials:

const auth: GtmAuthProvider = {
  async getAccessToken() {
    return myAuthBackend.getGoogleTokenFor(currentUser);
  },
};

getAccessToken() is called on every tool invocation, so providers should cache and refresh internally. createCachedTokenSource() is exported for that: it reuses a token until just before it expires and collapses concurrent refreshes into one request.

Built-in auth providers

| Provider | Use it when | | --- | --- | | createStaticTokenAuth({ accessToken, expiresAt }) | Some other layer already ran an OAuth flow and stores the token per session. Pass a function instead of an object when that session's token can be refreshed while the server runs. | | createRefreshTokenAuth({ clientId, clientSecret, refreshToken }) | The server owns one Google account's credentials and mints access tokens itself. | | createServiceAccountAuth({ clientEmail, privateKey, subject }) | The server authenticates as a service account (JWT bearer flow, RS256 via WebCrypto). Grant that service account access to the GTM accounts it manages, or use subject for domain-wide delegation. |

Also exported

  • tools — the default tool registrations, and each action module individually.
  • All request schemas (TagSchema, TriggerSchema, VariableSchema, …).
  • GTM_API_SCOPES / GTM_OAUTH_SCOPES, GOOGLE_AUTHORIZE_URL, GOOGLE_TOKEN_URL.
  • getTagManagerClient(auth), createErrorResponse, pagination helpers.
  • setLogSink() — required for stdio servers, where stdout is the JSON-RPC stream and logs must go to stderr.

License

Apache-2.0