Skip to main content
Glama
lukaskostka99

Marketing Miner MCP

Get Website Stats

marketing_miner_get_website_stats
Read-onlyIdempotent

Analyze organic and paid traffic, keyword counts, and SERP feature breakdowns for any domain, subdomain, prefix, or exact URL. Ideal for competitor sizing and SEO audits.

Instructions

Aggregate organic/paid traffic, keyword counts and result-type breakdown for a domain, subdomain, prefix, or exact URL.

Args:

  • lang: Market code (cs/sk/pl/hu/ro/gb/us).

  • type: 'domain' | 'subdomain' | 'prefix' | 'exact'.

  • target: Target value (3-253 chars). Examples: 'seznam.cz', 'blog.seznam.cz', 'https://seznam.cz/email/'.

  • scheme (optional, for type='exact' or 'prefix'): 'https' | 'http'.

  • response_format: 'markdown' or 'json'.

Returns: stats[] per result_type (organic, paid, ai_overviews, local_pack, images, videos, ...), plus totals (estimated_traffic_sum, number_of_keywords_sum).

Use for competitor sizing, SEO audits, and SERP-feature distribution analysis.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
langYesLanguage/market code. 'gb' = United Kingdom, 'us' = United States.
typeYesTarget granularity: 'domain' (example.com), 'subdomain' (blog.example.com), 'prefix' (URL prefix), 'exact' (exact URL).
targetYesTarget value (domain, subdomain, or URL, 3-253 chars).
schemeNoURL scheme. Only relevant for type='exact' or 'prefix'.
response_formatNoOutput format. 'markdown' for human reading, 'json' for structured processing.markdown

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
statsYes
estimated_traffic_sumYes
estimated_traffic_change_sumYes
number_of_keywords_sumYes

Implementation Reference

  • TypeScript interfaces for API response data: WebsiteStatsRow and WebsitesStatsData. These define the shape of data returned from the /websites/stats endpoint.
    interface WebsiteStatsRow {
      result_type: string;
      estimated_traffic: number;
      estimated_traffic_change: number;
      number_of_keywords: number;
    }
    
    interface WebsitesStatsData {
      stats: WebsiteStatsRow[];
      estimated_traffic_sum: number;
      estimated_traffic_change_sum: number;
      number_of_keywords_sum: number;
    }
  • WebsiteStatsRowSchema - Zod schema for individual result-type rows (result_type, estimated_traffic, estimated_traffic_change, number_of_keywords).
    const WebsiteStatsRowSchema = z
      .object({
        result_type: z.string(),
        estimated_traffic: z.number(),
        estimated_traffic_change: z.number(),
        number_of_keywords: z.number(),
      })
      .passthrough();
  • WebsiteStatsOutputSchema - Zod output schema defining the full API response shape: stats array plus aggregated totals.
    const WebsiteStatsOutputSchema = z
      .object({
        stats: z.array(WebsiteStatsRowSchema),
        estimated_traffic_sum: z.number(),
        estimated_traffic_change_sum: z.number(),
        number_of_keywords_sum: z.number(),
      })
      .passthrough();
  • WebsiteStatsInputSchema - Zod input schema validating lang, type, target, optional scheme, and response_format.
    const WebsiteStatsInputSchema = z
      .object({
        lang: LangSchema,
        type: z
          .enum(WEBSITE_TYPES)
          .describe(
            "Target granularity: 'domain' (example.com), 'subdomain' (blog.example.com), 'prefix' (URL prefix), 'exact' (exact URL).",
          ),
        target: z
          .string()
          .min(3)
          .max(253)
          .describe("Target value (domain, subdomain, or URL, 3-253 chars)."),
        scheme: z
          .enum(WEBSITE_SCHEMES)
          .optional()
          .describe("URL scheme. Only relevant for type='exact' or 'prefix'."),
        response_format: ResponseFormatSchema,
      })
      .strict();
  • Complete tool registration and handler for marketing_miner_get_website_stats. Registers the tool with title, description, schemas, and implements the async handler: parses input, calls mmGet('/websites/stats', params), formats markdown table or JSON response, uses truncateIfNeeded for large payloads, and returns content with structured data.
      // -------------------------------------------------------------------------
      // Tool: website stats
      // -------------------------------------------------------------------------
      server.registerTool(
        "marketing_miner_get_website_stats",
        {
          title: "Get Website Stats",
          description: `Aggregate organic/paid traffic, keyword counts and result-type breakdown for a domain, subdomain, prefix, or exact URL.
    
    Args:
      - lang: Market code (cs/sk/pl/hu/ro/gb/us).
      - type: 'domain' | 'subdomain' | 'prefix' | 'exact'.
      - target: Target value (3-253 chars). Examples: 'seznam.cz', 'blog.seznam.cz', 'https://seznam.cz/email/'.
      - scheme (optional, for type='exact' or 'prefix'): 'https' | 'http'.
      - response_format: 'markdown' or 'json'.
    
    Returns: stats[] per result_type (organic, paid, ai_overviews, local_pack, images, videos, ...), plus totals (estimated_traffic_sum, number_of_keywords_sum).
    
    Use for competitor sizing, SEO audits, and SERP-feature distribution analysis.`,
          inputSchema: WebsiteStatsInputSchema.shape,
          outputSchema: WebsiteStatsOutputSchema.shape,
          annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: true,
          },
        },
        async (args) => {
          const input = WebsiteStatsInputSchema.parse(args);
          try {
            const params: Record<string, unknown> = {
              lang: input.lang,
              type: input.type,
              target: input.target,
            };
            if (input.scheme) params.scheme = input.scheme;
            const data = await mmGet<WebsitesStatsData>("/websites/stats", params);
            const payload: Record<string, unknown> = { ...data };
            const md = [
              `# Website stats: \`${input.target}\` (${input.lang}, ${input.type})`,
              "",
              `- **Total estimated traffic**: ${data.estimated_traffic_sum}`,
              `- **Traffic change**: ${data.estimated_traffic_change_sum}`,
              `- **Total keywords**: ${data.number_of_keywords_sum}`,
              "",
              "| Result type | Traffic | Δ traffic | Keywords |",
              "|---|---|---|---|",
              ...data.stats.map(
                (s) =>
                  `| ${s.result_type} | ${s.estimated_traffic} | ${s.estimated_traffic_change} | ${s.number_of_keywords} |`,
              ),
            ].join("\n");
    
            const text = input.response_format === "json" ? JSON.stringify(payload, null, 2) : md;
            const final = truncateIfNeeded(payload, text, "stats");
            return {
              content: [{ type: "text", text: final.text }],
              structuredContent: final.payload,
            };
          } catch (error) {
            return toolError(
              error instanceof Error ? error.message : `Unexpected error: ${String(error)}`,
            );
          }
        },
      );
Behavior4/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds context on the output structure: 'stats[] per result_type (organic, paid, ai_overviews, ...) plus totals.' This goes beyond the annotations, providing useful behavioral insight. 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 concise (four sentences) with front-loaded summary. It uses a clean 'Args' block for parameter details. Every sentence earns its place, no redundancy. Structured format aids quick parsing.

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 output schema exists, the description adequately explains the return values (stats per result type plus totals). All parameters are explained with examples. The tool's complexity is moderate, and the description covers all necessary information for an agent to use effectively.

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

Parameters4/5

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

Schema covers all 5 parameters with descriptions (100% coverage). The description adds value by providing concrete examples for 'target' (e.g., 'seznam.cz') and clarifies the usage of 'scheme' parameter. This enhances understanding beyond the schema.

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 it aggregates organic/paid traffic, keyword counts, and result-type breakdown for various URL granularities. It explicitly names the resource ('website stats') and the verb ('aggregate'). Sibling tools like batch search volume and keyword suggestions are distinct, so no confusion.

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

Usage Guidelines4/5

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

The description provides explicit use cases: 'competitor sizing, SEO audits, and SERP-feature distribution analysis.' This gives clear context on when to use the tool. However, it does not explicitly state when not to use it or mention alternatives, but the use cases are sufficient for differentiation.

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/lukaskostka99/marketing-miner-mcp'

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