/** * Learning how to BUILD a tag type nobody documented. * * Creating a vendor tag needs two undocumented things: the string that goes in `type`, and the * parameter keys that tag expects. Google publishes neither for its ~68 native vendor templates, * and every gallery template invents its own field names. Recording guesses for all of that would * be worse than useless, because GTM accepts a tag with wrong keys and then renders it blank. * * So the server discovers both instead, from two sources that cannot be wrong: * * templates_describe_fields For a CUSTOM or GALLERY template. Every such template carries its * own source in `templateData`, and inside it the * ___TEMPLATE_PARAMETERS___ block declares every field the template * accepts, by name and type. That is the authoritative schema, and it * ships with the template itself. * * tags_type_profile For a NATIVE vendor template, where no templateData exists because * the template is built into GTM. If a container already has one of * these tags, that tag IS the documentation: its `type` is the real * code and its parameter keys are the real schema. This groups a * workspace's tags by type and reports both. * * Between them, a tag type can go from "unknown code" to "buildable" without anybody inventing a * field name. */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import type { GtmClient } from '../utils/gtmClient.js'; export interface TemplateField { /** The key to use in a tag's `parameter` array. */ name: string; /** GTM's field widget type, e.g. TEXT, SELECT, CHECKBOX, SIMPLE_TABLE. */ type: string; /** The label shown in the GTM interface, when the template gives one. */ displayName?: string; /** True when the field must be filled for the tag to validate. */ required?: boolean; /** Allowed values, for SELECT fields. */ options?: string[]; /** Column keys, for table fields, since those nest their own parameters. */ subFields?: string[]; } /** * Pulls the field declarations out of a template's own source. * * A .tpl file is a sequence of ___SECTION___ blocks, one of which is a JSON array of field * descriptors. The parse is deliberately forgiving: templates in the wild carry trailing commas, * comments and unusual whitespace, and a template whose schema cannot be read should degrade to * "could not read the fields" rather than throw and lose the rest of the answer. */ export declare function parseTemplateParameters(templateData: string): TemplateField[] | null; export interface TagTypeProfile { type: string; count: number; /** Parameter keys seen on tags of this type, most common first. */ parameterKeys: string[]; /** Keys present on EVERY tag of this type, so almost certainly required. */ alwaysPresent: string[]; /** A real tag name using this type, to look at in the interface. */ exampleTagName: string; } /** * Summarises the tag types actually present in a workspace. * * The value is in `alwaysPresent`: a key that appears on every single tag of a type is one the tag * cannot do without, which is as close to a required-field list as an undocumented template gets. * Keys seen on only some tags are optional, and reporting the two separately stops a caller * treating an optional field as mandatory or the reverse. */ export declare function summariseTagTypes(tags: { type?: string | null; name?: string | null; parameter?: unknown; }[]): TagTypeProfile[]; export declare function registerTemplateFieldTools(server: McpServer, getClient: () => GtmClient): void; //# sourceMappingURL=templateFields.d.ts.map