Skip to main content
Glama

brand_check

Validate text, colors, fonts, and CSS against brand identity in under 50ms. Get pass/fail results with specific fixes to ensure brand compliance.

Instructions

Fast inline brand gate — check text, colors, fonts, or CSS against the compiled brand identity in under 50ms. Pass one or more inputs: text (voice violations, never-say, AI-isms), color (palette match with ΔE distance), font (typography match), css (visual anti-pattern violations). Returns pass/fail with specific fixes. Call this reflexively while generating content or code, the way you'd run a linter. Requires brand_compile to have run first. NOT for deep audits — use brand_audit_content for comprehensive scoring.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
textNoText to check for voice violations (never-say words, anchor term misuse, AI-isms). Example: "We leverage cutting-edge AI solutions"
colorNoHex color to check against the brand palette. Returns nearest brand color with perceptual distance (ΔE). Example: "#3b82f6"
fontNoFont family name to check against brand typography. Example: "Helvetica"
cssNoCSS snippet to check for visual anti-pattern violations (shadows, gradients, etc.). Example: "box-shadow: 0 2px 4px rgba(0,0,0,0.1)"

Implementation Reference

  • Main handler for the brand_check tool. Accepts text, color, font, and/or CSS inputs, calls runBrandCheck from the engine, and builds a structured response with pass/fail, flags, and optional brand palette data.
    async function handler(input: Params) {
      const cwd = process.cwd();
    
      // Require at least one input
      if (!input.text && !input.color && !input.font && !input.css) {
        return buildResponse({
          what_happened: "No input provided — pass at least one of: text, color, font, css",
          next_steps: [
            'Check text: brand_check text="We leverage AI solutions"',
            'Check color: brand_check color="#3b82f6"',
            'Check font: brand_check font="Helvetica"',
            'Check CSS: brand_check css="box-shadow: 0 2px 4px rgba(0,0,0,0.1)"',
          ],
          data: { error: ERROR_CODES.NO_INPUT },
        });
      }
    
      const live = await ensureLiveFreshness(cwd);
      const liveIndicator = buildLiveIndicator(live);
    
      const result = await runBrandCheck(cwd, {
        text: input.text,
        color: input.color,
        font: input.font,
        css: input.css,
      });
    
      if (!result) {
        return buildResponse({
          what_happened: "No compiled brand data found — run brand_compile first",
          next_steps: [
            "brand_check requires brand-runtime.json and interaction-policy.json",
            "Run brand_compile to generate them from your .brand/ data",
          ],
          data: { error: ERROR_CODES.NOT_COMPILED },
        });
      }
    
      // Build concise response
      const { pass, flags, checked } = result;
    
      if (pass && flags.length === 0) {
        return buildResponse({
          what_happened: `Brand check passed (${checked.join(", ")})`,
          next_steps: [],
          data: {
            pass: true,
            checked,
            flags: [],
            ...(liveIndicator ? { live: liveIndicator } : {}),
          },
        });
      }
    
      // Summarize flags by type
      const errorCount = flags.filter((f) => f.severity === "error").length;
      const warnCount = flags.filter((f) => f.severity === "warning").length;
      const infoCount = flags.filter((f) => f.severity === "info").length;
    
      const parts: string[] = [];
      if (errorCount > 0) parts.push(`${errorCount} error(s)`);
      if (warnCount > 0) parts.push(`${warnCount} warning(s)`);
      if (infoCount > 0) parts.push(`${infoCount} info`);
    
      // Include palette when checking colors (helps agents self-correct)
      let palette: Array<{ name: string; hex: string }> | null = null;
      if (input.color && !pass) {
        palette = await getBrandPalette(cwd);
      }
    
      const data: Record<string, unknown> = {
        pass,
        checked,
        flags,
      };
      if (palette) {
        data.brand_palette = palette;
      }
      if (liveIndicator) {
        data.live = liveIndicator;
      }
    
      return buildResponse({
        what_happened: `Brand check ${pass ? "passed" : "failed"}: ${parts.join(", ")} (${checked.join(", ")})`,
        next_steps: pass
          ? []
          : flags
              .filter((f) => f.fix)
              .slice(0, 3)
              .map((f) => f.fix!),
        data,
      });
    }
  • Registration of the 'brand_check' tool on the MCP server via server.tool(), with Zod schema paramsShape and description of its fast inline brand gate functionality.
    export function register(server: McpServer) {
      server.tool(
        "brand_check",
        'Fast inline brand gate — check text, colors, fonts, or CSS against the compiled brand identity in under 50ms. Pass one or more inputs: text (voice violations, never-say, AI-isms), color (palette match with ΔE distance), font (typography match), css (visual anti-pattern violations). Returns pass/fail with specific fixes. Call this reflexively while generating content or code, the way you\'d run a linter. Requires brand_compile to have run first. NOT for deep audits — use brand_audit_content for comprehensive scoring.',
        paramsShape,
        async (args) => {
          const parsed = safeParseParams(ParamsSchema, args);
          if (!parsed.success) return parsed.response;
          return handler(parsed.data);
        },
      );
    }
  • Zod schema for brand_check inputs: text, color, font, css — all optional but at least one required.
    const paramsShape = {
      text: z
        .string()
        .optional()
        .describe(
          'Text to check for voice violations (never-say words, anchor term misuse, AI-isms). Example: "We leverage cutting-edge AI solutions"',
        ),
      color: z
        .string()
        .optional()
        .describe(
          'Hex color to check against the brand palette. Returns nearest brand color with perceptual distance (ΔE). Example: "#3b82f6"',
        ),
      font: z
        .string()
        .optional()
        .describe(
          'Font family name to check against brand typography. Example: "Helvetica"',
        ),
      css: z
        .string()
        .optional()
        .describe(
          'CSS snippet to check for visual anti-pattern violations (shadows, gradients, etc.). Example: "box-shadow: 0 2px 4px rgba(0,0,0,0.1)"',
        ),
    };
  • Core engine function runBrandCheck() that loads cached brand data and runs checkText, checkColor, checkFont, checkCss sub-functions. Also exports getBrandPalette() helper.
    export async function runBrandCheck(cwd: string, input: CheckInput): Promise<CheckResult | null> {
      const brand = await loadCached(cwd);
      if (!brand) return null;
    
      const flags: CheckFlag[] = [];
      const checked: string[] = [];
    
      if (input.text) {
        checked.push("text");
        flags.push(...checkText(input.text, brand));
      }
    
      if (input.color) {
        checked.push("color");
        flags.push(...checkColor(input.color, brand));
      }
    
      if (input.font) {
        checked.push("font");
        flags.push(...checkFont(input.font, brand));
      }
    
      if (input.css) {
        checked.push("css");
        flags.push(...checkCss(input.css, brand));
      }
    
      return {
        pass: flags.every((f) => f.severity === "info"),
        flags,
        checked,
      };
    }
    
    /** Expose brand palette for color suggestions without running a full check. */
    export async function getBrandPalette(cwd: string): Promise<Array<{ name: string; hex: string }> | null> {
      const brand = await loadCached(cwd);
      if (!brand) return null;
      return brand.brandColors.map((c) => ({ name: c.name, hex: c.hex }));
    }
  • src/server.ts:36-97 (registration)
    Import and call to registerCheck(server) which registers the brand_check tool on the main MCP server.
    import { register as registerCheck } from "./tools/brand-check.js";
    import { register as registerPreview } from "./tools/brand-preview.js";
    import { register as registerExtractVisual } from "./tools/brand-extract-visual.js";
    import { register as registerExtractPdf } from "./tools/brand-extract-pdf.js";
    import { register as registerResolveConflicts } from "./tools/brand-resolve-conflicts.js";
    import { register as registerBrandcodeAuth } from "./tools/brand-brandcode-auth.js";
    import { register as registerBrandcodeConnect } from "./tools/brand-brandcode-connect.js";
    import { register as registerBrandcodeSync } from "./tools/brand-brandcode-sync.js";
    import { register as registerBrandcodeStatus } from "./tools/brand-brandcode-status.js";
    import { register as registerBrandcodeLive } from "./tools/brand-brandcode-live.js";
    import { register as registerRepoConnect } from "./tools/brand-repo-connect.js";
    import { register as registerRepoStatus } from "./tools/brand-repo-status.js";
    import { register as registerEnrichSkill } from "./tools/brand-enrich-skill.js";
    
    export function createServer(): McpServer {
      const server = new McpServer({
        name: "brandsystem",
        version: getVersion(),
      });
    
      // ── Entry points (register first — agents see these first) ──
      registerStart(server);       // #1: Entry point for new brands
      registerStatus(server);      // #2: "What can I do?" / resume point
    
      // ── Session 1: Core Identity ──
      registerExtractWeb(server);  // Extract from website (CSS parsing)
      registerExtractVisual(server); // Extract from website (headless Chrome + vision)
      registerExtractSite(server); // Extract from website (multi-page rendered crawl)
      registerExtractPdf(server); // Extract from PDF guidelines
      registerResolveConflicts(server); // Compare and resolve source conflicts
      registerGenerateDesignMd(server); // Generate design-synthesis.json + DESIGN.md
      registerExtractFigma(server);// Extract from Figma
      registerSetLogo(server);     // Add/replace logo manually
      registerCompile(server);     // Generate tokens + VIM
      registerClarify(server);     // Resolve ambiguous values
      registerAudit(server);       // Validate .brand/ directory
      registerReport(server);      // Generate HTML report
      registerInit(server);        // Low-level init (prefer brand_start)
    
      // ── Session 2: Visual Identity ──
      registerDeepenIdentity(server);
      registerIngestAssets(server);
      registerPreflight(server);
    
      // ── Session 3: Messaging ──
      registerExtractMessaging(server);
      registerCompileMessaging(server);
    
      // ── Session 4: Content Strategy ──
      registerBuildPersonas(server);
      registerBuildJourney(server);
      registerBuildThemes(server);
      registerBuildMatrix(server);
    
      // ── Content scoring ──
      registerAuditContent(server);   // Score content against brand identity
      registerCheckCompliance(server); // Binary pass/fail gate
      registerAuditDrift(server);     // Batch drift detection
    
      // ── Runtime ──
      registerRuntime(server);     // Read compiled brand runtime contract
      registerCheck(server);       // Fast inline brand gate
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses behavior: speed (<50ms), input types (text, color, font, css), output format (pass/fail with specific fixes), and mentions it's not for deep audits. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each serving a purpose: first sentence defines purpose and speed, second details inputs and outputs, third provides usage guidance and boundaries. No redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (4 optional parameters, no output schema), the description thoroughly covers what it does, when to use it, prerequisites, and what to expect as output. It compensates for lacking output schema by stating 'returns pass/fail with specific fixes'.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with clear descriptions per parameter. The description adds value beyond the schema by explaining the purpose of each input (e.g., 'voice violations, never-say, AI-isms' for text) and the return type (pass/fail with fixes).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool checks text, colors, fonts, or CSS against the compiled brand identity, with specific verb 'check' and resource 'brand identity'. It distinguishes from sibling tools like brand_audit_content by noting it's for fast inline checks, not deep audits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('call reflexively while generating content or code, the way you'd run a linter') and when not ('NOT for deep audits — use brand_audit_content for comprehensive scoring'). Also mentions prerequisite: 'Requires brand_compile to have run first'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Brandcode-Studio/brandsystem-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server